Fossil SCM
Avoid appending to g.zPath inside doc_page() loop. Instead, wait until the loop is done to modify g.zPath. When doing a directory lookup, the check-in and directory name were being repeatedly appended to g.zPath each step through the list of possible filename suffixes. This corrupted <base href> should index.html not exist, which in turn broke relative URLs.
Commit
956d4901a95cc54c5d62c963d9e25882bc7f0a3f9f8dd54abf9149277259e426
Parent
e76f3bbe45dcefd…
1 file changed
+4
-2
+4
-2
| --- src/doc.c | ||
| +++ src/doc.c | ||
| @@ -576,10 +576,11 @@ | ||
| 576 | 576 | void doc_page(void){ |
| 577 | 577 | const char *zName; /* Argument to the /doc page */ |
| 578 | 578 | const char *zOrigName = "?"; /* Original document name */ |
| 579 | 579 | const char *zMime; /* Document MIME type */ |
| 580 | 580 | char *zCheckin = "tip"; /* The check-in holding the document */ |
| 581 | + char *zPathSuffix = ""; /* Text to append to g.zPath */ | |
| 581 | 582 | int vid = 0; /* Artifact of check-in */ |
| 582 | 583 | int rid = 0; /* Artifact of file */ |
| 583 | 584 | int i; /* Loop counter */ |
| 584 | 585 | Blob filebody; /* Content of the documentation file */ |
| 585 | 586 | Blob title; /* Document title */ |
| @@ -619,13 +620,13 @@ | ||
| 619 | 620 | }else if( !isUV ){ |
| 620 | 621 | zName += i; |
| 621 | 622 | } |
| 622 | 623 | while( zName[0]=='/' ){ zName++; } |
| 623 | 624 | if( isUV ){ |
| 624 | - g.zPath = mprintf("%s/%s", g.zPath, zName); | |
| 625 | + zPathSuffix = fossil_strdup(zName); | |
| 625 | 626 | }else{ |
| 626 | - g.zPath = mprintf("%s/%s/%s", g.zPath, zCheckin, zName); | |
| 627 | + zPathSuffix = mprintf("%s/%s", zCheckin, zName); | |
| 627 | 628 | } |
| 628 | 629 | if( nMiss==0 ) zOrigName = zName; |
| 629 | 630 | if( !file_is_simple_pathname(zName, 1) ){ |
| 630 | 631 | if( sqlite3_strglob("*/", zName)==0 ){ |
| 631 | 632 | assert( nMiss>=0 && nMiss<count(azSuffix) ); |
| @@ -657,10 +658,11 @@ | ||
| 657 | 658 | }else{ |
| 658 | 659 | vid = name_to_typed_rid(zCheckin, "ci"); |
| 659 | 660 | rid = doc_load_content(vid, zName, &filebody); |
| 660 | 661 | } |
| 661 | 662 | } |
| 663 | + g.zPath = mprintf("%s/%s", g.zPath, zPathSuffix); | |
| 662 | 664 | if( rid==0 ) goto doc_not_found; |
| 663 | 665 | blob_to_utf8_no_bom(&filebody, 0); |
| 664 | 666 | |
| 665 | 667 | /* The file is now contained in the filebody blob. Deliver the |
| 666 | 668 | ** file to the user |
| 667 | 669 |
| --- src/doc.c | |
| +++ src/doc.c | |
| @@ -576,10 +576,11 @@ | |
| 576 | void doc_page(void){ |
| 577 | const char *zName; /* Argument to the /doc page */ |
| 578 | const char *zOrigName = "?"; /* Original document name */ |
| 579 | const char *zMime; /* Document MIME type */ |
| 580 | char *zCheckin = "tip"; /* The check-in holding the document */ |
| 581 | int vid = 0; /* Artifact of check-in */ |
| 582 | int rid = 0; /* Artifact of file */ |
| 583 | int i; /* Loop counter */ |
| 584 | Blob filebody; /* Content of the documentation file */ |
| 585 | Blob title; /* Document title */ |
| @@ -619,13 +620,13 @@ | |
| 619 | }else if( !isUV ){ |
| 620 | zName += i; |
| 621 | } |
| 622 | while( zName[0]=='/' ){ zName++; } |
| 623 | if( isUV ){ |
| 624 | g.zPath = mprintf("%s/%s", g.zPath, zName); |
| 625 | }else{ |
| 626 | g.zPath = mprintf("%s/%s/%s", g.zPath, zCheckin, zName); |
| 627 | } |
| 628 | if( nMiss==0 ) zOrigName = zName; |
| 629 | if( !file_is_simple_pathname(zName, 1) ){ |
| 630 | if( sqlite3_strglob("*/", zName)==0 ){ |
| 631 | assert( nMiss>=0 && nMiss<count(azSuffix) ); |
| @@ -657,10 +658,11 @@ | |
| 657 | }else{ |
| 658 | vid = name_to_typed_rid(zCheckin, "ci"); |
| 659 | rid = doc_load_content(vid, zName, &filebody); |
| 660 | } |
| 661 | } |
| 662 | if( rid==0 ) goto doc_not_found; |
| 663 | blob_to_utf8_no_bom(&filebody, 0); |
| 664 | |
| 665 | /* The file is now contained in the filebody blob. Deliver the |
| 666 | ** file to the user |
| 667 |
| --- src/doc.c | |
| +++ src/doc.c | |
| @@ -576,10 +576,11 @@ | |
| 576 | void doc_page(void){ |
| 577 | const char *zName; /* Argument to the /doc page */ |
| 578 | const char *zOrigName = "?"; /* Original document name */ |
| 579 | const char *zMime; /* Document MIME type */ |
| 580 | char *zCheckin = "tip"; /* The check-in holding the document */ |
| 581 | char *zPathSuffix = ""; /* Text to append to g.zPath */ |
| 582 | int vid = 0; /* Artifact of check-in */ |
| 583 | int rid = 0; /* Artifact of file */ |
| 584 | int i; /* Loop counter */ |
| 585 | Blob filebody; /* Content of the documentation file */ |
| 586 | Blob title; /* Document title */ |
| @@ -619,13 +620,13 @@ | |
| 620 | }else if( !isUV ){ |
| 621 | zName += i; |
| 622 | } |
| 623 | while( zName[0]=='/' ){ zName++; } |
| 624 | if( isUV ){ |
| 625 | zPathSuffix = fossil_strdup(zName); |
| 626 | }else{ |
| 627 | zPathSuffix = mprintf("%s/%s", zCheckin, zName); |
| 628 | } |
| 629 | if( nMiss==0 ) zOrigName = zName; |
| 630 | if( !file_is_simple_pathname(zName, 1) ){ |
| 631 | if( sqlite3_strglob("*/", zName)==0 ){ |
| 632 | assert( nMiss>=0 && nMiss<count(azSuffix) ); |
| @@ -657,10 +658,11 @@ | |
| 658 | }else{ |
| 659 | vid = name_to_typed_rid(zCheckin, "ci"); |
| 660 | rid = doc_load_content(vid, zName, &filebody); |
| 661 | } |
| 662 | } |
| 663 | g.zPath = mprintf("%s/%s", g.zPath, zPathSuffix); |
| 664 | if( rid==0 ) goto doc_not_found; |
| 665 | blob_to_utf8_no_bom(&filebody, 0); |
| 666 | |
| 667 | /* The file is now contained in the filebody blob. Deliver the |
| 668 | ** file to the user |
| 669 |