Fossil SCM
Fix bug in utf8.c (don't translate first ':' in extended path). Add test-case (win32-longpath.test). Some formatting (don't use tabs).
Commit
7d5c1bbd9c101347953a2b5f43f9a426d1b61027
Parent
23b849cce52d189…
3 files changed
+6
-6
+10
-5
+33
+6
-6
| --- src/sqlite3.c | ||
| +++ src/sqlite3.c | ||
| @@ -35152,27 +35152,27 @@ | ||
| 35152 | 35152 | /* No Win32 API functions can handle such long paths. Let's see if |
| 35153 | 35153 | * we can do something about it. If not, just leave it as is. */ |
| 35154 | 35154 | if( winIsDirSep(zFilename[0]) && winIsDirSep(zFilename[1]) |
| 35155 | 35155 | && zFilename[2]!='?' ){ |
| 35156 | 35156 | /* It's an UNC path, convert it to an extended UNC path. */ |
| 35157 | - zWideFilename = sqlite3MallocZero( (nChar+6)*sizeof(WCHAR) ); | |
| 35158 | - if( !zWideFilename ){ | |
| 35157 | + zWideFilename = sqlite3MallocZero( (nChar+6)*sizeof(WCHAR) ); | |
| 35158 | + if( zWideFilename ){ | |
| 35159 | 35159 | memcpy(zWideFilename, L"\\\\?\\UNC\\", 16); |
| 35160 | 35160 | nChar = osMultiByteToWideChar(CP_UTF8, 0, zFilename+2, -1, |
| 35161 | 35161 | zWideFilename+8, nChar); |
| 35162 | - } | |
| 35162 | + } | |
| 35163 | 35163 | return zWideFilename; |
| 35164 | 35164 | }else if( winIsDriveLetterAndColon(zFilename) |
| 35165 | 35165 | && winIsDirSep(zFilename[2]) ){ |
| 35166 | 35166 | /* It has a correct drive prefix, convert to extended form. */ |
| 35167 | - zWideFilename = sqlite3MallocZero( (nChar+4)*sizeof(WCHAR) ); | |
| 35168 | - if( !zWideFilename ){ | |
| 35167 | + zWideFilename = sqlite3MallocZero( (nChar+4)*sizeof(WCHAR) ); | |
| 35168 | + if( zWideFilename ){ | |
| 35169 | 35169 | memcpy(zWideFilename, L"\\\\?\\", 8); |
| 35170 | 35170 | nChar = osMultiByteToWideChar(CP_UTF8, 0, zFilename, -1, |
| 35171 | 35171 | zWideFilename+4, nChar); |
| 35172 | 35172 | zWideFilename[6] = '\\'; |
| 35173 | - } | |
| 35173 | + } | |
| 35174 | 35174 | return zWideFilename; |
| 35175 | 35175 | } |
| 35176 | 35176 | /* Another form, e.g. relative path or maybe it already |
| 35177 | 35177 | * has the '\\?\' prefix. Just leave it as-is. */ |
| 35178 | 35178 | } |
| 35179 | 35179 |
| --- src/sqlite3.c | |
| +++ src/sqlite3.c | |
| @@ -35152,27 +35152,27 @@ | |
| 35152 | /* No Win32 API functions can handle such long paths. Let's see if |
| 35153 | * we can do something about it. If not, just leave it as is. */ |
| 35154 | if( winIsDirSep(zFilename[0]) && winIsDirSep(zFilename[1]) |
| 35155 | && zFilename[2]!='?' ){ |
| 35156 | /* It's an UNC path, convert it to an extended UNC path. */ |
| 35157 | zWideFilename = sqlite3MallocZero( (nChar+6)*sizeof(WCHAR) ); |
| 35158 | if( !zWideFilename ){ |
| 35159 | memcpy(zWideFilename, L"\\\\?\\UNC\\", 16); |
| 35160 | nChar = osMultiByteToWideChar(CP_UTF8, 0, zFilename+2, -1, |
| 35161 | zWideFilename+8, nChar); |
| 35162 | } |
| 35163 | return zWideFilename; |
| 35164 | }else if( winIsDriveLetterAndColon(zFilename) |
| 35165 | && winIsDirSep(zFilename[2]) ){ |
| 35166 | /* It has a correct drive prefix, convert to extended form. */ |
| 35167 | zWideFilename = sqlite3MallocZero( (nChar+4)*sizeof(WCHAR) ); |
| 35168 | if( !zWideFilename ){ |
| 35169 | memcpy(zWideFilename, L"\\\\?\\", 8); |
| 35170 | nChar = osMultiByteToWideChar(CP_UTF8, 0, zFilename, -1, |
| 35171 | zWideFilename+4, nChar); |
| 35172 | zWideFilename[6] = '\\'; |
| 35173 | } |
| 35174 | return zWideFilename; |
| 35175 | } |
| 35176 | /* Another form, e.g. relative path or maybe it already |
| 35177 | * has the '\\?\' prefix. Just leave it as-is. */ |
| 35178 | } |
| 35179 |
| --- src/sqlite3.c | |
| +++ src/sqlite3.c | |
| @@ -35152,27 +35152,27 @@ | |
| 35152 | /* No Win32 API functions can handle such long paths. Let's see if |
| 35153 | * we can do something about it. If not, just leave it as is. */ |
| 35154 | if( winIsDirSep(zFilename[0]) && winIsDirSep(zFilename[1]) |
| 35155 | && zFilename[2]!='?' ){ |
| 35156 | /* It's an UNC path, convert it to an extended UNC path. */ |
| 35157 | zWideFilename = sqlite3MallocZero( (nChar+6)*sizeof(WCHAR) ); |
| 35158 | if( zWideFilename ){ |
| 35159 | memcpy(zWideFilename, L"\\\\?\\UNC\\", 16); |
| 35160 | nChar = osMultiByteToWideChar(CP_UTF8, 0, zFilename+2, -1, |
| 35161 | zWideFilename+8, nChar); |
| 35162 | } |
| 35163 | return zWideFilename; |
| 35164 | }else if( winIsDriveLetterAndColon(zFilename) |
| 35165 | && winIsDirSep(zFilename[2]) ){ |
| 35166 | /* It has a correct drive prefix, convert to extended form. */ |
| 35167 | zWideFilename = sqlite3MallocZero( (nChar+4)*sizeof(WCHAR) ); |
| 35168 | if( zWideFilename ){ |
| 35169 | memcpy(zWideFilename, L"\\\\?\\", 8); |
| 35170 | nChar = osMultiByteToWideChar(CP_UTF8, 0, zFilename, -1, |
| 35171 | zWideFilename+4, nChar); |
| 35172 | zWideFilename[6] = '\\'; |
| 35173 | } |
| 35174 | return zWideFilename; |
| 35175 | } |
| 35176 | /* Another form, e.g. relative path or maybe it already |
| 35177 | * has the '\\?\' prefix. Just leave it as-is. */ |
| 35178 | } |
| 35179 |
+10
-5
| --- src/utf8.c | ||
| +++ src/utf8.c | ||
| @@ -206,15 +206,20 @@ | ||
| 206 | 206 | wUnicode += 4; |
| 207 | 207 | MultiByteToWideChar(CP_UTF8, 0, zUtf8, -1, wUnicode, nChar); |
| 208 | 208 | wUnicode[2] = '\\'; |
| 209 | 209 | wUnicode += 3; |
| 210 | 210 | }else if( (zUtf8[0]=='\\' || zUtf8[0]=='/') && |
| 211 | - (zUtf8[1]=='\\' || zUtf8[1]=='/') && zUtf8[2]!='?' ) { | |
| 212 | - /* Convert to extended UNC path. */ | |
| 213 | - memcpy(zUnicode, L"\\\\?\\UNC\\", 16); | |
| 214 | - wUnicode += 8; | |
| 215 | - MultiByteToWideChar(CP_UTF8, 0, zUtf8+2, -1, wUnicode, nChar); | |
| 211 | + (zUtf8[1]=='\\' || zUtf8[1]=='/') ) { | |
| 212 | + if (zUtf8[2]=='?'){ | |
| 213 | + MultiByteToWideChar(CP_UTF8, 0, zUtf8, -1, wUnicode, nChar); | |
| 214 | + wUnicode+=6; | |
| 215 | + }else{ | |
| 216 | + /* Convert to extended UNC path. */ | |
| 217 | + memcpy(zUnicode, L"\\\\?\\UNC\\", 16); | |
| 218 | + wUnicode += 8; | |
| 219 | + MultiByteToWideChar(CP_UTF8, 0, zUtf8+2, -1, wUnicode, nChar); | |
| 220 | + } | |
| 216 | 221 | }else{ |
| 217 | 222 | MultiByteToWideChar(CP_UTF8, 0, zUtf8, -1, wUnicode, nChar); |
| 218 | 223 | } |
| 219 | 224 | while( *wUnicode != '\0' ){ |
| 220 | 225 | if ( (*wUnicode < ' ') || wcschr(L"\"*:<>?|", *wUnicode) ){ |
| 221 | 226 | |
| 222 | 227 | ADDED test/win32-longpath.test |
| --- src/utf8.c | |
| +++ src/utf8.c | |
| @@ -206,15 +206,20 @@ | |
| 206 | wUnicode += 4; |
| 207 | MultiByteToWideChar(CP_UTF8, 0, zUtf8, -1, wUnicode, nChar); |
| 208 | wUnicode[2] = '\\'; |
| 209 | wUnicode += 3; |
| 210 | }else if( (zUtf8[0]=='\\' || zUtf8[0]=='/') && |
| 211 | (zUtf8[1]=='\\' || zUtf8[1]=='/') && zUtf8[2]!='?' ) { |
| 212 | /* Convert to extended UNC path. */ |
| 213 | memcpy(zUnicode, L"\\\\?\\UNC\\", 16); |
| 214 | wUnicode += 8; |
| 215 | MultiByteToWideChar(CP_UTF8, 0, zUtf8+2, -1, wUnicode, nChar); |
| 216 | }else{ |
| 217 | MultiByteToWideChar(CP_UTF8, 0, zUtf8, -1, wUnicode, nChar); |
| 218 | } |
| 219 | while( *wUnicode != '\0' ){ |
| 220 | if ( (*wUnicode < ' ') || wcschr(L"\"*:<>?|", *wUnicode) ){ |
| 221 | |
| 222 | DDED test/win32-longpath.test |
| --- src/utf8.c | |
| +++ src/utf8.c | |
| @@ -206,15 +206,20 @@ | |
| 206 | wUnicode += 4; |
| 207 | MultiByteToWideChar(CP_UTF8, 0, zUtf8, -1, wUnicode, nChar); |
| 208 | wUnicode[2] = '\\'; |
| 209 | wUnicode += 3; |
| 210 | }else if( (zUtf8[0]=='\\' || zUtf8[0]=='/') && |
| 211 | (zUtf8[1]=='\\' || zUtf8[1]=='/') ) { |
| 212 | if (zUtf8[2]=='?'){ |
| 213 | MultiByteToWideChar(CP_UTF8, 0, zUtf8, -1, wUnicode, nChar); |
| 214 | wUnicode+=6; |
| 215 | }else{ |
| 216 | /* Convert to extended UNC path. */ |
| 217 | memcpy(zUnicode, L"\\\\?\\UNC\\", 16); |
| 218 | wUnicode += 8; |
| 219 | MultiByteToWideChar(CP_UTF8, 0, zUtf8+2, -1, wUnicode, nChar); |
| 220 | } |
| 221 | }else{ |
| 222 | MultiByteToWideChar(CP_UTF8, 0, zUtf8, -1, wUnicode, nChar); |
| 223 | } |
| 224 | while( *wUnicode != '\0' ){ |
| 225 | if ( (*wUnicode < ' ') || wcschr(L"\"*:<>?|", *wUnicode) ){ |
| 226 | |
| 227 | DDED test/win32-longpath.test |
+33
| --- a/test/win32-longpath.test | ||
| +++ b/test/win32-longpath.test | ||
| @@ -0,0 +1,33 @@ | ||
| 1 | +# | |
| 2 | +# Tests for 'win32-longpath' VFS, using a repo path >260 chars. | |
| 3 | +# | |
| 4 | +# Actually, this test should pass on any platform. | |
| 5 | +# | |
| 6 | + | |
| 7 | +# Fossil will write data on $HOME, running 'fossil new' here. | |
| 8 | +# We need not to clutter the $HOME of the test caller. | |
| 9 | +# | |
| 10 | +set env(HOME) [pwd] | |
| 11 | + | |
| 12 | +# Create the repo | |
| 13 | +# | |
| 14 | +set x [string repeat x 132] | |
| 15 | +set longpath [pwd]/$x | |
| 16 | +file mkdir $longpath | |
| 17 | +catch { | |
| 18 | + # Use "cygpath" for converting it to win32 path. If not | |
| 19 | + # in Msys or Cygwin shell, nothing needs to be done. | |
| 20 | + set longpath [exec cygpath -w $longpath] | |
| 21 | +} | |
| 22 | + | |
| 23 | +test longpath-test.1 { | |
| 24 | + ![catch { | |
| 25 | + t.1 { | |
| 26 | + ![regexp CANTOPEN [fos | |
| 27 | + }] | |
| 28 | +} | |
| 29 | + | |
| 30 | +catch { | |
| 31 | + # If file deletion fails because your shell cannot | |
| 32 | + # handle that, you need to clean it up manually | |
| 33 | + |
| --- a/test/win32-longpath.test | |
| +++ b/test/win32-longpath.test | |
| @@ -0,0 +1,33 @@ | |
| --- a/test/win32-longpath.test | |
| +++ b/test/win32-longpath.test | |
| @@ -0,0 +1,33 @@ | |
| 1 | # |
| 2 | # Tests for 'win32-longpath' VFS, using a repo path >260 chars. |
| 3 | # |
| 4 | # Actually, this test should pass on any platform. |
| 5 | # |
| 6 | |
| 7 | # Fossil will write data on $HOME, running 'fossil new' here. |
| 8 | # We need not to clutter the $HOME of the test caller. |
| 9 | # |
| 10 | set env(HOME) [pwd] |
| 11 | |
| 12 | # Create the repo |
| 13 | # |
| 14 | set x [string repeat x 132] |
| 15 | set longpath [pwd]/$x |
| 16 | file mkdir $longpath |
| 17 | catch { |
| 18 | # Use "cygpath" for converting it to win32 path. If not |
| 19 | # in Msys or Cygwin shell, nothing needs to be done. |
| 20 | set longpath [exec cygpath -w $longpath] |
| 21 | } |
| 22 | |
| 23 | test longpath-test.1 { |
| 24 | ![catch { |
| 25 | t.1 { |
| 26 | ![regexp CANTOPEN [fos |
| 27 | }] |
| 28 | } |
| 29 | |
| 30 | catch { |
| 31 | # If file deletion fails because your shell cannot |
| 32 | # handle that, you need to clean it up manually |
| 33 |