aboutsummaryrefslogtreecommitdiffstats
path: root/contrib/libs/icu/io/ufile.cpp
diff options
context:
space:
mode:
authorromankoshelev <romankoshelev@yandex-team.com>2023-08-09 20:07:20 +0300
committerromankoshelev <romankoshelev@yandex-team.com>2023-08-09 20:59:13 +0300
commitfd82fb12fb45e71a02c628e45b12c50c0dd0d308 (patch)
treef582b79f9002ab1d083e9acda600dfb3551c47b6 /contrib/libs/icu/io/ufile.cpp
parentbf862ddf5c6178e1bb5e4fb3f7c61015deebe284 (diff)
downloadydb-fd82fb12fb45e71a02c628e45b12c50c0dd0d308.tar.gz
Update ICU to 70.1
Diffstat (limited to 'contrib/libs/icu/io/ufile.cpp')
-rw-r--r--contrib/libs/icu/io/ufile.cpp46
1 files changed, 38 insertions, 8 deletions
diff --git a/contrib/libs/icu/io/ufile.cpp b/contrib/libs/icu/io/ufile.cpp
index 1d8c221cdc..607601935c 100644
--- a/contrib/libs/icu/io/ufile.cpp
+++ b/contrib/libs/icu/io/ufile.cpp
@@ -40,6 +40,7 @@
#include "unicode/ures.h"
#include "unicode/ucnv.h"
#include "unicode/ustring.h"
+#include "unicode/unistr.h"
#include "cstring.h"
#include "cmemory.h"
@@ -142,18 +143,42 @@ u_fopen(const char *filename,
return result; /* not a file leak */
}
+// FILENAME_BUF_MAX represents the largest size that we are willing to use for a
+// stack-allocated buffer to contain a file name or path. If PATH_MAX (POSIX) or MAX_PATH
+// (Windows) are defined and are smaller than this we will use their defined value;
+// otherwise, we will use FILENAME_BUF_MAX for the stack-allocated buffer, and dynamically
+// allocate a buffer for any file name or path that is that length or longer.
+#define FILENAME_BUF_MAX 296
+#if defined PATH_MAX && PATH_MAX < FILENAME_BUF_MAX
+#define FILENAME_BUF_CAPACITY PATH_MAX
+#elif defined MAX_PATH && MAX_PATH < FILENAME_BUF_MAX
+#define FILENAME_BUF_CAPACITY MAX_PATH
+#else
+#define FILENAME_BUF_CAPACITY FILENAME_BUF_MAX
+#endif
+
U_CAPI UFILE* U_EXPORT2
u_fopen_u(const UChar *filename,
const char *perm,
const char *locale,
const char *codepage)
{
- UFILE *result;
- char buffer[256];
-
- u_austrcpy(buffer, filename);
+ UFILE *result;
+ char buffer[FILENAME_BUF_CAPACITY];
+ char *filenameBuffer = buffer;
+
+ icu::UnicodeString filenameString(true, filename, -1); // readonly aliasing, does not allocate memory
+ // extract with conversion to platform default codepage, return full length (not including 0 termination)
+ int32_t filenameLength = filenameString.extract(0, filenameString.length(), filenameBuffer, FILENAME_BUF_CAPACITY);
+ if (filenameLength >= FILENAME_BUF_CAPACITY) { // could not fit (with zero termination) in buffer
+ filenameBuffer = static_cast<char *>(uprv_malloc(++filenameLength)); // add one for zero termination
+ if (!filenameBuffer) {
+ return nullptr;
+ }
+ filenameString.extract(0, filenameString.length(), filenameBuffer, filenameLength);
+ }
- result = u_fopen(buffer, perm, locale, codepage);
+ result = u_fopen(filenameBuffer, perm, locale, codepage);
#if U_PLATFORM_USES_ONLY_WIN32_API
/* Try Windows API _wfopen if the above fails. */
if (!result) {
@@ -161,20 +186,25 @@ u_fopen_u(const UChar *filename,
wchar_t wperm[40] = {};
size_t retVal;
mbstowcs_s(&retVal, wperm, UPRV_LENGTHOF(wperm), perm, _TRUNCATE);
- FILE *systemFile = _wfopen((const wchar_t *)filename, wperm);
+ FILE *systemFile = _wfopen(reinterpret_cast<const wchar_t *>(filename), wperm); // may return NULL for long filename
if (systemFile) {
result = finit_owner(systemFile, locale, codepage, TRUE);
}
- if (!result) {
+ if (!result && systemFile) {
/* Something bad happened.
- Maybe the converter couldn't be opened. */
+ Maybe the converter couldn't be opened.
+ Bu do not fclose(systemFile) if systemFile is NULL. */
fclose(systemFile);
}
}
#endif
+ if (filenameBuffer != buffer) {
+ uprv_free(filenameBuffer);
+ }
return result; /* not a file leak */
}
+
U_CAPI UFILE* U_EXPORT2
u_fstropen(UChar *stringBuf,
int32_t capacity,