Fossil SCM

Merge in reject-ckout-db branch.

stephan 2020-08-17 18:20 sec2020 merge
Commit 8c16884aa2d163122db36ecd10175a1d886aa0929e71d9822e9f9289ea4c37e3
+87
--- src/file.c
+++ src/file.c
@@ -2406,5 +2406,92 @@
24062406
*/
24072407
const char * file_extension(const char *zFileName){
24082408
const char * zExt = zFileName ? strrchr(zFileName, '.') : 0;
24092409
return zExt ? &zExt[1] : 0;
24102410
}
2411
+
2412
+/*
2413
+** Returns true if the given filename ends with any of fossil's
2414
+** checkout database filenames: _FOSSIL_ or .fslckout. Specifically,
2415
+** it returns 1 if it's an exact match and 2 if it's the tail match
2416
+** on a longer input.
2417
+**
2418
+** zFilename must, for efficiency's sake, be a
2419
+** canonicalized/normalized name, e.g. using only '/' as directory
2420
+** separators.
2421
+**
2422
+** nFilename must be the strlen of zFilename. If it is negative,
2423
+** strlen() is used to calculate it.
2424
+*/
2425
+int filename_is_ckout_db(const char *zFilename, int nFilename){
2426
+ const char *zEnd; /* one-after-the-end of zFilename */
2427
+ int gotSuffix = 0; /* length of suffix (-wal, -shm, -journal) */
2428
+
2429
+ assert(zFilename && "API misuse");
2430
+ if(nFilename<0) nFilename = (int)strlen(zFilename);
2431
+ if(nFilename<8/*strlen _FOSSIL_*/) return 0;
2432
+ zEnd = zFilename + nFilename;
2433
+ if(nFilename>=12/*strlen _FOSSIL_-(shm|wal)*/){
2434
+ /* Check for (-wal, -shm, -journal) suffixes, with an eye towards
2435
+ ** runtime speed. */
2436
+ if('-'==zEnd[-4]){
2437
+ if(fossil_stricmp("wal", &zEnd[-3])
2438
+ && fossil_stricmp("shm", &zEnd[-3])){
2439
+ return 0;
2440
+ }
2441
+ gotSuffix = 4;
2442
+ }else if(nFilename>=16/*strlen _FOSSIL_-journal*/ && '-'==zEnd[-8]){
2443
+ if(fossil_stricmp("journal",&zEnd[-7])){
2444
+ return 0;
2445
+ }
2446
+ gotSuffix = 8;
2447
+ }
2448
+ if(gotSuffix){
2449
+ assert(4==gotSuffix || 8==gotSuffix);
2450
+ zEnd -= gotSuffix;
2451
+ nFilename -= gotSuffix;
2452
+ gotSuffix = 1;
2453
+ }
2454
+ assert(nFilename>=8 && "strlen _FOSSIL_");
2455
+ assert(gotSuffix==0 || gotSuffix==1);
2456
+ }
2457
+ switch(zEnd[-1]){
2458
+ case '_': {
2459
+ return fossil_strnicmp("_FOSSIL_", &zEnd[-8], 8)
2460
+ ? 0 : (8==nFilename
2461
+ ? 1
2462
+ : ('/'==zEnd[-9] ? 2 : gotSuffix));
2463
+ }
2464
+ case 't': {
2465
+ return (nFilename<9
2466
+ || '.'!=zEnd[-9]
2467
+ || fossil_strnicmp(".fslckout", &zEnd[-9], 9))
2468
+ ? 0 : (9==nFilename
2469
+ ? 1
2470
+ : ('/'==zEnd[-10] ? 2 : gotSuffix));
2471
+ }
2472
+ default: {
2473
+ return 0;
2474
+ }
2475
+ }
2476
+}
2477
+
2478
+/*
2479
+** COMMAND: test-is-ckout-db
2480
+**
2481
+** Usage: %fossil test-is-ckout-db FILENAMES...
2482
+**
2483
+** Passes each given name to filename_is_ckout_db() and outputs one
2484
+** line per file: the result value of that function followed by the
2485
+** name.
2486
+*/
2487
+void test_is_ckout_name_cmd(void){
2488
+ int i;
2489
+
2490
+ if(g.argc<3){
2491
+ usage("FILENAME_1 [...FILENAME_N]");
2492
+ }
2493
+ for( i = 2; i < g.argc; ++i ){
2494
+ const int check = filename_is_ckout_db(g.argv[i], -1);
2495
+ fossil_print("%d %s\n", check, g.argv[i]);
2496
+ }
2497
+}
24112498
--- src/file.c
+++ src/file.c
@@ -2406,5 +2406,92 @@
2406 */
2407 const char * file_extension(const char *zFileName){
2408 const char * zExt = zFileName ? strrchr(zFileName, '.') : 0;
2409 return zExt ? &zExt[1] : 0;
2410 }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2411
--- src/file.c
+++ src/file.c
@@ -2406,5 +2406,92 @@
2406 */
2407 const char * file_extension(const char *zFileName){
2408 const char * zExt = zFileName ? strrchr(zFileName, '.') : 0;
2409 return zExt ? &zExt[1] : 0;
2410 }
2411
2412 /*
2413 ** Returns true if the given filename ends with any of fossil's
2414 ** checkout database filenames: _FOSSIL_ or .fslckout. Specifically,
2415 ** it returns 1 if it's an exact match and 2 if it's the tail match
2416 ** on a longer input.
2417 **
2418 ** zFilename must, for efficiency's sake, be a
2419 ** canonicalized/normalized name, e.g. using only '/' as directory
2420 ** separators.
2421 **
2422 ** nFilename must be the strlen of zFilename. If it is negative,
2423 ** strlen() is used to calculate it.
2424 */
2425 int filename_is_ckout_db(const char *zFilename, int nFilename){
2426 const char *zEnd; /* one-after-the-end of zFilename */
2427 int gotSuffix = 0; /* length of suffix (-wal, -shm, -journal) */
2428
2429 assert(zFilename && "API misuse");
2430 if(nFilename<0) nFilename = (int)strlen(zFilename);
2431 if(nFilename<8/*strlen _FOSSIL_*/) return 0;
2432 zEnd = zFilename + nFilename;
2433 if(nFilename>=12/*strlen _FOSSIL_-(shm|wal)*/){
2434 /* Check for (-wal, -shm, -journal) suffixes, with an eye towards
2435 ** runtime speed. */
2436 if('-'==zEnd[-4]){
2437 if(fossil_stricmp("wal", &zEnd[-3])
2438 && fossil_stricmp("shm", &zEnd[-3])){
2439 return 0;
2440 }
2441 gotSuffix = 4;
2442 }else if(nFilename>=16/*strlen _FOSSIL_-journal*/ && '-'==zEnd[-8]){
2443 if(fossil_stricmp("journal",&zEnd[-7])){
2444 return 0;
2445 }
2446 gotSuffix = 8;
2447 }
2448 if(gotSuffix){
2449 assert(4==gotSuffix || 8==gotSuffix);
2450 zEnd -= gotSuffix;
2451 nFilename -= gotSuffix;
2452 gotSuffix = 1;
2453 }
2454 assert(nFilename>=8 && "strlen _FOSSIL_");
2455 assert(gotSuffix==0 || gotSuffix==1);
2456 }
2457 switch(zEnd[-1]){
2458 case '_': {
2459 return fossil_strnicmp("_FOSSIL_", &zEnd[-8], 8)
2460 ? 0 : (8==nFilename
2461 ? 1
2462 : ('/'==zEnd[-9] ? 2 : gotSuffix));
2463 }
2464 case 't': {
2465 return (nFilename<9
2466 || '.'!=zEnd[-9]
2467 || fossil_strnicmp(".fslckout", &zEnd[-9], 9))
2468 ? 0 : (9==nFilename
2469 ? 1
2470 : ('/'==zEnd[-10] ? 2 : gotSuffix));
2471 }
2472 default: {
2473 return 0;
2474 }
2475 }
2476 }
2477
2478 /*
2479 ** COMMAND: test-is-ckout-db
2480 **
2481 ** Usage: %fossil test-is-ckout-db FILENAMES...
2482 **
2483 ** Passes each given name to filename_is_ckout_db() and outputs one
2484 ** line per file: the result value of that function followed by the
2485 ** name.
2486 */
2487 void test_is_ckout_name_cmd(void){
2488 int i;
2489
2490 if(g.argc<3){
2491 usage("FILENAME_1 [...FILENAME_N]");
2492 }
2493 for( i = 2; i < g.argc; ++i ){
2494 const int check = filename_is_ckout_db(g.argv[i], -1);
2495 fossil_print("%d %s\n", check, g.argv[i]);
2496 }
2497 }
2498
+87
--- src/file.c
+++ src/file.c
@@ -2406,5 +2406,92 @@
24062406
*/
24072407
const char * file_extension(const char *zFileName){
24082408
const char * zExt = zFileName ? strrchr(zFileName, '.') : 0;
24092409
return zExt ? &zExt[1] : 0;
24102410
}
2411
+
2412
+/*
2413
+** Returns true if the given filename ends with any of fossil's
2414
+** checkout database filenames: _FOSSIL_ or .fslckout. Specifically,
2415
+** it returns 1 if it's an exact match and 2 if it's the tail match
2416
+** on a longer input.
2417
+**
2418
+** zFilename must, for efficiency's sake, be a
2419
+** canonicalized/normalized name, e.g. using only '/' as directory
2420
+** separators.
2421
+**
2422
+** nFilename must be the strlen of zFilename. If it is negative,
2423
+** strlen() is used to calculate it.
2424
+*/
2425
+int filename_is_ckout_db(const char *zFilename, int nFilename){
2426
+ const char *zEnd; /* one-after-the-end of zFilename */
2427
+ int gotSuffix = 0; /* length of suffix (-wal, -shm, -journal) */
2428
+
2429
+ assert(zFilename && "API misuse");
2430
+ if(nFilename<0) nFilename = (int)strlen(zFilename);
2431
+ if(nFilename<8/*strlen _FOSSIL_*/) return 0;
2432
+ zEnd = zFilename + nFilename;
2433
+ if(nFilename>=12/*strlen _FOSSIL_-(shm|wal)*/){
2434
+ /* Check for (-wal, -shm, -journal) suffixes, with an eye towards
2435
+ ** runtime speed. */
2436
+ if('-'==zEnd[-4]){
2437
+ if(fossil_stricmp("wal", &zEnd[-3])
2438
+ && fossil_stricmp("shm", &zEnd[-3])){
2439
+ return 0;
2440
+ }
2441
+ gotSuffix = 4;
2442
+ }else if(nFilename>=16/*strlen _FOSSIL_-journal*/ && '-'==zEnd[-8]){
2443
+ if(fossil_stricmp("journal",&zEnd[-7])){
2444
+ return 0;
2445
+ }
2446
+ gotSuffix = 8;
2447
+ }
2448
+ if(gotSuffix){
2449
+ assert(4==gotSuffix || 8==gotSuffix);
2450
+ zEnd -= gotSuffix;
2451
+ nFilename -= gotSuffix;
2452
+ gotSuffix = 1;
2453
+ }
2454
+ assert(nFilename>=8 && "strlen _FOSSIL_");
2455
+ assert(gotSuffix==0 || gotSuffix==1);
2456
+ }
2457
+ switch(zEnd[-1]){
2458
+ case '_': {
2459
+ return fossil_strnicmp("_FOSSIL_", &zEnd[-8], 8)
2460
+ ? 0 : (8==nFilename
2461
+ ? 1
2462
+ : ('/'==zEnd[-9] ? 2 : gotSuffix));
2463
+ }
2464
+ case 't': {
2465
+ return (nFilename<9
2466
+ || '.'!=zEnd[-9]
2467
+ || fossil_strnicmp(".fslckout", &zEnd[-9], 9))
2468
+ ? 0 : (9==nFilename
2469
+ ? 1
2470
+ : ('/'==zEnd[-10] ? 2 : gotSuffix));
2471
+ }
2472
+ default: {
2473
+ return 0;
2474
+ }
2475
+ }
2476
+}
2477
+
2478
+/*
2479
+** COMMAND: test-is-ckout-db
2480
+**
2481
+** Usage: %fossil test-is-ckout-db FILENAMES...
2482
+**
2483
+** Passes each given name to filename_is_ckout_db() and outputs one
2484
+** line per file: the result value of that function followed by the
2485
+** name.
2486
+*/
2487
+void test_is_ckout_name_cmd(void){
2488
+ int i;
2489
+
2490
+ if(g.argc<3){
2491
+ usage("FILENAME_1 [...FILENAME_N]");
2492
+ }
2493
+ for( i = 2; i < g.argc; ++i ){
2494
+ const int check = filename_is_ckout_db(g.argv[i], -1);
2495
+ fossil_print("%d %s\n", check, g.argv[i]);
2496
+ }
2497
+}
24112498
--- src/file.c
+++ src/file.c
@@ -2406,5 +2406,92 @@
2406 */
2407 const char * file_extension(const char *zFileName){
2408 const char * zExt = zFileName ? strrchr(zFileName, '.') : 0;
2409 return zExt ? &zExt[1] : 0;
2410 }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2411
--- src/file.c
+++ src/file.c
@@ -2406,5 +2406,92 @@
2406 */
2407 const char * file_extension(const char *zFileName){
2408 const char * zExt = zFileName ? strrchr(zFileName, '.') : 0;
2409 return zExt ? &zExt[1] : 0;
2410 }
2411
2412 /*
2413 ** Returns true if the given filename ends with any of fossil's
2414 ** checkout database filenames: _FOSSIL_ or .fslckout. Specifically,
2415 ** it returns 1 if it's an exact match and 2 if it's the tail match
2416 ** on a longer input.
2417 **
2418 ** zFilename must, for efficiency's sake, be a
2419 ** canonicalized/normalized name, e.g. using only '/' as directory
2420 ** separators.
2421 **
2422 ** nFilename must be the strlen of zFilename. If it is negative,
2423 ** strlen() is used to calculate it.
2424 */
2425 int filename_is_ckout_db(const char *zFilename, int nFilename){
2426 const char *zEnd; /* one-after-the-end of zFilename */
2427 int gotSuffix = 0; /* length of suffix (-wal, -shm, -journal) */
2428
2429 assert(zFilename && "API misuse");
2430 if(nFilename<0) nFilename = (int)strlen(zFilename);
2431 if(nFilename<8/*strlen _FOSSIL_*/) return 0;
2432 zEnd = zFilename + nFilename;
2433 if(nFilename>=12/*strlen _FOSSIL_-(shm|wal)*/){
2434 /* Check for (-wal, -shm, -journal) suffixes, with an eye towards
2435 ** runtime speed. */
2436 if('-'==zEnd[-4]){
2437 if(fossil_stricmp("wal", &zEnd[-3])
2438 && fossil_stricmp("shm", &zEnd[-3])){
2439 return 0;
2440 }
2441 gotSuffix = 4;
2442 }else if(nFilename>=16/*strlen _FOSSIL_-journal*/ && '-'==zEnd[-8]){
2443 if(fossil_stricmp("journal",&zEnd[-7])){
2444 return 0;
2445 }
2446 gotSuffix = 8;
2447 }
2448 if(gotSuffix){
2449 assert(4==gotSuffix || 8==gotSuffix);
2450 zEnd -= gotSuffix;
2451 nFilename -= gotSuffix;
2452 gotSuffix = 1;
2453 }
2454 assert(nFilename>=8 && "strlen _FOSSIL_");
2455 assert(gotSuffix==0 || gotSuffix==1);
2456 }
2457 switch(zEnd[-1]){
2458 case '_': {
2459 return fossil_strnicmp("_FOSSIL_", &zEnd[-8], 8)
2460 ? 0 : (8==nFilename
2461 ? 1
2462 : ('/'==zEnd[-9] ? 2 : gotSuffix));
2463 }
2464 case 't': {
2465 return (nFilename<9
2466 || '.'!=zEnd[-9]
2467 || fossil_strnicmp(".fslckout", &zEnd[-9], 9))
2468 ? 0 : (9==nFilename
2469 ? 1
2470 : ('/'==zEnd[-10] ? 2 : gotSuffix));
2471 }
2472 default: {
2473 return 0;
2474 }
2475 }
2476 }
2477
2478 /*
2479 ** COMMAND: test-is-ckout-db
2480 **
2481 ** Usage: %fossil test-is-ckout-db FILENAMES...
2482 **
2483 ** Passes each given name to filename_is_ckout_db() and outputs one
2484 ** line per file: the result value of that function followed by the
2485 ** name.
2486 */
2487 void test_is_ckout_name_cmd(void){
2488 int i;
2489
2490 if(g.argc<3){
2491 usage("FILENAME_1 [...FILENAME_N]");
2492 }
2493 for( i = 2; i < g.argc; ++i ){
2494 const int check = filename_is_ckout_db(g.argv[i], -1);
2495 fossil_print("%d %s\n", check, g.argv[i]);
2496 }
2497 }
2498
--- 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));
@@ -601,10 +610,11 @@
601610
case 'E': {
602611
if( p->rEventDate>0.0 ) SYNTAX("more than one E-card");
603612
p->rEventDate = db_double(0.0,"SELECT julianday(%Q)", next_token(&x,0));
604613
if( p->rEventDate<=0.0 ) SYNTAX("malformed date on E-card");
605614
p->zEventId = next_token(&x, &sz);
615
+ if( p->zEventId==0 ) SYNTAX("missing hash on E-card");
606616
if( !hname_validate(p->zEventId, sz) ){
607617
SYNTAX("malformed hash on E-card");
608618
}
609619
p->type = CFTYPE_EVENT;
610620
break;
@@ -622,13 +632,16 @@
622632
zName = next_token(&x,0);
623633
if( zName==0 ) SYNTAX("missing filename on F-card");
624634
defossilize(zName);
625635
if( !file_is_simple_pathname_nonstrict(zName) ){
626636
SYNTAX("F-card filename is not a simple path");
637
+ }else if( filename_is_ckout_db(zName,-1) ){
638
+ SYNTAX("F-card contains reserved name of a checkout db.");
627639
}
628640
zUuid = next_token(&x, &sz);
629641
if( p->zBaseline==0 || zUuid!=0 ){
642
+ if( zUuid==0 ) SYNTAX("missing hash on F-card");
630643
if( !hname_validate(zUuid,sz) ){
631644
SYNTAX("F-card hash invalid");
632645
}
633646
}
634647
zPerm = next_token(&x,0);
635648
--- 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));
@@ -601,10 +610,11 @@
601 case 'E': {
602 if( p->rEventDate>0.0 ) SYNTAX("more than one E-card");
603 p->rEventDate = db_double(0.0,"SELECT julianday(%Q)", next_token(&x,0));
604 if( p->rEventDate<=0.0 ) SYNTAX("malformed date on E-card");
605 p->zEventId = next_token(&x, &sz);
 
606 if( !hname_validate(p->zEventId, sz) ){
607 SYNTAX("malformed hash on E-card");
608 }
609 p->type = CFTYPE_EVENT;
610 break;
@@ -622,13 +632,16 @@
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 }
633 }
634 zPerm = next_token(&x,0);
635
--- 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));
@@ -601,10 +610,11 @@
610 case 'E': {
611 if( p->rEventDate>0.0 ) SYNTAX("more than one E-card");
612 p->rEventDate = db_double(0.0,"SELECT julianday(%Q)", next_token(&x,0));
613 if( p->rEventDate<=0.0 ) SYNTAX("malformed date on E-card");
614 p->zEventId = next_token(&x, &sz);
615 if( p->zEventId==0 ) SYNTAX("missing hash on E-card");
616 if( !hname_validate(p->zEventId, sz) ){
617 SYNTAX("malformed hash on E-card");
618 }
619 p->type = CFTYPE_EVENT;
620 break;
@@ -622,13 +632,16 @@
632 zName = next_token(&x,0);
633 if( zName==0 ) SYNTAX("missing filename on F-card");
634 defossilize(zName);
635 if( !file_is_simple_pathname_nonstrict(zName) ){
636 SYNTAX("F-card filename is not a simple path");
637 }else if( filename_is_ckout_db(zName,-1) ){
638 SYNTAX("F-card contains reserved name of a checkout db.");
639 }
640 zUuid = next_token(&x, &sz);
641 if( p->zBaseline==0 || zUuid!=0 ){
642 if( zUuid==0 ) SYNTAX("missing hash on F-card");
643 if( !hname_validate(zUuid,sz) ){
644 SYNTAX("F-card hash invalid");
645 }
646 }
647 zPerm = next_token(&x,0);
648

Keyboard Shortcuts

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