From c832a9eee536e8341cced71f5217226cc855442d Mon Sep 17 00:00:00 2001 From: Christian Kamm Date: Fri, 4 Sep 2015 14:00:02 +0200 Subject: [PATCH] csync io: Fix UNC path conversion on Win #3748 Paths that were already in UNC form don't need to be prefixed. --- csync/src/std/c_path.c | 23 ++++++----- csync/tests/encoding_tests/check_encoding.c | 46 ++++++++++++++++++--- 2 files changed, 52 insertions(+), 17 deletions(-) diff --git a/csync/src/std/c_path.c b/csync/src/std/c_path.c index 140a784f74..1094a1c67c 100644 --- a/csync/src/std/c_path.c +++ b/csync/src/std/c_path.c @@ -393,8 +393,8 @@ int c_parse_uri(const char *uri, /* * This function takes a path and converts it to a UNC representation of the - * string. That means that it prepends a \\?\ and convertes all slashes to - * backslashes. + * string. That means that it prepends a \\?\ (unless already UNC) and converts + * all slashes to backslashes. * * Note the following: * - The string must be absolute. @@ -408,27 +408,28 @@ int c_parse_uri(const char *uri, { int len = 0; char *longStr = NULL; - int i = 4; // index where to start changing "/"=>"\" len = strlen(str); longStr = c_malloc(len+5); *longStr = '\0'; // prepend \\?\ and convert '/' => '\' to support long names - if( str[0] == '/' ) { - strncpy( longStr, "\\\\?", 4); - i=3; + if( str[0] == '/' || str[0] == '\\' ) { + // Don't prepend if already UNC + if( !(len > 1 && (str[1] == '/' || str[1] == '\\')) ) { + strcpy( longStr, "\\\\?"); + } } else { - strncpy( longStr, "\\\\?\\", 5); // prepend string by this four magic chars. + strcpy( longStr, "\\\\?\\"); // prepend string by this four magic chars. } strncat( longStr, str, len ); /* replace all occurences of / with the windows native \ */ - while(longStr[i] != '\0') { - if(longStr[i] == '/') { - longStr[i] = '\\'; + char *c = longStr; + for (; *c; ++c) { + if(*c == '/') { + *c = '\\'; } - i++; } return longStr; } diff --git a/csync/tests/encoding_tests/check_encoding.c b/csync/tests/encoding_tests/check_encoding.c index 6df73debfc..bbfbe99c8d 100644 --- a/csync/tests/encoding_tests/check_encoding.c +++ b/csync/tests/encoding_tests/check_encoding.c @@ -146,13 +146,47 @@ 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"; // check a short path - const char *exp_path = "\\\\?\\C:\\\\DATA\\FILES\\MUSIC\\MY_MUSIC.mp3"; - const char *new_short = c_path_to_UNC(path); - (void) state; /* unused */ - assert_string_equal(new_short, exp_path); + { + const char *path = "C://DATA/FILES/MUSIC/MY_MUSIC.mp3"; // check a short path + const char *exp_path = "\\\\?\\C:\\\\DATA\\FILES\\MUSIC\\MY_MUSIC.mp3"; + const char *new_short = c_path_to_UNC(path); + assert_string_equal(new_short, exp_path); + SAFE_FREE(new_short); + } + + { + const char *path = "\\\\foo\\bar/MY_MUSIC.mp3"; + const char *exp_path = "\\\\foo\\bar\\MY_MUSIC.mp3"; + const char *new_short = c_path_to_UNC(path); + assert_string_equal(new_short, exp_path); + SAFE_FREE(new_short); + } + + { + const char *path = "//foo\\bar/MY_MUSIC.mp3"; + const char *exp_path = "\\\\foo\\bar\\MY_MUSIC.mp3"; + const char *new_short = c_path_to_UNC(path); + assert_string_equal(new_short, exp_path); + SAFE_FREE(new_short); + } + + { + const char *path = "\\foo\\bar"; + const char *exp_path = "\\\\?\\foo\\bar"; + const char *new_short = c_path_to_UNC(path); + assert_string_equal(new_short, exp_path); + SAFE_FREE(new_short); + } + + { + const char *path = "/foo/bar"; + const char *exp_path = "\\\\?\\foo\\bar"; + const char *new_short = c_path_to_UNC(path); + assert_string_equal(new_short, exp_path); + SAFE_FREE(new_short); + } const char *longPath = "D://alonglonglonglong/blonglonglonglong/clonglonglonglong/dlonglonglonglong/" "elonglonglonglong/flonglonglonglong/glonglonglonglong/hlonglonglonglong/ilonglonglonglong/" @@ -170,7 +204,7 @@ static void check_long_win_path(void **state) // printf( "YYYYYYYYYYYY %ld\n", strlen(new_long)); assert_int_equal( strlen(new_long), 286); - + SAFE_FREE(new_long); } int torture_run_tests(void)