Fossil SCM

Moved is_fossil_ckout_db_name() from db.c to file.c and renamed it filename_is_ckout_db(). Integrated the check into manifest_parse(), but testing it requires temporarily #if'ing out the Z-card check, which is one of the first validations.

stephan 2020-08-17 16:10 reject-ckout-db
Commit 6c19baa09b6316cbe6d2b41ead20cfa4cb21eba798ce29227ef5d17fa1c19ab5
-57
--- src/db.c
+++ src/db.c
@@ -1705,67 +1705,10 @@
17051705
** the repository database at hand in order to do the migration, so that
17061706
** step is deferred. */
17071707
return 1;
17081708
}
17091709
1710
-/*
1711
-** Returns true if the given filename ends with any of fossil's
1712
-** checkout database filenames: _FOSSIL_ or .fslckout. Specifically,
1713
-** it returns 1 if it's an exact match and 2 if it's the tail match
1714
-** on a longer input.
1715
-**
1716
-** zFilename must, for efficiency's sake, be a
1717
-** canonicalized/normalized name, e.g. using only '/' as directory
1718
-** separators.
1719
-**
1720
-** nFilename must be the strlen of zFilename. If it is negative,
1721
-** strlen() is used to calculate it.
1722
-*/
1723
-int is_fossil_ckout_db_name(const char *zFilename, int nFilename){
1724
- const char *zEnd;
1725
-
1726
- if(nFilename>=0 && nFilename<8/*strlen _FOSSIL_*/) return 0;
1727
- else if(nFilename<0) nFilename = (int)strlen(zFilename);
1728
- if(nFilename<8) return 0;
1729
- zEnd = zFilename + nFilename;
1730
- switch(zEnd[-1]){
1731
- case '_': {
1732
- return fossil_strcmp("_FOSSIL_", &zEnd[-8])
1733
- ? 0 : (8==nFilename ? 1 : ('/'==zEnd[-9] ? 2 : 0));
1734
- }
1735
- case 't': {
1736
- return (nFilename<9
1737
- || '.'!=zEnd[-9]
1738
- || fossil_strcmp(".fslckout", &zEnd[-9]))
1739
- ? 0 : (9==nFilename ? 1 : ('/'==zEnd[-10] ? 2 : 0));
1740
- }
1741
- default:
1742
- return 0;
1743
- }
1744
-}
1745
-
1746
-/*
1747
-** COMMAND: test-is-ckout-db
1748
-**
1749
-** Usage: %fossil test-is-ckout-db FILENAMES...
1750
-**
1751
-** Passes each given name to is_fossil_ckout_db_name() and outputs one
1752
-** line per file: the result value of that function followed by the
1753
-** name.
1754
-*/
1755
-void test_is_ckout_name_cmd(void){
1756
- int i;
1757
-
1758
- if(g.argc<3){
1759
- usage("FILENAME_1 [...FILENAME_N]");
1760
- }
1761
- for( i = 2; i < g.argc; ++i ){
1762
- const int check = is_fossil_ckout_db_name(g.argv[i], -1);
1763
- fossil_print("%d %s\n", check, g.argv[i]);
1764
- }
1765
-}
1766
-
17671710
/*
17681711
** Locate the root directory of the local repository tree. The root
17691712
** directory is found by searching for a file named "_FOSSIL_" or ".fslckout"
17701713
** that contains a valid repository database.
17711714
**
17721715
--- src/db.c
+++ src/db.c
@@ -1705,67 +1705,10 @@
1705 ** the repository database at hand in order to do the migration, so that
1706 ** step is deferred. */
1707 return 1;
1708 }
1709
1710 /*
1711 ** Returns true if the given filename ends with any of fossil's
1712 ** checkout database filenames: _FOSSIL_ or .fslckout. Specifically,
1713 ** it returns 1 if it's an exact match and 2 if it's the tail match
1714 ** on a longer input.
1715 **
1716 ** zFilename must, for efficiency's sake, be a
1717 ** canonicalized/normalized name, e.g. using only '/' as directory
1718 ** separators.
1719 **
1720 ** nFilename must be the strlen of zFilename. If it is negative,
1721 ** strlen() is used to calculate it.
1722 */
1723 int is_fossil_ckout_db_name(const char *zFilename, int nFilename){
1724 const char *zEnd;
1725
1726 if(nFilename>=0 && nFilename<8/*strlen _FOSSIL_*/) return 0;
1727 else if(nFilename<0) nFilename = (int)strlen(zFilename);
1728 if(nFilename<8) return 0;
1729 zEnd = zFilename + nFilename;
1730 switch(zEnd[-1]){
1731 case '_': {
1732 return fossil_strcmp("_FOSSIL_", &zEnd[-8])
1733 ? 0 : (8==nFilename ? 1 : ('/'==zEnd[-9] ? 2 : 0));
1734 }
1735 case 't': {
1736 return (nFilename<9
1737 || '.'!=zEnd[-9]
1738 || fossil_strcmp(".fslckout", &zEnd[-9]))
1739 ? 0 : (9==nFilename ? 1 : ('/'==zEnd[-10] ? 2 : 0));
1740 }
1741 default:
1742 return 0;
1743 }
1744 }
1745
1746 /*
1747 ** COMMAND: test-is-ckout-db
1748 **
1749 ** Usage: %fossil test-is-ckout-db FILENAMES...
1750 **
1751 ** Passes each given name to is_fossil_ckout_db_name() and outputs one
1752 ** line per file: the result value of that function followed by the
1753 ** name.
1754 */
1755 void test_is_ckout_name_cmd(void){
1756 int i;
1757
1758 if(g.argc<3){
1759 usage("FILENAME_1 [...FILENAME_N]");
1760 }
1761 for( i = 2; i < g.argc; ++i ){
1762 const int check = is_fossil_ckout_db_name(g.argv[i], -1);
1763 fossil_print("%d %s\n", check, g.argv[i]);
1764 }
1765 }
1766
1767 /*
1768 ** Locate the root directory of the local repository tree. The root
1769 ** directory is found by searching for a file named "_FOSSIL_" or ".fslckout"
1770 ** that contains a valid repository database.
1771 **
1772
--- src/db.c
+++ src/db.c
@@ -1705,67 +1705,10 @@
1705 ** the repository database at hand in order to do the migration, so that
1706 ** step is deferred. */
1707 return 1;
1708 }
1709
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1710 /*
1711 ** Locate the root directory of the local repository tree. The root
1712 ** directory is found by searching for a file named "_FOSSIL_" or ".fslckout"
1713 ** that contains a valid repository database.
1714 **
1715
+61
--- src/file.c
+++ src/file.c
@@ -2408,5 +2408,66 @@
24082408
*/
24092409
const char * file_extension(const char *zFileName){
24102410
const char * zExt = zFileName ? strrchr(zFileName, '.') : 0;
24112411
return zExt ? &zExt[1] : 0;
24122412
}
2413
+
2414
+/*
2415
+** Returns true if the given filename ends with any of fossil's
2416
+** checkout database filenames: _FOSSIL_ or .fslckout. Specifically,
2417
+** it returns 1 if it's an exact match and 2 if it's the tail match
2418
+** on a longer input.
2419
+**
2420
+** zFilename must, for efficiency's sake, be a
2421
+** canonicalized/normalized name, e.g. using only '/' as directory
2422
+** separators.
2423
+**
2424
+** nFilename must be the strlen of zFilename. If it is negative,
2425
+** strlen() is used to calculate it.
2426
+**
2427
+** TODO: https://fossil-scm.org/sec2020/info/972cf9c302f5413f
2428
+** TL;DR: check for the -wal, -shm, -journal suffix forms of the db
2429
+** names.
2430
+*/
2431
+int filename_is_ckout_db(const char *zFilename, int nFilename){
2432
+ const char *zEnd;
2433
+
2434
+ if(nFilename>=0 && nFilename<8/*strlen _FOSSIL_*/) return 0;
2435
+ else if(nFilename<0) nFilename = (int)strlen(zFilename);
2436
+ if(nFilename<8) return 0;
2437
+ zEnd = zFilename + nFilename;
2438
+ switch(zEnd[-1]){
2439
+ case '_': {
2440
+ return fossil_strcmp("_FOSSIL_", &zEnd[-8])
2441
+ ? 0 : (8==nFilename ? 1 : ('/'==zEnd[-9] ? 2 : 0));
2442
+ }
2443
+ case 't': {
2444
+ return (nFilename<9
2445
+ || '.'!=zEnd[-9]
2446
+ || fossil_strcmp(".fslckout", &zEnd[-9]))
2447
+ ? 0 : (9==nFilename ? 1 : ('/'==zEnd[-10] ? 2 : 0));
2448
+ }
2449
+ default:
2450
+ return 0;
2451
+ }
2452
+}
2453
+
2454
+/*
2455
+** COMMAND: test-is-ckout-db
2456
+**
2457
+** Usage: %fossil test-is-ckout-db FILENAMES...
2458
+**
2459
+** Passes each given name to filename_is_ckout_db() and outputs one
2460
+** line per file: the result value of that function followed by the
2461
+** name.
2462
+*/
2463
+void test_is_ckout_name_cmd(void){
2464
+ int i;
2465
+
2466
+ if(g.argc<3){
2467
+ usage("FILENAME_1 [...FILENAME_N]");
2468
+ }
2469
+ for( i = 2; i < g.argc; ++i ){
2470
+ const int check = filename_is_ckout_db(g.argv[i], -1);
2471
+ fossil_print("%d %s\n", check, g.argv[i]);
2472
+ }
2473
+}
24132474
--- src/file.c
+++ src/file.c
@@ -2408,5 +2408,66 @@
2408 */
2409 const char * file_extension(const char *zFileName){
2410 const char * zExt = zFileName ? strrchr(zFileName, '.') : 0;
2411 return zExt ? &zExt[1] : 0;
2412 }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2413
--- src/file.c
+++ src/file.c
@@ -2408,5 +2408,66 @@
2408 */
2409 const char * file_extension(const char *zFileName){
2410 const char * zExt = zFileName ? strrchr(zFileName, '.') : 0;
2411 return zExt ? &zExt[1] : 0;
2412 }
2413
2414 /*
2415 ** Returns true if the given filename ends with any of fossil's
2416 ** checkout database filenames: _FOSSIL_ or .fslckout. Specifically,
2417 ** it returns 1 if it's an exact match and 2 if it's the tail match
2418 ** on a longer input.
2419 **
2420 ** zFilename must, for efficiency's sake, be a
2421 ** canonicalized/normalized name, e.g. using only '/' as directory
2422 ** separators.
2423 **
2424 ** nFilename must be the strlen of zFilename. If it is negative,
2425 ** strlen() is used to calculate it.
2426 **
2427 ** TODO: https://fossil-scm.org/sec2020/info/972cf9c302f5413f
2428 ** TL;DR: check for the -wal, -shm, -journal suffix forms of the db
2429 ** names.
2430 */
2431 int filename_is_ckout_db(const char *zFilename, int nFilename){
2432 const char *zEnd;
2433
2434 if(nFilename>=0 && nFilename<8/*strlen _FOSSIL_*/) return 0;
2435 else if(nFilename<0) nFilename = (int)strlen(zFilename);
2436 if(nFilename<8) return 0;
2437 zEnd = zFilename + nFilename;
2438 switch(zEnd[-1]){
2439 case '_': {
2440 return fossil_strcmp("_FOSSIL_", &zEnd[-8])
2441 ? 0 : (8==nFilename ? 1 : ('/'==zEnd[-9] ? 2 : 0));
2442 }
2443 case 't': {
2444 return (nFilename<9
2445 || '.'!=zEnd[-9]
2446 || fossil_strcmp(".fslckout", &zEnd[-9]))
2447 ? 0 : (9==nFilename ? 1 : ('/'==zEnd[-10] ? 2 : 0));
2448 }
2449 default:
2450 return 0;
2451 }
2452 }
2453
2454 /*
2455 ** COMMAND: test-is-ckout-db
2456 **
2457 ** Usage: %fossil test-is-ckout-db FILENAMES...
2458 **
2459 ** Passes each given name to filename_is_ckout_db() and outputs one
2460 ** line per file: the result value of that function followed by the
2461 ** name.
2462 */
2463 void test_is_ckout_name_cmd(void){
2464 int i;
2465
2466 if(g.argc<3){
2467 usage("FILENAME_1 [...FILENAME_N]");
2468 }
2469 for( i = 2; i < g.argc; ++i ){
2470 const int check = filename_is_ckout_db(g.argv[i], -1);
2471 fossil_print("%d %s\n", check, g.argv[i]);
2472 }
2473 }
2474
--- src/manifest.c
+++ src/manifest.c
@@ -481,14 +481,23 @@
481481
blob_appendf(pErr, "line 1 not recognized");
482482
return 0;
483483
}
484484
/* Then verify the Z-card.
485485
*/
486
+#if 1
487
+ /* Disable this ***ONLY*** (ONLY!) when testing hand-written inputs
488
+ for card-related syntax errors. */
486489
if( verify_z_card(z, n, pErr)==2 ){
487490
blob_reset(pContent);
488491
return 0;
489492
}
493
+#else
494
+#warning ACHTUNG - z-card check is disabled for testing purposes.
495
+ if(0 && verify_z_card(NULL, 0, NULL)){
496
+ /*avoid unused static func error*/
497
+ }
498
+#endif
490499
491500
/* Allocate a Manifest object to hold the parsed control artifact.
492501
*/
493502
p = fossil_malloc( sizeof(*p) );
494503
memset(p, 0, sizeof(*p));
@@ -622,10 +631,12 @@
622631
zName = next_token(&x,0);
623632
if( zName==0 ) SYNTAX("missing filename on F-card");
624633
defossilize(zName);
625634
if( !file_is_simple_pathname_nonstrict(zName) ){
626635
SYNTAX("F-card filename is not a simple path");
636
+ }else if( filename_is_ckout_db(zName,-1) ){
637
+ SYNTAX("F-card contains reserved name of a checkout db.");
627638
}
628639
zUuid = next_token(&x, &sz);
629640
if( p->zBaseline==0 || zUuid!=0 ){
630641
if( !hname_validate(zUuid,sz) ){
631642
SYNTAX("F-card hash invalid");
632643
--- src/manifest.c
+++ src/manifest.c
@@ -481,14 +481,23 @@
481 blob_appendf(pErr, "line 1 not recognized");
482 return 0;
483 }
484 /* Then verify the Z-card.
485 */
 
 
 
486 if( verify_z_card(z, n, pErr)==2 ){
487 blob_reset(pContent);
488 return 0;
489 }
 
 
 
 
 
 
490
491 /* Allocate a Manifest object to hold the parsed control artifact.
492 */
493 p = fossil_malloc( sizeof(*p) );
494 memset(p, 0, sizeof(*p));
@@ -622,10 +631,12 @@
622 zName = next_token(&x,0);
623 if( zName==0 ) SYNTAX("missing filename on F-card");
624 defossilize(zName);
625 if( !file_is_simple_pathname_nonstrict(zName) ){
626 SYNTAX("F-card filename is not a simple path");
 
 
627 }
628 zUuid = next_token(&x, &sz);
629 if( p->zBaseline==0 || zUuid!=0 ){
630 if( !hname_validate(zUuid,sz) ){
631 SYNTAX("F-card hash invalid");
632
--- src/manifest.c
+++ src/manifest.c
@@ -481,14 +481,23 @@
481 blob_appendf(pErr, "line 1 not recognized");
482 return 0;
483 }
484 /* Then verify the Z-card.
485 */
486 #if 1
487 /* Disable this ***ONLY*** (ONLY!) when testing hand-written inputs
488 for card-related syntax errors. */
489 if( verify_z_card(z, n, pErr)==2 ){
490 blob_reset(pContent);
491 return 0;
492 }
493 #else
494 #warning ACHTUNG - z-card check is disabled for testing purposes.
495 if(0 && verify_z_card(NULL, 0, NULL)){
496 /*avoid unused static func error*/
497 }
498 #endif
499
500 /* Allocate a Manifest object to hold the parsed control artifact.
501 */
502 p = fossil_malloc( sizeof(*p) );
503 memset(p, 0, sizeof(*p));
@@ -622,10 +631,12 @@
631 zName = next_token(&x,0);
632 if( zName==0 ) SYNTAX("missing filename on F-card");
633 defossilize(zName);
634 if( !file_is_simple_pathname_nonstrict(zName) ){
635 SYNTAX("F-card filename is not a simple path");
636 }else if( filename_is_ckout_db(zName,-1) ){
637 SYNTAX("F-card contains reserved name of a checkout db.");
638 }
639 zUuid = next_token(&x, &sz);
640 if( p->zBaseline==0 || zUuid!=0 ){
641 if( !hname_validate(zUuid,sz) ){
642 SYNTAX("F-card hash invalid");
643

Keyboard Shortcuts

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