From b9b5e1cf33054f89b8410ae2b8c3e8b0fd72417b Mon Sep 17 00:00:00 2001 From: Klaas Freitag Date: Tue, 23 Jun 2015 11:40:26 +0200 Subject: [PATCH] Long win pathes: Make makeLongWinPath function return the num of alloc bytes. This enables the calling function to free these accordingly. That is needed because the makeLongWinPath for efficiency reasons does not always realloc the original string. --- csync/src/std/c_string.c | 24 +++++++++++------ csync/src/std/c_string.h | 2 +- csync/src/vio/csync_vio_local.c | 3 ++- csync/tests/encoding_tests/check_encoding.c | 30 +++++++++++++++++---- 4 files changed, 44 insertions(+), 15 deletions(-) diff --git a/csync/src/std/c_string.c b/csync/src/std/c_string.c index 7702c224f..e878ed5eb 100644 --- a/csync/src/std/c_string.c +++ b/csync/src/std/c_string.c @@ -274,24 +274,32 @@ char* c_utf8_from_locale(const mbchar_t *wstr) return dst; } - const char *makeLongWinPath(const char *str) +/* + */ + const char *makeLongWinPath(const char *str, int *mem_reserved) { int len = 0; char *longStr = NULL; - int mem_reserved = 0; + + if( mem_reserved ) { + *mem_reserved = 0; + } len = strlen(str); // prepend \\?\ and convert '/' => '\' to support long names - if( len > 2 ) { // FIXME set this to 250 or so + if( len > 250 ) { // Only do realloc for long pathes. Shorter pathes are fine. int i = 4; // reserve mem for a new string with the prefix - mem_reserved = len + 5; - longStr = c_malloc(mem_reserved); + if( mem_reserved ) { + *mem_reserved = len + 5; + } + longStr = c_malloc(len+5); *longStr = '\0'; strcpy( longStr, "\\\\?\\"); // prepend string by this four magic chars. strcat( longStr, str ); + /* replace all occurences of / with the windows native \ */ while(longStr[i] != '\0') { if(longStr[i] == '/') { longStr[i] = '\\'; @@ -312,7 +320,7 @@ mbchar_t* c_utf8_to_locale(const char *str) #ifdef _WIN32 size_t len = 0; int size_needed = 0; - char *longStr = NULL; + const char *longStr = NULL; int mem_reserved = 0; #endif @@ -321,7 +329,7 @@ mbchar_t* c_utf8_to_locale(const char *str) } #ifdef _WIN32 - longStr = makeLongWinPath(str); + longStr = makeLongWinPath(str, &mem_reserved); if( longStr ) { len = strlen(longStr); @@ -333,7 +341,7 @@ mbchar_t* c_utf8_to_locale(const char *str) MultiByteToWideChar(CP_UTF8, 0, longStr, -1, dst, size_needed); } - if( mem_reserved > 0 ) { // FIXME!! free mem. + if( mem_reserved > 0 ) { // Free mem reserved in hte makeLongWinPath function SAFE_FREE(longStr); } } diff --git a/csync/src/std/c_string.h b/csync/src/std/c_string.h index d8de2e120..c9e191cc6 100644 --- a/csync/src/std/c_string.h +++ b/csync/src/std/c_string.h @@ -155,7 +155,7 @@ void c_strlist_destroy(c_strlist_t *strlist); char* c_utf8_from_locale(const mbchar_t *str); - const char *makeLongWinPath(const char *str); + const char *makeLongWinPath(const char *str, int *mem_reserved); /** * @brief Convert a utf8 encoded string to platform specific locale. diff --git a/csync/src/vio/csync_vio_local.c b/csync/src/vio/csync_vio_local.c index 91b0c1b41..6868256d7 100644 --- a/csync/src/vio/csync_vio_local.c +++ b/csync/src/vio/csync_vio_local.c @@ -130,7 +130,6 @@ int csync_vio_local_closedir(csync_vio_handle_t *dhandle) { } csync_vio_file_stat_t *csync_vio_local_readdir(csync_vio_handle_t *dhandle) { - struct _tdirent *dirent = NULL; dhandle_t *handle = NULL; csync_vio_file_stat_t *file_stat = NULL; @@ -171,6 +170,8 @@ csync_vio_file_stat_t *csync_vio_local_readdir(csync_vio_handle_t *dhandle) { file_stat->type = CSYNC_VIO_FILE_TYPE_REGULAR; } #else + struct _tdirent *dirent = NULL; + dirent = _treaddir(handle->dh); if (dirent == NULL) { if (errno) { diff --git a/csync/tests/encoding_tests/check_encoding.c b/csync/tests/encoding_tests/check_encoding.c index 403aa2249..bc98b200c 100644 --- a/csync/tests/encoding_tests/check_encoding.c +++ b/csync/tests/encoding_tests/check_encoding.c @@ -145,12 +145,32 @@ static void check_to_multibyte(void **state) static void check_long_win_path(void **state) { - const char *path = "C://DATA/FILES/MUSIC/MY_MUSIC.mp3"; - const char *new = makeLongWinPath(path); + int mem_reserved = 0; + const char *path = "C://DATA/FILES/MUSIC/MY_MUSIC.mp3"; // check a short path + const char *new_short = makeLongWinPath(path, &mem_reserved); - assert_string_equal(new, "\\\\?\\C:\\\\DATA\\FILES\\MUSIC\\MY_MUSIC.mp3"); - printf( "XXXXXXXXXXXX %s\n", new); - assert_int_equal( strlen(new), 37); + (void) state; /* unused */ + + assert_string_equal(new_short, path); + assert_int_equal(mem_reserved, 0); + + const char *longPath = "D://alonglonglonglong/blonglonglonglong/clonglonglonglong/dlonglonglonglong/" + "elonglonglonglong/flonglonglonglong/glonglonglonglong/hlonglonglonglong/ilonglonglonglong/" + "jlonglonglonglong/klonglonglonglong/llonglonglonglong/mlonglonglonglong/nlonglonglonglong/" + "olonglonglonglong/file.txt"; + const char *longPathConv = "\\\\?\\D:\\\\alonglonglonglong\\blonglonglonglong\\clonglonglonglong\\dlonglonglonglong\\" + "elonglonglonglong\\flonglonglonglong\\glonglonglonglong\\hlonglonglonglong\\ilonglonglonglong\\" + "jlonglonglonglong\\klonglonglonglong\\llonglonglonglong\\mlonglonglonglong\\nlonglonglonglong\\" + "olonglonglonglong\\file.txt"; + + const char *new_long = makeLongWinPath(longPath, &mem_reserved); + // printf( "XXXXXXXXXXXX %s %d\n", new_long, mem_reserved); + + assert_string_equal(new_long, longPathConv); + assert_int_equal(mem_reserved, 287); + + // printf( "YYYYYYYYYYYY %ld\n", strlen(new_long)); + assert_int_equal( strlen(new_long), 286); }