Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(249)

Unified Diff: patches/tzpath.patch

Issue 2496433004: Cherry pick an upstream patch for tz dir traversal (Closed)
Patch Set: Created 4 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « README.chromium ('k') | source/common/putil.cpp » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: patches/tzpath.patch
diff --git a/patches/tzpath.patch b/patches/tzpath.patch
new file mode 100644
index 0000000000000000000000000000000000000000..38906b5ca3098d4f30563c78dc09bf9d4b3c3d91
--- /dev/null
+++ b/patches/tzpath.patch
@@ -0,0 +1,184 @@
+diff --git a/source/common/putil.cpp b/source/common/putil.cpp
+index c87b60e..9b8e184 100644
+--- a/source/common/putil.cpp
++++ b/source/common/putil.cpp
+@@ -832,7 +832,6 @@ static const char* remapShortTimeZone(const char *stdID, const char *dstID, int3
+ #endif
+
+ #ifdef SEARCH_TZFILE
+-#define MAX_PATH_SIZE PATH_MAX /* Set the limit for the size of the path. */
+ #define MAX_READ_SIZE 512
+
+ typedef struct DefaultTZInfo {
+@@ -908,15 +907,19 @@ static UBool compareBinaryFiles(const char* defaultTZFileName, const char* TZFil
+
+ return result;
+ }
+-/*
+- * This method recursively traverses the directory given for a matching TZ file and returns the first match.
+- */
++
++
+ /* dirent also lists two entries: "." and ".." that we can safely ignore. */
+ #define SKIP1 "."
+ #define SKIP2 ".."
+-static char SEARCH_TZFILE_RESULT[MAX_PATH_SIZE] = "";
++static UBool U_CALLCONV putil_cleanup(void);
++static CharString *gSearchTZFileResult = NULL;
++
++/*
++ * This method recursively traverses the directory given for a matching TZ file and returns the first match.
++ * This function is not thread safe - it uses a global, gSearchTZFileResult, to hold its results.
++ */
+ static char* searchForTZFile(const char* path, DefaultTZInfo* tzInfo) {
+- char curpath[MAX_PATH_SIZE];
+ DIR* dirp = opendir(path);
+ DIR* subDirp = NULL;
+ struct dirent* dirEntry = NULL;
+@@ -926,24 +929,40 @@ static char* searchForTZFile(const char* path, DefaultTZInfo* tzInfo) {
+ return result;
+ }
+
++ if (gSearchTZFileResult == NULL) {
++ gSearchTZFileResult = new CharString;
++ if (gSearchTZFileResult == NULL) {
++ return NULL;
++ }
++ ucln_common_registerCleanup(UCLN_COMMON_PUTIL, putil_cleanup);
++ }
++
+ /* Save the current path */
+- uprv_memset(curpath, 0, MAX_PATH_SIZE);
+- uprv_strcpy(curpath, path);
++ UErrorCode status = U_ZERO_ERROR;
++ CharString curpath(path, -1, status);
++ if (U_FAILURE(status)) {
++ return NULL;
++ }
+
+ /* Check each entry in the directory. */
+ while((dirEntry = readdir(dirp)) != NULL) {
+ const char* dirName = dirEntry->d_name;
+ if (uprv_strcmp(dirName, SKIP1) != 0 && uprv_strcmp(dirName, SKIP2) != 0) {
+ /* Create a newpath with the new entry to test each entry in the directory. */
+- char newpath[MAX_PATH_SIZE];
+- uprv_strcpy(newpath, curpath);
+- uprv_strcat(newpath, dirName);
++ CharString newpath(curpath, status);
++ newpath.append(dirName, -1, status);
++ if (U_FAILURE(status)) {
++ return NULL;
++ }
+
+- if ((subDirp = opendir(newpath)) != NULL) {
++ if ((subDirp = opendir(newpath.data())) != NULL) {
+ /* If this new path is a directory, make a recursive call with the newpath. */
+ closedir(subDirp);
+- uprv_strcat(newpath, "/");
+- result = searchForTZFile(newpath, tzInfo);
++ newpath.append('/', status);
++ if (U_FAILURE(status)) {
++ return NULL;
++ }
++ result = searchForTZFile(newpath.data(), tzInfo);
+ /*
+ Have to get out here. Otherwise, we'd keep looking
+ and return the first match in the top-level directory
+@@ -955,11 +974,19 @@ static char* searchForTZFile(const char* path, DefaultTZInfo* tzInfo) {
+ if (result != NULL)
+ break;
+ } else if (uprv_strcmp(TZFILE_SKIP, dirName) != 0 && uprv_strcmp(TZFILE_SKIP2, dirName) != 0) {
+- if(compareBinaryFiles(TZDEFAULT, newpath, tzInfo)) {
+- const char* zoneid = newpath + (sizeof(TZZONEINFO)) - 1;
++ if(compareBinaryFiles(TZDEFAULT, newpath.data(), tzInfo)) {
++ int32_t amountToSkip = sizeof(TZZONEINFO) - 1;
++ if (amountToSkip > newpath.length()) {
++ amountToSkip = newpath.length();
++ }
++ const char* zoneid = newpath.data() + amountToSkip;
+ skipZoneIDPrefix(&zoneid);
+- uprv_strcpy(SEARCH_TZFILE_RESULT, zoneid);
+- result = SEARCH_TZFILE_RESULT;
++ gSearchTZFileResult->clear();
++ gSearchTZFileResult->append(zoneid, -1, status);
++ if (U_FAILURE(status)) {
++ return NULL;
++ }
++ result = gSearchTZFileResult->data();
+ /* Get out after the first one found. */
+ break;
+ }
+@@ -1144,6 +1171,11 @@ static UBool U_CALLCONV putil_cleanup(void)
+ gTimeZoneFilesDirectory = NULL;
+ gTimeZoneFilesInitOnce.reset();
+
++#ifdef SEARCH_TZFILE
++ delete gSearchTZFileResult;
++ gSearchTZFileResult = NULL;
++#endif
++
+ #if U_POSIX_LOCALE || U_PLATFORM_USES_ONLY_WIN32_API
+ if (gCorrectedPOSIXLocale) {
+ uprv_free(gCorrectedPOSIXLocale);
+diff --git a/source/tools/toolutil/filetools.cpp b/source/tools/toolutil/filetools.cpp
+index 238ef7b..9b61c87 100644
+--- a/source/tools/toolutil/filetools.cpp
++++ b/source/tools/toolutil/filetools.cpp
+@@ -4,6 +4,7 @@
+ *******************************************************************************
+ */
+
++#include "unicode/platform.h"
+ #if U_PLATFORM == U_PF_MINGW
+ // *cough* - for struct stat
+ #ifdef __STRICT_ANSI__
+@@ -13,6 +14,7 @@
+
+ #include "filetools.h"
+ #include "filestrm.h"
++#include "charstr.h"
+ #include "cstring.h"
+ #include "unicode/putil.h"
+ #include "putilimp.h"
+@@ -27,8 +29,6 @@
+ #include <dirent.h>
+ typedef struct dirent DIRENT;
+
+-#define MAX_PATH_SIZE 4096 /* Set the limit for the size of the path. */
+-
+ #define SKIP1 "."
+ #define SKIP2 ".."
+ #endif
+@@ -56,20 +56,24 @@ isFileModTimeLater(const char *filePath, const char *checkAgainst, UBool isDir)
+
+ while ((dirEntry = readdir(pDir)) != NULL) {
+ if (uprv_strcmp(dirEntry->d_name, SKIP1) != 0 && uprv_strcmp(dirEntry->d_name, SKIP2) != 0) {
+- char newpath[MAX_PATH_SIZE] = "";
+- uprv_strcpy(newpath, checkAgainst);
+- uprv_strcat(newpath, U_FILE_SEP_STRING);
+- uprv_strcat(newpath, dirEntry->d_name);
+-
+- if ((subDirp = opendir(newpath)) != NULL) {
++ UErrorCode status = U_ZERO_ERROR;
++ icu::CharString newpath(checkAgainst, -1, status);
++ newpath.append(U_FILE_SEP_STRING, -1, status);
++ newpath.append(dirEntry->d_name, -1, status);
++ if (U_FAILURE(status)) {
++ fprintf(stderr, "%s:%d: %s\n", __FILE__, __LINE__, u_errorName(status));
++ return FALSE;
++ };
++
++ if ((subDirp = opendir(newpath.data())) != NULL) {
+ /* If this new path is a directory, make a recursive call with the newpath. */
+ closedir(subDirp);
+- isLatest = isFileModTimeLater(filePath, newpath, isDir);
++ isLatest = isFileModTimeLater(filePath, newpath.data(), isDir);
+ if (!isLatest) {
+ break;
+ }
+ } else {
+- int32_t latest = whichFileModTimeIsLater(filePath, newpath);
++ int32_t latest = whichFileModTimeIsLater(filePath, newpath.data());
+ if (latest < 0 || latest == 2) {
+ isLatest = FALSE;
+ break;
« no previous file with comments | « README.chromium ('k') | source/common/putil.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698