Fossil SCM

Disallow invalid unicode characters in filenames.

drh 2012-11-25 11:50 trunk merge
Commit 897dfa48b4e28b3429f946b73353f1234409967a
+2 -1
--- src/add.c
+++ src/add.c
@@ -138,11 +138,12 @@
138138
int vid, /* Add to this VFILE */
139139
int caseSensitive /* True if filenames are case sensitive */
140140
){
141141
const char *zCollate = caseSensitive ? "binary" : "nocase";
142142
if( !file_is_simple_pathname(zPath) ){
143
- fossil_fatal("filename contains illegal characters: %s", zPath);
143
+ fossil_warning("filename contains illegal characters: %s", zPath);
144
+ return 0;
144145
}
145146
if( db_exists("SELECT 1 FROM vfile"
146147
" WHERE pathname=%Q COLLATE %s", zPath, zCollate) ){
147148
db_multi_exec("UPDATE vfile SET deleted=0"
148149
" WHERE pathname=%Q COLLATE %s", zPath, zCollate);
149150
--- src/add.c
+++ src/add.c
@@ -138,11 +138,12 @@
138 int vid, /* Add to this VFILE */
139 int caseSensitive /* True if filenames are case sensitive */
140 ){
141 const char *zCollate = caseSensitive ? "binary" : "nocase";
142 if( !file_is_simple_pathname(zPath) ){
143 fossil_fatal("filename contains illegal characters: %s", zPath);
 
144 }
145 if( db_exists("SELECT 1 FROM vfile"
146 " WHERE pathname=%Q COLLATE %s", zPath, zCollate) ){
147 db_multi_exec("UPDATE vfile SET deleted=0"
148 " WHERE pathname=%Q COLLATE %s", zPath, zCollate);
149
--- src/add.c
+++ src/add.c
@@ -138,11 +138,12 @@
138 int vid, /* Add to this VFILE */
139 int caseSensitive /* True if filenames are case sensitive */
140 ){
141 const char *zCollate = caseSensitive ? "binary" : "nocase";
142 if( !file_is_simple_pathname(zPath) ){
143 fossil_warning("filename contains illegal characters: %s", zPath);
144 return 0;
145 }
146 if( db_exists("SELECT 1 FROM vfile"
147 " WHERE pathname=%Q COLLATE %s", zPath, zCollate) ){
148 db_multi_exec("UPDATE vfile SET deleted=0"
149 " WHERE pathname=%Q COLLATE %s", zPath, zCollate);
150
+1 -1
--- src/checkout.c
+++ src/checkout.c
@@ -106,11 +106,11 @@
106106
/* Check the EXE permission status of all files
107107
*/
108108
pManifest = manifest_get(vid, CFTYPE_MANIFEST);
109109
if( pManifest==0 ) return;
110110
blob_zero(&filename);
111
- blob_appendf(&filename, "%s/", g.zLocalRoot);
111
+ blob_appendf(&filename, "%s", g.zLocalRoot);
112112
baseLen = blob_size(&filename);
113113
manifest_file_rewind(pManifest);
114114
while( (pFile = manifest_file_next(pManifest, 0))!=0 ){
115115
int isExe;
116116
blob_append(&filename, pFile->zName, -1);
117117
--- src/checkout.c
+++ src/checkout.c
@@ -106,11 +106,11 @@
106 /* Check the EXE permission status of all files
107 */
108 pManifest = manifest_get(vid, CFTYPE_MANIFEST);
109 if( pManifest==0 ) return;
110 blob_zero(&filename);
111 blob_appendf(&filename, "%s/", g.zLocalRoot);
112 baseLen = blob_size(&filename);
113 manifest_file_rewind(pManifest);
114 while( (pFile = manifest_file_next(pManifest, 0))!=0 ){
115 int isExe;
116 blob_append(&filename, pFile->zName, -1);
117
--- src/checkout.c
+++ src/checkout.c
@@ -106,11 +106,11 @@
106 /* Check the EXE permission status of all files
107 */
108 pManifest = manifest_get(vid, CFTYPE_MANIFEST);
109 if( pManifest==0 ) return;
110 blob_zero(&filename);
111 blob_appendf(&filename, "%s", g.zLocalRoot);
112 baseLen = blob_size(&filename);
113 manifest_file_rewind(pManifest);
114 while( (pFile = manifest_file_next(pManifest, 0))!=0 ){
115 int isExe;
116 blob_append(&filename, pFile->zName, -1);
117
+1 -1
--- src/db.c
+++ src/db.c
@@ -1697,11 +1697,11 @@
16971697
** and a checkout is open. */
16981698
if( cacheEntry==0 ){
16991699
Blob versionedPathname;
17001700
char *zVersionedPathname;
17011701
blob_zero(&versionedPathname);
1702
- blob_appendf(&versionedPathname, "%s/.fossil-settings/%s",
1702
+ blob_appendf(&versionedPathname, "%s.fossil-settings/%s",
17031703
g.zLocalRoot, zName);
17041704
zVersionedPathname = blob_str(&versionedPathname);
17051705
if( file_size(zVersionedPathname)>=0 ){
17061706
/* File exists, and contains the value for this setting. Load from
17071707
** the file. */
17081708
--- src/db.c
+++ src/db.c
@@ -1697,11 +1697,11 @@
1697 ** and a checkout is open. */
1698 if( cacheEntry==0 ){
1699 Blob versionedPathname;
1700 char *zVersionedPathname;
1701 blob_zero(&versionedPathname);
1702 blob_appendf(&versionedPathname, "%s/.fossil-settings/%s",
1703 g.zLocalRoot, zName);
1704 zVersionedPathname = blob_str(&versionedPathname);
1705 if( file_size(zVersionedPathname)>=0 ){
1706 /* File exists, and contains the value for this setting. Load from
1707 ** the file. */
1708
--- src/db.c
+++ src/db.c
@@ -1697,11 +1697,11 @@
1697 ** and a checkout is open. */
1698 if( cacheEntry==0 ){
1699 Blob versionedPathname;
1700 char *zVersionedPathname;
1701 blob_zero(&versionedPathname);
1702 blob_appendf(&versionedPathname, "%s.fossil-settings/%s",
1703 g.zLocalRoot, zName);
1704 zVersionedPathname = blob_str(&versionedPathname);
1705 if( file_size(zVersionedPathname)>=0 ){
1706 /* File exists, and contains the value for this setting. Load from
1707 ** the file. */
1708
+25
--- src/file.c
+++ src/file.c
@@ -495,10 +495,35 @@
495495
if( c=='.' ){
496496
if( z[1]=='/' || z[1]==0 ) return 0;
497497
if( z[1]=='.' && (z[2]=='/' || z[2]==0) ) return 0;
498498
}
499499
for(i=0; (c=z[i])!=0; i++){
500
+ if( (c & 0xf0) == 0xf0 ) {
501
+ /* Unicode characters > U+FFFF are not supported.
502
+ * Windows XP and earlier cannot handle them.
503
+ */
504
+ return 0;
505
+ }
506
+ if( (c & 0xf0) == 0xe0 ) {
507
+ /* This is a 3-byte UTF-8 character */
508
+ if ( (c & 0xfe) == 0xee ){
509
+ /* Range U+E000 - U+FFFF (Starting with 0xee or 0xef in UTF-8 ) */
510
+ if ( (c & 1) && ((z[i+1] & 0xff) >= 0xa4) ){
511
+ /* But exclude U+F900 - U+FFFF (0xef followed by byte >= 0xa4),
512
+ * which contain valid characters. */
513
+ continue;
514
+ }
515
+ /* Unicode character in the range U+E000 - U+F8FF are for
516
+ * private use, they shouldn't occur in filenames. */
517
+ return 0;
518
+ }
519
+ if( ((c & 0xff) == 0xed) && ((z[i+1] & 0xe0) == 0xa0) ){
520
+ /* Unicode character in the range U+D800 - U+DFFF are for
521
+ * surrogate pairs, they shouldn't occur in filenames. */
522
+ return 0;
523
+ }
524
+ }
500525
if( c=='\\' || c=='*' || c=='[' || c==']' || c=='?' ){
501526
return 0;
502527
}
503528
if( c=='/' ){
504529
if( z[i+1]=='/' ) return 0;
505530
--- src/file.c
+++ src/file.c
@@ -495,10 +495,35 @@
495 if( c=='.' ){
496 if( z[1]=='/' || z[1]==0 ) return 0;
497 if( z[1]=='.' && (z[2]=='/' || z[2]==0) ) return 0;
498 }
499 for(i=0; (c=z[i])!=0; i++){
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
500 if( c=='\\' || c=='*' || c=='[' || c==']' || c=='?' ){
501 return 0;
502 }
503 if( c=='/' ){
504 if( z[i+1]=='/' ) return 0;
505
--- src/file.c
+++ src/file.c
@@ -495,10 +495,35 @@
495 if( c=='.' ){
496 if( z[1]=='/' || z[1]==0 ) return 0;
497 if( z[1]=='.' && (z[2]=='/' || z[2]==0) ) return 0;
498 }
499 for(i=0; (c=z[i])!=0; i++){
500 if( (c & 0xf0) == 0xf0 ) {
501 /* Unicode characters > U+FFFF are not supported.
502 * Windows XP and earlier cannot handle them.
503 */
504 return 0;
505 }
506 if( (c & 0xf0) == 0xe0 ) {
507 /* This is a 3-byte UTF-8 character */
508 if ( (c & 0xfe) == 0xee ){
509 /* Range U+E000 - U+FFFF (Starting with 0xee or 0xef in UTF-8 ) */
510 if ( (c & 1) && ((z[i+1] & 0xff) >= 0xa4) ){
511 /* But exclude U+F900 - U+FFFF (0xef followed by byte >= 0xa4),
512 * which contain valid characters. */
513 continue;
514 }
515 /* Unicode character in the range U+E000 - U+F8FF are for
516 * private use, they shouldn't occur in filenames. */
517 return 0;
518 }
519 if( ((c & 0xff) == 0xed) && ((z[i+1] & 0xe0) == 0xa0) ){
520 /* Unicode character in the range U+D800 - U+DFFF are for
521 * surrogate pairs, they shouldn't occur in filenames. */
522 return 0;
523 }
524 }
525 if( c=='\\' || c=='*' || c=='[' || c==']' || c=='?' ){
526 return 0;
527 }
528 if( c=='/' ){
529 if( z[i+1]=='/' ) return 0;
530

Keyboard Shortcuts

Open search /
Next entry (timeline) j
Previous entry (timeline) k
Open focused entry Enter
Show this help ?
Toggle theme Top nav button