Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
| Comment: | Add support for extended UNC paths as well, and add Windows/Cygwin-specific test-cases for it. |
|---|---|
| Downloads: | Tarball | ZIP archive |
| Timelines: | family | ancestors | descendants | both | extended-path-prefix |
| Files: | files | file ages | folders |
| SHA1: |
ebb42b530e4c3dc9c8e5c5e8077617ed |
| User & Date: | jan.nijtmans 2014-02-26 10:42:44.436 |
Context
|
2014-02-28
| ||
| 13:46 | Handle win32 extended path prefix everywhere: Just strip it in the function file_simplify_name(), and only add it back when needed (just before feeding it to a win32 function when >260 chars). Includes additional test-cases. check-in: 95f004b1c5 user: jan.nijtmans tags: trunk | |
|
2014-02-26
| ||
| 10:42 | Add support for extended UNC paths as well, and add Windows/Cygwin-specific test-cases for it. Closed-Leaf check-in: ebb42b530e user: jan.nijtmans tags: extended-path-prefix | |
|
2014-02-25
| ||
| 13:31 | Follow-up to [8ab08d32c7]: Fossil still doesn't handle the extended path prefix on win32 ('\\?\') right, mainly in checking paths. e.g.: "fossil add //\?/C:/Localdata/workspace/fossil/foo.c". Fossil cannot know that this path is correct. Solution: Strip the extended path prefix in file_simplify_name(), and only add it back when needed. Latest "winhttp.c" changes could be reverted with this change when compiling with MSVC or MinGW-w64 (as the repository path after simplicifation doesn't contain '?' any more), but when using MinGW the command-line handling cannot be thrusted. check-in: ce4afc891c user: jan.nijtmans tags: extended-path-prefix | |
Changes
Changes to src/file.c.
| ︙ | ︙ | |||
642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 |
*pJ = i-1;
return 1;
}
/*
** Simplify a filename by
**
** * Convert all \ into / on windows and cygwin
** * removing any trailing and duplicate /
** * removing /./
** * removing /A/../
**
** Changes are made in-place. Return the new name length.
** If the slash parameter is non-zero, the trailing slash, if any,
** is retained.
*/
int file_simplify_name(char *z, int n, int slash){
int i = 1, j;
if( n<0 ) n = strlen(z);
/* On windows and cygwin convert all \ characters to /
* and remove extended path prefix if present */
#if defined(_WIN32) || defined(__CYGWIN__)
for(j=0; j<n; j++){
if( z[j]=='\\' ) z[j] = '/';
}
if( n>3 && !memcmp(z, "//?/", 4) ){
| > > | | > > > > | 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 |
*pJ = i-1;
return 1;
}
/*
** Simplify a filename by
**
** * Remove extended path prefix on windows and cygwin
** * Convert all \ into / on windows and cygwin
** * removing any trailing and duplicate /
** * removing /./
** * removing /A/../
**
** Changes are made in-place. Return the new name length.
** If the slash parameter is non-zero, the trailing slash, if any,
** is retained.
*/
int file_simplify_name(char *z, int n, int slash){
int i = 1, j;
if( n<0 ) n = strlen(z);
/* On windows and cygwin convert all \ characters to /
* and remove extended path prefix if present */
#if defined(_WIN32) || defined(__CYGWIN__)
for(j=0; j<n; j++){
if( z[j]=='\\' ) z[j] = '/';
}
if( n>3 && !memcmp(z, "//?/", 4) ){
if( fossil_strnicmp(z+4,"UNC", 3) ){
i += 4;
z[0] = z[4];
}else{
i += 6;
z[0] = '/';
}
}
#endif
/* Removing trailing "/" characters */
if( !slash ){
while( n>1 && z[n-1]=='/' ){ n--; }
}
|
| ︙ | ︙ |
Changes to src/utf8.c.
| ︙ | ︙ | |||
188 189 190 191 192 193 194 |
**
** See: <http://cygwin.com/cygwin-ug-net/using-specialnames.html>
**
*/
void *fossil_utf8_to_filename(const char *zUtf8){
#ifdef _WIN32
int nChar = MultiByteToWideChar(CP_UTF8, 0, zUtf8, -1, 0, 0);
| | | < < < < < < < | | | | | | > > > > > > > > > > > > > | 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 |
**
** See: <http://cygwin.com/cygwin-ug-net/using-specialnames.html>
**
*/
void *fossil_utf8_to_filename(const char *zUtf8){
#ifdef _WIN32
int nChar = MultiByteToWideChar(CP_UTF8, 0, zUtf8, -1, 0, 0);
/* Overallocate 6 chars, making some room for extended paths */
wchar_t *zUnicode = sqlite3_malloc( (nChar+6) * sizeof(wchar_t) );
wchar_t *wUnicode = zUnicode;
if( zUnicode==0 ){
return 0;
}
MultiByteToWideChar(CP_UTF8, 0, zUtf8, -1, zUnicode, nChar);
/*
** If path starts with "//?/" or "\\?\" (extended path), translate
** any slashes to backslashes but leave the '?' intact
*/
if( (zUtf8[0]=='\\' || zUtf8[0]=='/') && (zUtf8[1]=='\\' || zUtf8[1]=='/')
&& zUtf8[2]=='?' && (zUtf8[3]=='\\' || zUtf8[3]=='/')) {
wUnicode[0] = wUnicode[1] = wUnicode[3] = '\\';
zUtf8 += 4;
wUnicode += 4;
}
/*
** If there is no "\\?\" prefix but there is a drive or UNC
** path prefix and the path is larger than MAX_PATH chars,
** no Win32 API function can handle that unless it is
** prefixed with the extended path prefix. See:
** <http://msdn.microsoft.com/en-us/library/aa365247(VS.85).aspx#maxpath>
**/
if( fossil_isalpha(zUtf8[0]) && zUtf8[1]==':'
&& (zUtf8[2]=='\\' || zUtf8[2]=='/') ){
if( wUnicode==zUnicode && nChar>MAX_PATH){
memmove(wUnicode+4, wUnicode, nChar*sizeof(wchar_t));
memcpy(wUnicode, L"\\\\?\\", 4*sizeof(wchar_t));
wUnicode += 4;
}
/*
** If (remainder of) path starts with "<drive>:/" or "<drive>:\",
** leave the ':' intact but translate the backslash to a slash.
*/
wUnicode[2] = '\\';
wUnicode += 3;
}else if( wUnicode==zUnicode && nChar>MAX_PATH
&& (zUtf8[0]=='\\' || zUtf8[0]=='/')
&& (zUtf8[1]=='\\' || zUtf8[1]=='/') && zUtf8[2]!='?'){
memmove(wUnicode+6, wUnicode, nChar*sizeof(wchar_t));
memcpy(wUnicode, L"\\\\?\\UNC", 7*sizeof(wchar_t));
wUnicode += 7;
}
/*
** In the remainder of the path, translate invalid characters to
** characters in the Unicode private use area. This is what makes
** Win32 fossil.exe work well in a Cygwin environment even when a
** filename contains characters which are invalid for Win32.
*/
|
| ︙ | ︙ |
Changes to test/file1.test.
| ︙ | ︙ | |||
31 32 33 34 35 36 37 |
simplify-name 101 {} {} / / ///////// / ././././ .
simplify-name 102 x x /x /x ///x //x
simplify-name 103 a/b a/b /a/b /a/b a///b a/b ///a///b///// //a/b
simplify-name 104 a/b/../c/ a/c /a/b/../c /a/c /a/b//../c /a/c /a/b/..///c /a/c
simplify-name 105 a/b/../../x/y x/y /a/b/../../x/y /x/y
simplify-name 106 a/b/../../../x/y ../x/y /a/b/../../../x/y /../x/y
simplify-name 107 a/./b/.././../x/y x/y a//.//b//..//.//..//x//y/// x/y
| > > > > > | 31 32 33 34 35 36 37 38 39 40 41 42 |
simplify-name 101 {} {} / / ///////// / ././././ .
simplify-name 102 x x /x /x ///x //x
simplify-name 103 a/b a/b /a/b /a/b a///b a/b ///a///b///// //a/b
simplify-name 104 a/b/../c/ a/c /a/b/../c /a/c /a/b//../c /a/c /a/b/..///c /a/c
simplify-name 105 a/b/../../x/y x/y /a/b/../../x/y /x/y
simplify-name 106 a/b/../../../x/y ../x/y /a/b/../../../x/y /../x/y
simplify-name 107 a/./b/.././../x/y x/y a//.//b//..//.//..//x//y/// x/y
if {$::tcl_platform(os)=="Windows NT"} {
simplify-name 108 //?/a:/a/b a:/a/b //?/UNC/a/b //a/b //?/ {}
simplify-name 109 \\\\?\\a:\\a\\b a:/a/b \\\\?\\UNC\\a\\b //a/b \\\\?\\ {}
}
|