| | @@ -398,10 +398,49 @@ |
| 398 | 398 | */ |
| 399 | 399 | void manifest_clear_cache(){ |
| 400 | 400 | bag_clear(&seenManifests); |
| 401 | 401 | } |
| 402 | 402 | |
| 403 | + |
| 404 | +/* |
| 405 | +** SETTING: strict-manifest-syntax boolean default=on sensitive |
| 406 | +** LEAVE THIS SETTING TURNED ON! |
| 407 | +** |
| 408 | +** This flag indicates that manifest syntax should be strictly enforced. |
| 409 | +** It defaults to on. Clearing this flag is a security risk. |
| 410 | +** |
| 411 | +** Some questionable constructs were allowed in manifests in historical |
| 412 | +** versions of Fossil. In particular, it was formerly allowed to |
| 413 | +** include names like "_FOSSIL_" or ".fslckout" in subdirectories. But |
| 414 | +** doing so can lead to problems, and so newer versions of Fossil disallow |
| 415 | +** that. |
| 416 | +** |
| 417 | +** This flag allows the older questionable constructs to appear in |
| 418 | +** manifests for backwards compatibility for the very rare repositories |
| 419 | +** that make use of the questionable behavior. |
| 420 | +*/ |
| 421 | + |
| 422 | +/* |
| 423 | +** Return true if manifest parsing rules are strictly enforced. Return |
| 424 | +** zero is certain questionable constructs should be allowed for legacy |
| 425 | +** compatibility. |
| 426 | +** |
| 427 | +** At the current time, the only questionable construct that this applies |
| 428 | +** to is the use of filenames like "_FOSSIL_" or ".fslckout" in subdirectories |
| 429 | +** of the repository. These names have never been allowed in the top-level |
| 430 | +** directory, but historical versions of fossil allowed them in subdirectories. |
| 431 | +** |
| 432 | +** This routine is only called if a questionable construct is encountered, |
| 433 | +** which is to say it is rarely called. |
| 434 | +*/ |
| 435 | +int manifest_strict_enforcement(void){ |
| 436 | + if( g.manifestStrict==0 ){ |
| 437 | + g.manifestStrict = db_get_boolean("strict-manifest-syntax",1) + 1; |
| 438 | + } |
| 439 | + return g.manifestStrict - 1; |
| 440 | +} |
| 441 | + |
| 403 | 442 | /* |
| 404 | 443 | ** Parse a blob into a Manifest object. The Manifest object |
| 405 | 444 | ** takes over the input blob and will free it when the |
| 406 | 445 | ** Manifest object is freed. Zeros are inserted into the blob |
| 407 | 446 | ** as string terminators so that blob should not be used again. |
| | @@ -632,11 +671,12 @@ |
| 632 | 671 | zName = next_token(&x,0); |
| 633 | 672 | if( zName==0 ) SYNTAX("missing filename on F-card"); |
| 634 | 673 | defossilize(zName); |
| 635 | 674 | if( !file_is_simple_pathname_nonstrict(zName) ){ |
| 636 | 675 | SYNTAX("F-card filename is not a simple path"); |
| 637 | | - }else if( file_is_reserved_name(zName,-1) ){ |
| 676 | + }else if( file_is_reserved_name(zName,-1) |
| 677 | + && manifest_strict_enforcement() ){ |
| 638 | 678 | SYNTAX("F-card contains a reserved name"); |
| 639 | 679 | } |
| 640 | 680 | zUuid = next_token(&x, &sz); |
| 641 | 681 | if( p->zBaseline==0 || zUuid!=0 ){ |
| 642 | 682 | if( zUuid==0 ) SYNTAX("missing hash on F-card"); |
| 643 | 683 | |