Fossil SCM
For the '--no-dir-symlinks' flag to be honored when the 'allow-symlinks' setting is disabled, the file_wd_isdir() function must force lstat() to be used.
Commit
6c90761bcd7e29c57bb2acf93a4c3750f8f16243
Parent
957865107d8242b…
1 file changed
+13
-6
+13
-6
| --- src/file.c | ||
| +++ src/file.c | ||
| @@ -85,11 +85,16 @@ | ||
| 85 | 85 | /* |
| 86 | 86 | ** Fill stat buf with information received from stat() or lstat(). |
| 87 | 87 | ** lstat() is called on Unix if isWd is TRUE and allow-symlinks setting is on. |
| 88 | 88 | ** |
| 89 | 89 | */ |
| 90 | -static int fossil_stat(const char *zFilename, struct fossilStat *buf, int isWd){ | |
| 90 | +static int fossil_stat( | |
| 91 | + const char *zFilename, /* name of file or directory to inspect. */ | |
| 92 | + struct fossilStat *buf, /* pointer to buffer where info should go. */ | |
| 93 | + int isWd, /* non-zero to consider look at symlink itself. */ | |
| 94 | + int forceWd /* non-zero to force look at symlink itself. */ | |
| 95 | +){ | |
| 91 | 96 | int rc; |
| 92 | 97 | void *zMbcs = fossil_utf8_to_path(zFilename, 0); |
| 93 | 98 | #if !defined(_WIN32) |
| 94 | 99 | if( isWd && db_allow_symlinks(0) ){ |
| 95 | 100 | rc = lstat(zMbcs, buf); |
| @@ -115,11 +120,11 @@ | ||
| 115 | 120 | static int getStat(const char *zFilename, int isWd){ |
| 116 | 121 | int rc = 0; |
| 117 | 122 | if( zFilename==0 ){ |
| 118 | 123 | if( fileStatValid==0 ) rc = 1; |
| 119 | 124 | }else{ |
| 120 | - if( fossil_stat(zFilename, &fileStat, isWd)!=0 ){ | |
| 125 | + if( fossil_stat(zFilename, &fileStat, isWd, 0)!=0 ){ | |
| 121 | 126 | fileStatValid = 0; |
| 122 | 127 | rc = 1; |
| 123 | 128 | }else{ |
| 124 | 129 | fileStatValid = 1; |
| 125 | 130 | rc = 0; |
| @@ -301,19 +306,21 @@ | ||
| 301 | 306 | ** but is something other than a directory. |
| 302 | 307 | */ |
| 303 | 308 | int file_wd_isdir(const char *zFilename){ |
| 304 | 309 | int rc; |
| 305 | 310 | char *zFN; |
| 311 | + struct fossilStat dirFileStat; | |
| 306 | 312 | |
| 307 | 313 | zFN = mprintf("%s", zFilename); |
| 308 | 314 | file_simplify_name(zFN, -1, 0); |
| 309 | - rc = getStat(zFN, 1); | |
| 315 | + memset(&dirFileStat, 0, sizeof(struct fossilStat)); | |
| 316 | + rc = fossil_stat(zFN, &dirFileStat, 1, 1); | |
| 310 | 317 | if( rc ){ |
| 311 | 318 | rc = 0; /* It does not exist at all. */ |
| 312 | - }else if( S_ISDIR(fileStat.st_mode) ){ | |
| 319 | + }else if( S_ISDIR(dirFileStat.st_mode) ){ | |
| 313 | 320 | rc = 1; /* It exists and is a real directory. */ |
| 314 | - }else if( !db_allow_symlinks(1) && S_ISLNK(fileStat.st_mode) ){ | |
| 321 | + }else if( !db_allow_symlinks(1) && S_ISLNK(dirFileStat.st_mode) ){ | |
| 315 | 322 | Blob content; |
| 316 | 323 | blob_read_link(&content, zFN); /* It exists and is a link. */ |
| 317 | 324 | rc = file_wd_isdir(blob_str(&content)); /* Points to directory? */ |
| 318 | 325 | blob_reset(&content); |
| 319 | 326 | }else{ |
| @@ -480,11 +487,11 @@ | ||
| 480 | 487 | */ |
| 481 | 488 | int file_wd_setexe(const char *zFilename, int onoff){ |
| 482 | 489 | int rc = 0; |
| 483 | 490 | #if !defined(_WIN32) |
| 484 | 491 | struct stat buf; |
| 485 | - if( fossil_stat(zFilename, &buf, 1)!=0 || S_ISLNK(buf.st_mode) ) return 0; | |
| 492 | + if( fossil_stat(zFilename, &buf, 1, 0)!=0 || S_ISLNK(buf.st_mode) ) return 0; | |
| 486 | 493 | if( onoff ){ |
| 487 | 494 | int targetMode = (buf.st_mode & 0444)>>2; |
| 488 | 495 | if( (buf.st_mode & 0100)==0 ){ |
| 489 | 496 | chmod(zFilename, buf.st_mode | targetMode); |
| 490 | 497 | rc = 1; |
| 491 | 498 |
| --- src/file.c | |
| +++ src/file.c | |
| @@ -85,11 +85,16 @@ | |
| 85 | /* |
| 86 | ** Fill stat buf with information received from stat() or lstat(). |
| 87 | ** lstat() is called on Unix if isWd is TRUE and allow-symlinks setting is on. |
| 88 | ** |
| 89 | */ |
| 90 | static int fossil_stat(const char *zFilename, struct fossilStat *buf, int isWd){ |
| 91 | int rc; |
| 92 | void *zMbcs = fossil_utf8_to_path(zFilename, 0); |
| 93 | #if !defined(_WIN32) |
| 94 | if( isWd && db_allow_symlinks(0) ){ |
| 95 | rc = lstat(zMbcs, buf); |
| @@ -115,11 +120,11 @@ | |
| 115 | static int getStat(const char *zFilename, int isWd){ |
| 116 | int rc = 0; |
| 117 | if( zFilename==0 ){ |
| 118 | if( fileStatValid==0 ) rc = 1; |
| 119 | }else{ |
| 120 | if( fossil_stat(zFilename, &fileStat, isWd)!=0 ){ |
| 121 | fileStatValid = 0; |
| 122 | rc = 1; |
| 123 | }else{ |
| 124 | fileStatValid = 1; |
| 125 | rc = 0; |
| @@ -301,19 +306,21 @@ | |
| 301 | ** but is something other than a directory. |
| 302 | */ |
| 303 | int file_wd_isdir(const char *zFilename){ |
| 304 | int rc; |
| 305 | char *zFN; |
| 306 | |
| 307 | zFN = mprintf("%s", zFilename); |
| 308 | file_simplify_name(zFN, -1, 0); |
| 309 | rc = getStat(zFN, 1); |
| 310 | if( rc ){ |
| 311 | rc = 0; /* It does not exist at all. */ |
| 312 | }else if( S_ISDIR(fileStat.st_mode) ){ |
| 313 | rc = 1; /* It exists and is a real directory. */ |
| 314 | }else if( !db_allow_symlinks(1) && S_ISLNK(fileStat.st_mode) ){ |
| 315 | Blob content; |
| 316 | blob_read_link(&content, zFN); /* It exists and is a link. */ |
| 317 | rc = file_wd_isdir(blob_str(&content)); /* Points to directory? */ |
| 318 | blob_reset(&content); |
| 319 | }else{ |
| @@ -480,11 +487,11 @@ | |
| 480 | */ |
| 481 | int file_wd_setexe(const char *zFilename, int onoff){ |
| 482 | int rc = 0; |
| 483 | #if !defined(_WIN32) |
| 484 | struct stat buf; |
| 485 | if( fossil_stat(zFilename, &buf, 1)!=0 || S_ISLNK(buf.st_mode) ) return 0; |
| 486 | if( onoff ){ |
| 487 | int targetMode = (buf.st_mode & 0444)>>2; |
| 488 | if( (buf.st_mode & 0100)==0 ){ |
| 489 | chmod(zFilename, buf.st_mode | targetMode); |
| 490 | rc = 1; |
| 491 |
| --- src/file.c | |
| +++ src/file.c | |
| @@ -85,11 +85,16 @@ | |
| 85 | /* |
| 86 | ** Fill stat buf with information received from stat() or lstat(). |
| 87 | ** lstat() is called on Unix if isWd is TRUE and allow-symlinks setting is on. |
| 88 | ** |
| 89 | */ |
| 90 | static int fossil_stat( |
| 91 | const char *zFilename, /* name of file or directory to inspect. */ |
| 92 | struct fossilStat *buf, /* pointer to buffer where info should go. */ |
| 93 | int isWd, /* non-zero to consider look at symlink itself. */ |
| 94 | int forceWd /* non-zero to force look at symlink itself. */ |
| 95 | ){ |
| 96 | int rc; |
| 97 | void *zMbcs = fossil_utf8_to_path(zFilename, 0); |
| 98 | #if !defined(_WIN32) |
| 99 | if( isWd && db_allow_symlinks(0) ){ |
| 100 | rc = lstat(zMbcs, buf); |
| @@ -115,11 +120,11 @@ | |
| 120 | static int getStat(const char *zFilename, int isWd){ |
| 121 | int rc = 0; |
| 122 | if( zFilename==0 ){ |
| 123 | if( fileStatValid==0 ) rc = 1; |
| 124 | }else{ |
| 125 | if( fossil_stat(zFilename, &fileStat, isWd, 0)!=0 ){ |
| 126 | fileStatValid = 0; |
| 127 | rc = 1; |
| 128 | }else{ |
| 129 | fileStatValid = 1; |
| 130 | rc = 0; |
| @@ -301,19 +306,21 @@ | |
| 306 | ** but is something other than a directory. |
| 307 | */ |
| 308 | int file_wd_isdir(const char *zFilename){ |
| 309 | int rc; |
| 310 | char *zFN; |
| 311 | struct fossilStat dirFileStat; |
| 312 | |
| 313 | zFN = mprintf("%s", zFilename); |
| 314 | file_simplify_name(zFN, -1, 0); |
| 315 | memset(&dirFileStat, 0, sizeof(struct fossilStat)); |
| 316 | rc = fossil_stat(zFN, &dirFileStat, 1, 1); |
| 317 | if( rc ){ |
| 318 | rc = 0; /* It does not exist at all. */ |
| 319 | }else if( S_ISDIR(dirFileStat.st_mode) ){ |
| 320 | rc = 1; /* It exists and is a real directory. */ |
| 321 | }else if( !db_allow_symlinks(1) && S_ISLNK(dirFileStat.st_mode) ){ |
| 322 | Blob content; |
| 323 | blob_read_link(&content, zFN); /* It exists and is a link. */ |
| 324 | rc = file_wd_isdir(blob_str(&content)); /* Points to directory? */ |
| 325 | blob_reset(&content); |
| 326 | }else{ |
| @@ -480,11 +487,11 @@ | |
| 487 | */ |
| 488 | int file_wd_setexe(const char *zFilename, int onoff){ |
| 489 | int rc = 0; |
| 490 | #if !defined(_WIN32) |
| 491 | struct stat buf; |
| 492 | if( fossil_stat(zFilename, &buf, 1, 0)!=0 || S_ISLNK(buf.st_mode) ) return 0; |
| 493 | if( onoff ){ |
| 494 | int targetMode = (buf.st_mode & 0444)>>2; |
| 495 | if( (buf.st_mode & 0100)==0 ){ |
| 496 | chmod(zFilename, buf.st_mode | targetMode); |
| 497 | rc = 1; |
| 498 |