Fossil SCM
Merged in trunk improvements
Commit
42d28c02868fd7c26cb276c4fbe0d9a7af2e07eade93b2de3a012ccf663a401f
Parent
3cdf764c2c66358…
16 files changed
+7
+15
-4
+80
+3
-1
+107
-8
+80
-63
+11
+1
-1
+8
+8
+7
-4
+7
-4
+1
+1
+5
+5
~
src/cgi.c
~
src/main.c
~
src/security_audit.c
~
src/stat.c
~
src/wikiformat.c
~
www/customskin.md
+
www/defcsp.md
~
www/defcsp.md
~
www/embeddeddoc.wiki
~
www/embeddeddoc.wiki
~
www/fossil-v-git.wiki
~
www/fossil-v-git.wiki
~
www/mkindex.tcl
~
www/mkindex.tcl
~
www/permutedindex.html
~
www/permutedindex.html
+7
| --- src/cgi.c | ||
| +++ src/cgi.c | ||
| @@ -144,10 +144,17 @@ | ||
| 144 | 144 | ** Return a pointer to the CGI output blob. |
| 145 | 145 | */ |
| 146 | 146 | Blob *cgi_output_blob(void){ |
| 147 | 147 | return pContent; |
| 148 | 148 | } |
| 149 | + | |
| 150 | +/* | |
| 151 | +** Return complete text of the output header | |
| 152 | +*/ | |
| 153 | +const char *cgi_header(void){ | |
| 154 | + return blob_str(&cgiContent[0]); | |
| 155 | +} | |
| 149 | 156 | |
| 150 | 157 | /* |
| 151 | 158 | ** Combine the header and body of the CGI into a single string. |
| 152 | 159 | */ |
| 153 | 160 | static void cgi_combine_header_and_body(void){ |
| 154 | 161 |
| --- src/cgi.c | |
| +++ src/cgi.c | |
| @@ -144,10 +144,17 @@ | |
| 144 | ** Return a pointer to the CGI output blob. |
| 145 | */ |
| 146 | Blob *cgi_output_blob(void){ |
| 147 | return pContent; |
| 148 | } |
| 149 | |
| 150 | /* |
| 151 | ** Combine the header and body of the CGI into a single string. |
| 152 | */ |
| 153 | static void cgi_combine_header_and_body(void){ |
| 154 |
| --- src/cgi.c | |
| +++ src/cgi.c | |
| @@ -144,10 +144,17 @@ | |
| 144 | ** Return a pointer to the CGI output blob. |
| 145 | */ |
| 146 | Blob *cgi_output_blob(void){ |
| 147 | return pContent; |
| 148 | } |
| 149 | |
| 150 | /* |
| 151 | ** Return complete text of the output header |
| 152 | */ |
| 153 | const char *cgi_header(void){ |
| 154 | return blob_str(&cgiContent[0]); |
| 155 | } |
| 156 | |
| 157 | /* |
| 158 | ** Combine the header and body of the CGI into a single string. |
| 159 | */ |
| 160 | static void cgi_combine_header_and_body(void){ |
| 161 |
+15
-4
| --- src/main.c | ||
| +++ src/main.c | ||
| @@ -58,10 +58,19 @@ | ||
| 58 | 58 | #endif |
| 59 | 59 | #ifdef HAVE_BACKTRACE |
| 60 | 60 | # include <execinfo.h> |
| 61 | 61 | #endif |
| 62 | 62 | |
| 63 | +/* | |
| 64 | +** Default length of a timeout for serving an HTTP request. Changable | |
| 65 | +** using the "--timeout N" command-line option or via "timeout: N" in the | |
| 66 | +** CGI script. | |
| 67 | +*/ | |
| 68 | +#ifndef FOSSIL_DEFAULT_TIMEOUT | |
| 69 | +# define FOSSIL_DEFAULT_TIMEOUT 600 /* 10 minutes */ | |
| 70 | +#endif | |
| 71 | + | |
| 63 | 72 | /* |
| 64 | 73 | ** Maximum number of auxiliary parameters on reports |
| 65 | 74 | */ |
| 66 | 75 | #define MX_AUX 5 |
| 67 | 76 | |
| @@ -1949,11 +1958,11 @@ | ||
| 1949 | 1958 | ** into FILE. |
| 1950 | 1959 | ** |
| 1951 | 1960 | ** errorlog: FILE Warnings, errors, and panics written to FILE. |
| 1952 | 1961 | ** |
| 1953 | 1962 | ** timeout: SECONDS Do not run for longer than SECONDS. The default |
| 1954 | -** timeout is 300 seconds. | |
| 1963 | +** timeout is FOSSIL_DEFAULT_TIMEOUT (600) seconds. | |
| 1955 | 1964 | ** |
| 1956 | 1965 | ** extroot: DIR Directory that is the root of the sub-CGI tree |
| 1957 | 1966 | ** on the /ext page. |
| 1958 | 1967 | ** |
| 1959 | 1968 | ** redirect: REPO URL Extract the "name" query parameter and search |
| @@ -1984,11 +1993,11 @@ | ||
| 1984 | 1993 | g.httpOut = stdout; |
| 1985 | 1994 | g.httpIn = stdin; |
| 1986 | 1995 | fossil_binary_mode(g.httpOut); |
| 1987 | 1996 | fossil_binary_mode(g.httpIn); |
| 1988 | 1997 | g.cgiOutput = 1; |
| 1989 | - fossil_set_timeout(300); | |
| 1998 | + fossil_set_timeout(FOSSIL_DEFAULT_TIMEOUT); | |
| 1990 | 1999 | blob_read_from_file(&config, zFile, ExtFILE); |
| 1991 | 2000 | while( blob_line(&config, &line) ){ |
| 1992 | 2001 | if( !blob_token(&line, &key) ) continue; |
| 1993 | 2002 | if( blob_buffer(&key)[0]=='#' ) continue; |
| 1994 | 2003 | if( blob_eq(&key, "repository:") && blob_tail(&line, &value) ){ |
| @@ -2114,11 +2123,11 @@ | ||
| 2114 | 2123 | } |
| 2115 | 2124 | if( blob_eq(&key, "timeout:") && blob_token(&line, &value) ){ |
| 2116 | 2125 | /* timeout: SECONDS |
| 2117 | 2126 | ** |
| 2118 | 2127 | ** Set an alarm() that kills the process after SECONDS. The |
| 2119 | - ** default value is 300 seconds. | |
| 2128 | + ** default value is FOSSIL_DEFAULT_TIMEOUT (600) seconds. | |
| 2120 | 2129 | */ |
| 2121 | 2130 | fossil_set_timeout(atoi(blob_str(&value))); |
| 2122 | 2131 | continue; |
| 2123 | 2132 | } |
| 2124 | 2133 | if( blob_eq(&key, "HOME:") && blob_token(&line, &value) ){ |
| @@ -2570,11 +2579,11 @@ | ||
| 2570 | 2579 | int isUiCmd; /* True if command is "ui", not "server' */ |
| 2571 | 2580 | const char *zNotFound; /* The --notfound option or NULL */ |
| 2572 | 2581 | int flags = 0; /* Server flags */ |
| 2573 | 2582 | #if !defined(_WIN32) |
| 2574 | 2583 | int noJail; /* Do not enter the chroot jail */ |
| 2575 | - const char *zTimeout = "300"; /* Max runtime of any single HTTP request */ | |
| 2584 | + const char *zTimeout = 0; /* Max runtime of any single HTTP request */ | |
| 2576 | 2585 | #endif |
| 2577 | 2586 | int allowRepoList; /* List repositories on URL "/" */ |
| 2578 | 2587 | const char *zAltBase; /* Argument to the --baseurl option */ |
| 2579 | 2588 | const char *zFileGlob; /* Static content must match this */ |
| 2580 | 2589 | char *zIpAddr = 0; /* Bind to this IP address */ |
| @@ -2722,10 +2731,12 @@ | ||
| 2722 | 2731 | ** child process, the HTTP or SCGI request is pending on file |
| 2723 | 2732 | ** descriptor 0 and the reply should be written to file descriptor 1. |
| 2724 | 2733 | */ |
| 2725 | 2734 | if( zTimeout ){ |
| 2726 | 2735 | fossil_set_timeout(atoi(zTimeout)); |
| 2736 | + }else{ | |
| 2737 | + fossil_set_timeout(FOSSIL_DEFAULT_TIMEOUT); | |
| 2727 | 2738 | } |
| 2728 | 2739 | g.httpIn = stdin; |
| 2729 | 2740 | g.httpOut = stdout; |
| 2730 | 2741 | |
| 2731 | 2742 | #if !defined(_WIN32) |
| 2732 | 2743 |
| --- src/main.c | |
| +++ src/main.c | |
| @@ -58,10 +58,19 @@ | |
| 58 | #endif |
| 59 | #ifdef HAVE_BACKTRACE |
| 60 | # include <execinfo.h> |
| 61 | #endif |
| 62 | |
| 63 | /* |
| 64 | ** Maximum number of auxiliary parameters on reports |
| 65 | */ |
| 66 | #define MX_AUX 5 |
| 67 | |
| @@ -1949,11 +1958,11 @@ | |
| 1949 | ** into FILE. |
| 1950 | ** |
| 1951 | ** errorlog: FILE Warnings, errors, and panics written to FILE. |
| 1952 | ** |
| 1953 | ** timeout: SECONDS Do not run for longer than SECONDS. The default |
| 1954 | ** timeout is 300 seconds. |
| 1955 | ** |
| 1956 | ** extroot: DIR Directory that is the root of the sub-CGI tree |
| 1957 | ** on the /ext page. |
| 1958 | ** |
| 1959 | ** redirect: REPO URL Extract the "name" query parameter and search |
| @@ -1984,11 +1993,11 @@ | |
| 1984 | g.httpOut = stdout; |
| 1985 | g.httpIn = stdin; |
| 1986 | fossil_binary_mode(g.httpOut); |
| 1987 | fossil_binary_mode(g.httpIn); |
| 1988 | g.cgiOutput = 1; |
| 1989 | fossil_set_timeout(300); |
| 1990 | blob_read_from_file(&config, zFile, ExtFILE); |
| 1991 | while( blob_line(&config, &line) ){ |
| 1992 | if( !blob_token(&line, &key) ) continue; |
| 1993 | if( blob_buffer(&key)[0]=='#' ) continue; |
| 1994 | if( blob_eq(&key, "repository:") && blob_tail(&line, &value) ){ |
| @@ -2114,11 +2123,11 @@ | |
| 2114 | } |
| 2115 | if( blob_eq(&key, "timeout:") && blob_token(&line, &value) ){ |
| 2116 | /* timeout: SECONDS |
| 2117 | ** |
| 2118 | ** Set an alarm() that kills the process after SECONDS. The |
| 2119 | ** default value is 300 seconds. |
| 2120 | */ |
| 2121 | fossil_set_timeout(atoi(blob_str(&value))); |
| 2122 | continue; |
| 2123 | } |
| 2124 | if( blob_eq(&key, "HOME:") && blob_token(&line, &value) ){ |
| @@ -2570,11 +2579,11 @@ | |
| 2570 | int isUiCmd; /* True if command is "ui", not "server' */ |
| 2571 | const char *zNotFound; /* The --notfound option or NULL */ |
| 2572 | int flags = 0; /* Server flags */ |
| 2573 | #if !defined(_WIN32) |
| 2574 | int noJail; /* Do not enter the chroot jail */ |
| 2575 | const char *zTimeout = "300"; /* Max runtime of any single HTTP request */ |
| 2576 | #endif |
| 2577 | int allowRepoList; /* List repositories on URL "/" */ |
| 2578 | const char *zAltBase; /* Argument to the --baseurl option */ |
| 2579 | const char *zFileGlob; /* Static content must match this */ |
| 2580 | char *zIpAddr = 0; /* Bind to this IP address */ |
| @@ -2722,10 +2731,12 @@ | |
| 2722 | ** child process, the HTTP or SCGI request is pending on file |
| 2723 | ** descriptor 0 and the reply should be written to file descriptor 1. |
| 2724 | */ |
| 2725 | if( zTimeout ){ |
| 2726 | fossil_set_timeout(atoi(zTimeout)); |
| 2727 | } |
| 2728 | g.httpIn = stdin; |
| 2729 | g.httpOut = stdout; |
| 2730 | |
| 2731 | #if !defined(_WIN32) |
| 2732 |
| --- src/main.c | |
| +++ src/main.c | |
| @@ -58,10 +58,19 @@ | |
| 58 | #endif |
| 59 | #ifdef HAVE_BACKTRACE |
| 60 | # include <execinfo.h> |
| 61 | #endif |
| 62 | |
| 63 | /* |
| 64 | ** Default length of a timeout for serving an HTTP request. Changable |
| 65 | ** using the "--timeout N" command-line option or via "timeout: N" in the |
| 66 | ** CGI script. |
| 67 | */ |
| 68 | #ifndef FOSSIL_DEFAULT_TIMEOUT |
| 69 | # define FOSSIL_DEFAULT_TIMEOUT 600 /* 10 minutes */ |
| 70 | #endif |
| 71 | |
| 72 | /* |
| 73 | ** Maximum number of auxiliary parameters on reports |
| 74 | */ |
| 75 | #define MX_AUX 5 |
| 76 | |
| @@ -1949,11 +1958,11 @@ | |
| 1958 | ** into FILE. |
| 1959 | ** |
| 1960 | ** errorlog: FILE Warnings, errors, and panics written to FILE. |
| 1961 | ** |
| 1962 | ** timeout: SECONDS Do not run for longer than SECONDS. The default |
| 1963 | ** timeout is FOSSIL_DEFAULT_TIMEOUT (600) seconds. |
| 1964 | ** |
| 1965 | ** extroot: DIR Directory that is the root of the sub-CGI tree |
| 1966 | ** on the /ext page. |
| 1967 | ** |
| 1968 | ** redirect: REPO URL Extract the "name" query parameter and search |
| @@ -1984,11 +1993,11 @@ | |
| 1993 | g.httpOut = stdout; |
| 1994 | g.httpIn = stdin; |
| 1995 | fossil_binary_mode(g.httpOut); |
| 1996 | fossil_binary_mode(g.httpIn); |
| 1997 | g.cgiOutput = 1; |
| 1998 | fossil_set_timeout(FOSSIL_DEFAULT_TIMEOUT); |
| 1999 | blob_read_from_file(&config, zFile, ExtFILE); |
| 2000 | while( blob_line(&config, &line) ){ |
| 2001 | if( !blob_token(&line, &key) ) continue; |
| 2002 | if( blob_buffer(&key)[0]=='#' ) continue; |
| 2003 | if( blob_eq(&key, "repository:") && blob_tail(&line, &value) ){ |
| @@ -2114,11 +2123,11 @@ | |
| 2123 | } |
| 2124 | if( blob_eq(&key, "timeout:") && blob_token(&line, &value) ){ |
| 2125 | /* timeout: SECONDS |
| 2126 | ** |
| 2127 | ** Set an alarm() that kills the process after SECONDS. The |
| 2128 | ** default value is FOSSIL_DEFAULT_TIMEOUT (600) seconds. |
| 2129 | */ |
| 2130 | fossil_set_timeout(atoi(blob_str(&value))); |
| 2131 | continue; |
| 2132 | } |
| 2133 | if( blob_eq(&key, "HOME:") && blob_token(&line, &value) ){ |
| @@ -2570,11 +2579,11 @@ | |
| 2579 | int isUiCmd; /* True if command is "ui", not "server' */ |
| 2580 | const char *zNotFound; /* The --notfound option or NULL */ |
| 2581 | int flags = 0; /* Server flags */ |
| 2582 | #if !defined(_WIN32) |
| 2583 | int noJail; /* Do not enter the chroot jail */ |
| 2584 | const char *zTimeout = 0; /* Max runtime of any single HTTP request */ |
| 2585 | #endif |
| 2586 | int allowRepoList; /* List repositories on URL "/" */ |
| 2587 | const char *zAltBase; /* Argument to the --baseurl option */ |
| 2588 | const char *zFileGlob; /* Static content must match this */ |
| 2589 | char *zIpAddr = 0; /* Bind to this IP address */ |
| @@ -2722,10 +2731,12 @@ | |
| 2731 | ** child process, the HTTP or SCGI request is pending on file |
| 2732 | ** descriptor 0 and the reply should be written to file descriptor 1. |
| 2733 | */ |
| 2734 | if( zTimeout ){ |
| 2735 | fossil_set_timeout(atoi(zTimeout)); |
| 2736 | }else{ |
| 2737 | fossil_set_timeout(FOSSIL_DEFAULT_TIMEOUT); |
| 2738 | } |
| 2739 | g.httpIn = stdin; |
| 2740 | g.httpOut = stdout; |
| 2741 | |
| 2742 | #if !defined(_WIN32) |
| 2743 |
+80
| --- src/security_audit.c | ||
| +++ src/security_audit.c | ||
| @@ -32,10 +32,69 @@ | ||
| 32 | 32 | zTest++; |
| 33 | 33 | } |
| 34 | 34 | return 0; |
| 35 | 35 | } |
| 36 | 36 | |
| 37 | +/* | |
| 38 | +** Extract the content-security-policy from the reply header. Parse it | |
| 39 | +** up into separate fields, and return a pointer to a null-terminated | |
| 40 | +** array of pointers to strings, one entry for each field. Or return | |
| 41 | +** a NULL pointer if no CSP could be located in the header. | |
| 42 | +** | |
| 43 | +** Memory to hold the returned array and of the strings is obtained from | |
| 44 | +** a single memory allocation, which the caller should free to avoid a | |
| 45 | +** memory leak. | |
| 46 | +*/ | |
| 47 | +static char **parse_content_security_policy(void){ | |
| 48 | + char **azCSP = 0; | |
| 49 | + int nCSP = 0; | |
| 50 | + const char *zHeader; | |
| 51 | + const char *zAll; | |
| 52 | + char *zCopy; | |
| 53 | + int nAll = 0; | |
| 54 | + int ii, jj, n, nx = 0; | |
| 55 | + int nSemi; | |
| 56 | + | |
| 57 | + zHeader = cgi_header(); | |
| 58 | + if( zHeader==0 ) return 0; | |
| 59 | + for(ii=0; zHeader[ii]; ii+=n){ | |
| 60 | + n = html_token_length(zHeader+ii); | |
| 61 | + if( zHeader[ii]=='<' | |
| 62 | + && fossil_strnicmp(html_attribute(zHeader+ii,"http-equiv",&nx), | |
| 63 | + "Content-Security-Policy",23)==0 | |
| 64 | + && nx==23 | |
| 65 | + && (zAll = html_attribute(zHeader+ii,"content",&nAll))!=0 | |
| 66 | + ){ | |
| 67 | + for(jj=nSemi=0; jj<nAll; jj++){ if( zAll[jj]==';' ) nSemi++; } | |
| 68 | + azCSP = fossil_malloc( nAll+1 + (nSemi+2)*sizeof(char*) ); | |
| 69 | + zCopy = (char*)&azCSP[nSemi+2]; | |
| 70 | + memcpy(zCopy,zAll,nAll); | |
| 71 | + zCopy[nAll] = 0; | |
| 72 | + while( fossil_isspace(zCopy[0]) || zCopy[0]==';' ){ zCopy++; } | |
| 73 | + azCSP[0] = zCopy; | |
| 74 | + nCSP = 1; | |
| 75 | + for(jj=0; zCopy[jj]; jj++){ | |
| 76 | + if( zCopy[jj]==';' ){ | |
| 77 | + int k; | |
| 78 | + for(k=jj-1; k>0 && fossil_isspace(zCopy[k]); k--){ zCopy[k] = 0; } | |
| 79 | + zCopy[jj] = 0; | |
| 80 | + while( jj+1<nAll | |
| 81 | + && (fossil_isspace(zCopy[jj+1]) || zCopy[jj+1]==';') | |
| 82 | + ){ | |
| 83 | + jj++; | |
| 84 | + } | |
| 85 | + assert( nCSP<nSemi+1 ); | |
| 86 | + azCSP[nCSP++] = zCopy+jj; | |
| 87 | + } | |
| 88 | + } | |
| 89 | + assert( nCSP<=nSemi+2 ); | |
| 90 | + azCSP[nCSP] = 0; | |
| 91 | + return azCSP; | |
| 92 | + } | |
| 93 | + } | |
| 94 | + return 0; | |
| 95 | +} | |
| 37 | 96 | |
| 38 | 97 | /* |
| 39 | 98 | ** WEBPAGE: secaudit0 |
| 40 | 99 | ** |
| 41 | 100 | ** Run a security audit of the current Fossil setup, looking |
| @@ -50,10 +109,11 @@ | ||
| 50 | 109 | const char *zAnonCap; /* Capabilities of user "anonymous" and "nobody" */ |
| 51 | 110 | const char *zPubPages; /* GLOB pattern for public pages */ |
| 52 | 111 | const char *zSelfCap; /* Capabilities of self-registered users */ |
| 53 | 112 | char *z; |
| 54 | 113 | int n; |
| 114 | + char **azCSP; /* Parsed content security policy */ | |
| 55 | 115 | |
| 56 | 116 | login_check_credentials(); |
| 57 | 117 | if( !g.perm.Admin ){ |
| 58 | 118 | login_needed(0); |
| 59 | 119 | return; |
| @@ -439,10 +499,30 @@ | ||
| 439 | 499 | } |
| 440 | 500 | |
| 441 | 501 | @ <li><p> User capability summary: |
| 442 | 502 | capability_summary(); |
| 443 | 503 | |
| 504 | + | |
| 505 | + azCSP = parse_content_security_policy(); | |
| 506 | + if( azCSP==0 ){ | |
| 507 | + @ <li><p> WARNING: No Content Security Policy (CSP) is specified in the | |
| 508 | + @ header. Though not required, a strong CSP is recommended. Fossil will | |
| 509 | + @ automatically insert an appropriate CSP if you let it generate the | |
| 510 | + @ HTML <tt><head></tt> element by omitting <tt><body></tt> | |
| 511 | + @ from the header configuration in your customized skin. | |
| 512 | + @ | |
| 513 | + }else{ | |
| 514 | + int ii; | |
| 515 | + @ <li><p> Content Security Policy: | |
| 516 | + @ <ol type="a"> | |
| 517 | + for(ii=0; azCSP[ii]; ii++){ | |
| 518 | + @ <li>%h(azCSP[ii]) | |
| 519 | + } | |
| 520 | + @ </ol> | |
| 521 | + } | |
| 522 | + fossil_free(azCSP); | |
| 523 | + | |
| 444 | 524 | if( alert_enabled() ){ |
| 445 | 525 | @ <li><p> Email alert configuration summary: |
| 446 | 526 | @ <table class="label-value"> |
| 447 | 527 | stats_for_email(); |
| 448 | 528 | @ </table> |
| 449 | 529 |
| --- src/security_audit.c | |
| +++ src/security_audit.c | |
| @@ -32,10 +32,69 @@ | |
| 32 | zTest++; |
| 33 | } |
| 34 | return 0; |
| 35 | } |
| 36 | |
| 37 | |
| 38 | /* |
| 39 | ** WEBPAGE: secaudit0 |
| 40 | ** |
| 41 | ** Run a security audit of the current Fossil setup, looking |
| @@ -50,10 +109,11 @@ | |
| 50 | const char *zAnonCap; /* Capabilities of user "anonymous" and "nobody" */ |
| 51 | const char *zPubPages; /* GLOB pattern for public pages */ |
| 52 | const char *zSelfCap; /* Capabilities of self-registered users */ |
| 53 | char *z; |
| 54 | int n; |
| 55 | |
| 56 | login_check_credentials(); |
| 57 | if( !g.perm.Admin ){ |
| 58 | login_needed(0); |
| 59 | return; |
| @@ -439,10 +499,30 @@ | |
| 439 | } |
| 440 | |
| 441 | @ <li><p> User capability summary: |
| 442 | capability_summary(); |
| 443 | |
| 444 | if( alert_enabled() ){ |
| 445 | @ <li><p> Email alert configuration summary: |
| 446 | @ <table class="label-value"> |
| 447 | stats_for_email(); |
| 448 | @ </table> |
| 449 |
| --- src/security_audit.c | |
| +++ src/security_audit.c | |
| @@ -32,10 +32,69 @@ | |
| 32 | zTest++; |
| 33 | } |
| 34 | return 0; |
| 35 | } |
| 36 | |
| 37 | /* |
| 38 | ** Extract the content-security-policy from the reply header. Parse it |
| 39 | ** up into separate fields, and return a pointer to a null-terminated |
| 40 | ** array of pointers to strings, one entry for each field. Or return |
| 41 | ** a NULL pointer if no CSP could be located in the header. |
| 42 | ** |
| 43 | ** Memory to hold the returned array and of the strings is obtained from |
| 44 | ** a single memory allocation, which the caller should free to avoid a |
| 45 | ** memory leak. |
| 46 | */ |
| 47 | static char **parse_content_security_policy(void){ |
| 48 | char **azCSP = 0; |
| 49 | int nCSP = 0; |
| 50 | const char *zHeader; |
| 51 | const char *zAll; |
| 52 | char *zCopy; |
| 53 | int nAll = 0; |
| 54 | int ii, jj, n, nx = 0; |
| 55 | int nSemi; |
| 56 | |
| 57 | zHeader = cgi_header(); |
| 58 | if( zHeader==0 ) return 0; |
| 59 | for(ii=0; zHeader[ii]; ii+=n){ |
| 60 | n = html_token_length(zHeader+ii); |
| 61 | if( zHeader[ii]=='<' |
| 62 | && fossil_strnicmp(html_attribute(zHeader+ii,"http-equiv",&nx), |
| 63 | "Content-Security-Policy",23)==0 |
| 64 | && nx==23 |
| 65 | && (zAll = html_attribute(zHeader+ii,"content",&nAll))!=0 |
| 66 | ){ |
| 67 | for(jj=nSemi=0; jj<nAll; jj++){ if( zAll[jj]==';' ) nSemi++; } |
| 68 | azCSP = fossil_malloc( nAll+1 + (nSemi+2)*sizeof(char*) ); |
| 69 | zCopy = (char*)&azCSP[nSemi+2]; |
| 70 | memcpy(zCopy,zAll,nAll); |
| 71 | zCopy[nAll] = 0; |
| 72 | while( fossil_isspace(zCopy[0]) || zCopy[0]==';' ){ zCopy++; } |
| 73 | azCSP[0] = zCopy; |
| 74 | nCSP = 1; |
| 75 | for(jj=0; zCopy[jj]; jj++){ |
| 76 | if( zCopy[jj]==';' ){ |
| 77 | int k; |
| 78 | for(k=jj-1; k>0 && fossil_isspace(zCopy[k]); k--){ zCopy[k] = 0; } |
| 79 | zCopy[jj] = 0; |
| 80 | while( jj+1<nAll |
| 81 | && (fossil_isspace(zCopy[jj+1]) || zCopy[jj+1]==';') |
| 82 | ){ |
| 83 | jj++; |
| 84 | } |
| 85 | assert( nCSP<nSemi+1 ); |
| 86 | azCSP[nCSP++] = zCopy+jj; |
| 87 | } |
| 88 | } |
| 89 | assert( nCSP<=nSemi+2 ); |
| 90 | azCSP[nCSP] = 0; |
| 91 | return azCSP; |
| 92 | } |
| 93 | } |
| 94 | return 0; |
| 95 | } |
| 96 | |
| 97 | /* |
| 98 | ** WEBPAGE: secaudit0 |
| 99 | ** |
| 100 | ** Run a security audit of the current Fossil setup, looking |
| @@ -50,10 +109,11 @@ | |
| 109 | const char *zAnonCap; /* Capabilities of user "anonymous" and "nobody" */ |
| 110 | const char *zPubPages; /* GLOB pattern for public pages */ |
| 111 | const char *zSelfCap; /* Capabilities of self-registered users */ |
| 112 | char *z; |
| 113 | int n; |
| 114 | char **azCSP; /* Parsed content security policy */ |
| 115 | |
| 116 | login_check_credentials(); |
| 117 | if( !g.perm.Admin ){ |
| 118 | login_needed(0); |
| 119 | return; |
| @@ -439,10 +499,30 @@ | |
| 499 | } |
| 500 | |
| 501 | @ <li><p> User capability summary: |
| 502 | capability_summary(); |
| 503 | |
| 504 | |
| 505 | azCSP = parse_content_security_policy(); |
| 506 | if( azCSP==0 ){ |
| 507 | @ <li><p> WARNING: No Content Security Policy (CSP) is specified in the |
| 508 | @ header. Though not required, a strong CSP is recommended. Fossil will |
| 509 | @ automatically insert an appropriate CSP if you let it generate the |
| 510 | @ HTML <tt><head></tt> element by omitting <tt><body></tt> |
| 511 | @ from the header configuration in your customized skin. |
| 512 | @ |
| 513 | }else{ |
| 514 | int ii; |
| 515 | @ <li><p> Content Security Policy: |
| 516 | @ <ol type="a"> |
| 517 | for(ii=0; azCSP[ii]; ii++){ |
| 518 | @ <li>%h(azCSP[ii]) |
| 519 | } |
| 520 | @ </ol> |
| 521 | } |
| 522 | fossil_free(azCSP); |
| 523 | |
| 524 | if( alert_enabled() ){ |
| 525 | @ <li><p> Email alert configuration summary: |
| 526 | @ <table class="label-value"> |
| 527 | stats_for_email(); |
| 528 | @ </table> |
| 529 |
+3
-1
| --- src/stat.c | ||
| +++ src/stat.c | ||
| @@ -681,10 +681,12 @@ | ||
| 681 | 681 | @ UPDATE artstat SET atype='file' |
| 682 | 682 | @ WHERE id IN (SELECT fid FROM mlink) |
| 683 | 683 | @ AND atype IS NULL; |
| 684 | 684 | @ UPDATE artstat SET atype='manifest' |
| 685 | 685 | @ WHERE id IN (SELECT objid FROM event WHERE type='ci') AND atype IS NULL; |
| 686 | + @ UPDATE artstat SET atype='forum' | |
| 687 | + @ WHERE id IN (SELECT objid FROM event WHERE type='f') AND atype IS NULL; | |
| 686 | 688 | @ UPDATE artstat SET atype='cluster' |
| 687 | 689 | @ WHERE atype IS NULL |
| 688 | 690 | @ AND id IN (SELECT rid FROM tagxref |
| 689 | 691 | @ WHERE tagid=(SELECT tagid FROM tag |
| 690 | 692 | @ WHERE tagname='cluster')); |
| @@ -845,11 +847,11 @@ | ||
| 845 | 847 | " LIMIT 1 OFFSET %d", nFull/2); |
| 846 | 848 | @ <tr><th>Full-text artifact sizes:</th> |
| 847 | 849 | @ <td>largest: %,d(mxCmpr), average: %,d((int)r), median: %,d(med)</td> |
| 848 | 850 | @ </table> |
| 849 | 851 | |
| 850 | - @ <h1>Artifact size distribution facts:</h1> | |
| 852 | + @ <h1>Artifact Size Distribution Facts:</h1> | |
| 851 | 853 | @ <ol> |
| 852 | 854 | @ <li><p>The largest %.2f(n50pct*100.0/nTotal)%% of artifacts |
| 853 | 855 | largest_n_artifacts(n50pct); |
| 854 | 856 | @ use 50%% of the total artifact space. |
| 855 | 857 | @ <li><p>The largest 1%% of artifacts |
| 856 | 858 |
| --- src/stat.c | |
| +++ src/stat.c | |
| @@ -681,10 +681,12 @@ | |
| 681 | @ UPDATE artstat SET atype='file' |
| 682 | @ WHERE id IN (SELECT fid FROM mlink) |
| 683 | @ AND atype IS NULL; |
| 684 | @ UPDATE artstat SET atype='manifest' |
| 685 | @ WHERE id IN (SELECT objid FROM event WHERE type='ci') AND atype IS NULL; |
| 686 | @ UPDATE artstat SET atype='cluster' |
| 687 | @ WHERE atype IS NULL |
| 688 | @ AND id IN (SELECT rid FROM tagxref |
| 689 | @ WHERE tagid=(SELECT tagid FROM tag |
| 690 | @ WHERE tagname='cluster')); |
| @@ -845,11 +847,11 @@ | |
| 845 | " LIMIT 1 OFFSET %d", nFull/2); |
| 846 | @ <tr><th>Full-text artifact sizes:</th> |
| 847 | @ <td>largest: %,d(mxCmpr), average: %,d((int)r), median: %,d(med)</td> |
| 848 | @ </table> |
| 849 | |
| 850 | @ <h1>Artifact size distribution facts:</h1> |
| 851 | @ <ol> |
| 852 | @ <li><p>The largest %.2f(n50pct*100.0/nTotal)%% of artifacts |
| 853 | largest_n_artifacts(n50pct); |
| 854 | @ use 50%% of the total artifact space. |
| 855 | @ <li><p>The largest 1%% of artifacts |
| 856 |
| --- src/stat.c | |
| +++ src/stat.c | |
| @@ -681,10 +681,12 @@ | |
| 681 | @ UPDATE artstat SET atype='file' |
| 682 | @ WHERE id IN (SELECT fid FROM mlink) |
| 683 | @ AND atype IS NULL; |
| 684 | @ UPDATE artstat SET atype='manifest' |
| 685 | @ WHERE id IN (SELECT objid FROM event WHERE type='ci') AND atype IS NULL; |
| 686 | @ UPDATE artstat SET atype='forum' |
| 687 | @ WHERE id IN (SELECT objid FROM event WHERE type='f') AND atype IS NULL; |
| 688 | @ UPDATE artstat SET atype='cluster' |
| 689 | @ WHERE atype IS NULL |
| 690 | @ AND id IN (SELECT rid FROM tagxref |
| 691 | @ WHERE tagid=(SELECT tagid FROM tag |
| 692 | @ WHERE tagname='cluster')); |
| @@ -845,11 +847,11 @@ | |
| 847 | " LIMIT 1 OFFSET %d", nFull/2); |
| 848 | @ <tr><th>Full-text artifact sizes:</th> |
| 849 | @ <td>largest: %,d(mxCmpr), average: %,d((int)r), median: %,d(med)</td> |
| 850 | @ </table> |
| 851 | |
| 852 | @ <h1>Artifact Size Distribution Facts:</h1> |
| 853 | @ <ol> |
| 854 | @ <li><p>The largest %.2f(n50pct*100.0/nTotal)%% of artifacts |
| 855 | largest_n_artifacts(n50pct); |
| 856 | @ use 50%% of the total artifact space. |
| 857 | @ <li><p>The largest 1%% of artifacts |
| 858 |
+107
-8
| --- src/wikiformat.c | ||
| +++ src/wikiformat.c | ||
| @@ -2014,16 +2014,13 @@ | ||
| 2014 | 2014 | } |
| 2015 | 2015 | free(renderer.aStack); |
| 2016 | 2016 | } |
| 2017 | 2017 | |
| 2018 | 2018 | /* |
| 2019 | -** Get the next HTML token. | |
| 2020 | -** | |
| 2021 | -** z points to the start of a token. Return the number of | |
| 2022 | -** characters in that token. | |
| 2019 | +** Return the length, in bytes, of the HTML token that z is pointing to. | |
| 2023 | 2020 | */ |
| 2024 | -static int nextHtmlToken(const char *z){ | |
| 2021 | +int html_token_length(const char *z){ | |
| 2025 | 2022 | int n; |
| 2026 | 2023 | char c; |
| 2027 | 2024 | if( (c=z[0])=='<' ){ |
| 2028 | 2025 | n = htmlTagLength(z); |
| 2029 | 2026 | if( n<=0 ) n = 1; |
| @@ -2040,10 +2037,112 @@ | ||
| 2040 | 2037 | if( c=='<' || c=='&' || fossil_isspace(c) || c==0 ) break; |
| 2041 | 2038 | } |
| 2042 | 2039 | } |
| 2043 | 2040 | return n; |
| 2044 | 2041 | } |
| 2042 | + | |
| 2043 | +/* | |
| 2044 | +** z points to someplace in the middle of HTML markup. Return the length | |
| 2045 | +** of the subtoken that starts on z. | |
| 2046 | +*/ | |
| 2047 | +int html_subtoken_length(const char *z){ | |
| 2048 | + int n; | |
| 2049 | + char c; | |
| 2050 | + c = z[0]; | |
| 2051 | + if( fossil_isspace(c) ){ | |
| 2052 | + for(n=1; z[n] && fossil_isspace(z[n]); n++){} | |
| 2053 | + return n; | |
| 2054 | + } | |
| 2055 | + if( c=='"' || c=='\'' ){ | |
| 2056 | + for(n=1; z[n] && z[n]!=c && z[n]!='>'; n++){} | |
| 2057 | + if( z[n]==c ) n++; | |
| 2058 | + return n; | |
| 2059 | + } | |
| 2060 | + if( c=='>' ){ | |
| 2061 | + return 0; | |
| 2062 | + } | |
| 2063 | + if( c=='=' ){ | |
| 2064 | + return 1; | |
| 2065 | + } | |
| 2066 | + if( fossil_isalnum(c) || c=='/' ){ | |
| 2067 | + for(n=1; (c=z[n])!=0 && (fossil_isalnum(c) || c=='-' || c=='_'); n++){} | |
| 2068 | + return n; | |
| 2069 | + } | |
| 2070 | + return 1; | |
| 2071 | +} | |
| 2072 | + | |
| 2073 | +/* | |
| 2074 | +** z points to an HTML markup token: <TAG ATTR=VALUE ...> | |
| 2075 | +** This routine looks for the VALUE associated with zAttr and returns | |
| 2076 | +** a pointer to the start of that value and sets *pLen to be the length | |
| 2077 | +** in bytes for the value. Or it returns NULL if no such attr exists. | |
| 2078 | +*/ | |
| 2079 | +const char *html_attribute(const char *zMarkup, const char *zAttr, int *pLen){ | |
| 2080 | + int i = 1; | |
| 2081 | + int n; | |
| 2082 | + int nAttr; | |
| 2083 | + int iMatchCnt = 0; | |
| 2084 | + assert( zMarkup[0]=='<' ); | |
| 2085 | + assert( zMarkup[1]!=0 ); | |
| 2086 | + n = html_subtoken_length(zMarkup+i); | |
| 2087 | + if( n==0 ) return 0; | |
| 2088 | + i += n; | |
| 2089 | + nAttr = (int)strlen(zAttr); | |
| 2090 | + while( 1 ){ | |
| 2091 | + const char *zStart = zMarkup+i; | |
| 2092 | + n = html_subtoken_length(zStart); | |
| 2093 | + if( n==0 ) break; | |
| 2094 | + i += n; | |
| 2095 | + if( fossil_isspace(zStart[0]) ) continue; | |
| 2096 | + if( n==nAttr && fossil_strnicmp(zAttr,zStart,nAttr)==0 ){ | |
| 2097 | + iMatchCnt = 1; | |
| 2098 | + }else if( n==1 && zStart[0]=='=' && iMatchCnt==1 ){ | |
| 2099 | + iMatchCnt = 2; | |
| 2100 | + }else if( iMatchCnt==2 ){ | |
| 2101 | + if( (zStart[0]=='"' || zStart[0]=='\'') && zStart[n-1]==zStart[0] ){ | |
| 2102 | + zStart++; | |
| 2103 | + n -= 2; | |
| 2104 | + } | |
| 2105 | + *pLen = n; | |
| 2106 | + return zStart; | |
| 2107 | + }else{ | |
| 2108 | + iMatchCnt = 0; | |
| 2109 | + } | |
| 2110 | + } | |
| 2111 | + return 0; | |
| 2112 | +} | |
| 2113 | + | |
| 2114 | +/* | |
| 2115 | +** COMMAND: test-html-tokenize | |
| 2116 | +** | |
| 2117 | +** Tokenize an HTML file. Return the offset and length and text of | |
| 2118 | +** each token - one token per line. Omit white-space tokens. | |
| 2119 | +*/ | |
| 2120 | +void test_html_tokenize(void){ | |
| 2121 | + Blob in; | |
| 2122 | + char *z; | |
| 2123 | + int i; | |
| 2124 | + int iOfst, n; | |
| 2125 | + | |
| 2126 | + for(i=2; i<g.argc; i++){ | |
| 2127 | + blob_read_from_file(&in, g.argv[i], ExtFILE); | |
| 2128 | + z = blob_str(&in); | |
| 2129 | + for(iOfst=0; z[iOfst]; iOfst+=n){ | |
| 2130 | + n = html_token_length(z+iOfst); | |
| 2131 | + if( fossil_isspace(z[iOfst]) ) continue; | |
| 2132 | + fossil_print("%d %d %.*s\n", iOfst, n, n, z+iOfst); | |
| 2133 | + if( z[iOfst]=='<' && n>1 ){ | |
| 2134 | + int j,k; | |
| 2135 | + for(j=iOfst+1; (k = html_subtoken_length(z+j))>0; j+=k){ | |
| 2136 | + if( fossil_isspace(z[j]) || z[j]=='=' ) continue; | |
| 2137 | + fossil_print("# %d %d %.*s\n", j, k, k, z+j); | |
| 2138 | + } | |
| 2139 | + } | |
| 2140 | + } | |
| 2141 | + blob_reset(&in); | |
| 2142 | + } | |
| 2143 | +} | |
| 2045 | 2144 | |
| 2046 | 2145 | /* |
| 2047 | 2146 | ** Attempt to reformat messy HTML to be easily readable by humans. |
| 2048 | 2147 | ** |
| 2049 | 2148 | ** * Try to keep lines less than 80 characters in length |
| @@ -2062,11 +2161,11 @@ | ||
| 2062 | 2161 | int nPre = 0; |
| 2063 | 2162 | int iCur = 0; |
| 2064 | 2163 | int wantSpace = 0; |
| 2065 | 2164 | int omitSpace = 1; |
| 2066 | 2165 | while( zIn[0] ){ |
| 2067 | - n = nextHtmlToken(zIn); | |
| 2166 | + n = html_token_length(zIn); | |
| 2068 | 2167 | if( zIn[0]=='<' && n>1 ){ |
| 2069 | 2168 | int i, j; |
| 2070 | 2169 | int isCloseTag; |
| 2071 | 2170 | int eTag; |
| 2072 | 2171 | int eType; |
| @@ -2181,11 +2280,11 @@ | ||
| 2181 | 2280 | int seenText = 0; /* True after first non-whitespace seen */ |
| 2182 | 2281 | int nNL = 0; /* Number of \n characters at the end of pOut */ |
| 2183 | 2282 | int nWS = 0; /* True if pOut ends with whitespace */ |
| 2184 | 2283 | while( fossil_isspace(zIn[0]) ) zIn++; |
| 2185 | 2284 | while( zIn[0] ){ |
| 2186 | - n = nextHtmlToken(zIn); | |
| 2285 | + n = html_token_length(zIn); | |
| 2187 | 2286 | if( zIn[0]=='<' && n>1 ){ |
| 2188 | 2287 | int isCloseTag; |
| 2189 | 2288 | int eTag; |
| 2190 | 2289 | int eType; |
| 2191 | 2290 | char zTag[32]; |
| @@ -2197,11 +2296,11 @@ | ||
| 2197 | 2296 | eTag = findTag(zTag); |
| 2198 | 2297 | eType = aMarkup[eTag].iType; |
| 2199 | 2298 | if( eTag==MARKUP_INVALID && fossil_strnicmp(zIn,"<style",6)==0 ){ |
| 2200 | 2299 | zIn += n; |
| 2201 | 2300 | while( zIn[0] ){ |
| 2202 | - n = nextHtmlToken(zIn); | |
| 2301 | + n = html_token_length(zIn); | |
| 2203 | 2302 | if( fossil_strnicmp(zIn, "</style",7)==0 ) break; |
| 2204 | 2303 | zIn += n; |
| 2205 | 2304 | } |
| 2206 | 2305 | if( zIn[0]=='<' ) zIn += n; |
| 2207 | 2306 | continue; |
| 2208 | 2307 |
| --- src/wikiformat.c | |
| +++ src/wikiformat.c | |
| @@ -2014,16 +2014,13 @@ | |
| 2014 | } |
| 2015 | free(renderer.aStack); |
| 2016 | } |
| 2017 | |
| 2018 | /* |
| 2019 | ** Get the next HTML token. |
| 2020 | ** |
| 2021 | ** z points to the start of a token. Return the number of |
| 2022 | ** characters in that token. |
| 2023 | */ |
| 2024 | static int nextHtmlToken(const char *z){ |
| 2025 | int n; |
| 2026 | char c; |
| 2027 | if( (c=z[0])=='<' ){ |
| 2028 | n = htmlTagLength(z); |
| 2029 | if( n<=0 ) n = 1; |
| @@ -2040,10 +2037,112 @@ | |
| 2040 | if( c=='<' || c=='&' || fossil_isspace(c) || c==0 ) break; |
| 2041 | } |
| 2042 | } |
| 2043 | return n; |
| 2044 | } |
| 2045 | |
| 2046 | /* |
| 2047 | ** Attempt to reformat messy HTML to be easily readable by humans. |
| 2048 | ** |
| 2049 | ** * Try to keep lines less than 80 characters in length |
| @@ -2062,11 +2161,11 @@ | |
| 2062 | int nPre = 0; |
| 2063 | int iCur = 0; |
| 2064 | int wantSpace = 0; |
| 2065 | int omitSpace = 1; |
| 2066 | while( zIn[0] ){ |
| 2067 | n = nextHtmlToken(zIn); |
| 2068 | if( zIn[0]=='<' && n>1 ){ |
| 2069 | int i, j; |
| 2070 | int isCloseTag; |
| 2071 | int eTag; |
| 2072 | int eType; |
| @@ -2181,11 +2280,11 @@ | |
| 2181 | int seenText = 0; /* True after first non-whitespace seen */ |
| 2182 | int nNL = 0; /* Number of \n characters at the end of pOut */ |
| 2183 | int nWS = 0; /* True if pOut ends with whitespace */ |
| 2184 | while( fossil_isspace(zIn[0]) ) zIn++; |
| 2185 | while( zIn[0] ){ |
| 2186 | n = nextHtmlToken(zIn); |
| 2187 | if( zIn[0]=='<' && n>1 ){ |
| 2188 | int isCloseTag; |
| 2189 | int eTag; |
| 2190 | int eType; |
| 2191 | char zTag[32]; |
| @@ -2197,11 +2296,11 @@ | |
| 2197 | eTag = findTag(zTag); |
| 2198 | eType = aMarkup[eTag].iType; |
| 2199 | if( eTag==MARKUP_INVALID && fossil_strnicmp(zIn,"<style",6)==0 ){ |
| 2200 | zIn += n; |
| 2201 | while( zIn[0] ){ |
| 2202 | n = nextHtmlToken(zIn); |
| 2203 | if( fossil_strnicmp(zIn, "</style",7)==0 ) break; |
| 2204 | zIn += n; |
| 2205 | } |
| 2206 | if( zIn[0]=='<' ) zIn += n; |
| 2207 | continue; |
| 2208 |
| --- src/wikiformat.c | |
| +++ src/wikiformat.c | |
| @@ -2014,16 +2014,13 @@ | |
| 2014 | } |
| 2015 | free(renderer.aStack); |
| 2016 | } |
| 2017 | |
| 2018 | /* |
| 2019 | ** Return the length, in bytes, of the HTML token that z is pointing to. |
| 2020 | */ |
| 2021 | int html_token_length(const char *z){ |
| 2022 | int n; |
| 2023 | char c; |
| 2024 | if( (c=z[0])=='<' ){ |
| 2025 | n = htmlTagLength(z); |
| 2026 | if( n<=0 ) n = 1; |
| @@ -2040,10 +2037,112 @@ | |
| 2037 | if( c=='<' || c=='&' || fossil_isspace(c) || c==0 ) break; |
| 2038 | } |
| 2039 | } |
| 2040 | return n; |
| 2041 | } |
| 2042 | |
| 2043 | /* |
| 2044 | ** z points to someplace in the middle of HTML markup. Return the length |
| 2045 | ** of the subtoken that starts on z. |
| 2046 | */ |
| 2047 | int html_subtoken_length(const char *z){ |
| 2048 | int n; |
| 2049 | char c; |
| 2050 | c = z[0]; |
| 2051 | if( fossil_isspace(c) ){ |
| 2052 | for(n=1; z[n] && fossil_isspace(z[n]); n++){} |
| 2053 | return n; |
| 2054 | } |
| 2055 | if( c=='"' || c=='\'' ){ |
| 2056 | for(n=1; z[n] && z[n]!=c && z[n]!='>'; n++){} |
| 2057 | if( z[n]==c ) n++; |
| 2058 | return n; |
| 2059 | } |
| 2060 | if( c=='>' ){ |
| 2061 | return 0; |
| 2062 | } |
| 2063 | if( c=='=' ){ |
| 2064 | return 1; |
| 2065 | } |
| 2066 | if( fossil_isalnum(c) || c=='/' ){ |
| 2067 | for(n=1; (c=z[n])!=0 && (fossil_isalnum(c) || c=='-' || c=='_'); n++){} |
| 2068 | return n; |
| 2069 | } |
| 2070 | return 1; |
| 2071 | } |
| 2072 | |
| 2073 | /* |
| 2074 | ** z points to an HTML markup token: <TAG ATTR=VALUE ...> |
| 2075 | ** This routine looks for the VALUE associated with zAttr and returns |
| 2076 | ** a pointer to the start of that value and sets *pLen to be the length |
| 2077 | ** in bytes for the value. Or it returns NULL if no such attr exists. |
| 2078 | */ |
| 2079 | const char *html_attribute(const char *zMarkup, const char *zAttr, int *pLen){ |
| 2080 | int i = 1; |
| 2081 | int n; |
| 2082 | int nAttr; |
| 2083 | int iMatchCnt = 0; |
| 2084 | assert( zMarkup[0]=='<' ); |
| 2085 | assert( zMarkup[1]!=0 ); |
| 2086 | n = html_subtoken_length(zMarkup+i); |
| 2087 | if( n==0 ) return 0; |
| 2088 | i += n; |
| 2089 | nAttr = (int)strlen(zAttr); |
| 2090 | while( 1 ){ |
| 2091 | const char *zStart = zMarkup+i; |
| 2092 | n = html_subtoken_length(zStart); |
| 2093 | if( n==0 ) break; |
| 2094 | i += n; |
| 2095 | if( fossil_isspace(zStart[0]) ) continue; |
| 2096 | if( n==nAttr && fossil_strnicmp(zAttr,zStart,nAttr)==0 ){ |
| 2097 | iMatchCnt = 1; |
| 2098 | }else if( n==1 && zStart[0]=='=' && iMatchCnt==1 ){ |
| 2099 | iMatchCnt = 2; |
| 2100 | }else if( iMatchCnt==2 ){ |
| 2101 | if( (zStart[0]=='"' || zStart[0]=='\'') && zStart[n-1]==zStart[0] ){ |
| 2102 | zStart++; |
| 2103 | n -= 2; |
| 2104 | } |
| 2105 | *pLen = n; |
| 2106 | return zStart; |
| 2107 | }else{ |
| 2108 | iMatchCnt = 0; |
| 2109 | } |
| 2110 | } |
| 2111 | return 0; |
| 2112 | } |
| 2113 | |
| 2114 | /* |
| 2115 | ** COMMAND: test-html-tokenize |
| 2116 | ** |
| 2117 | ** Tokenize an HTML file. Return the offset and length and text of |
| 2118 | ** each token - one token per line. Omit white-space tokens. |
| 2119 | */ |
| 2120 | void test_html_tokenize(void){ |
| 2121 | Blob in; |
| 2122 | char *z; |
| 2123 | int i; |
| 2124 | int iOfst, n; |
| 2125 | |
| 2126 | for(i=2; i<g.argc; i++){ |
| 2127 | blob_read_from_file(&in, g.argv[i], ExtFILE); |
| 2128 | z = blob_str(&in); |
| 2129 | for(iOfst=0; z[iOfst]; iOfst+=n){ |
| 2130 | n = html_token_length(z+iOfst); |
| 2131 | if( fossil_isspace(z[iOfst]) ) continue; |
| 2132 | fossil_print("%d %d %.*s\n", iOfst, n, n, z+iOfst); |
| 2133 | if( z[iOfst]=='<' && n>1 ){ |
| 2134 | int j,k; |
| 2135 | for(j=iOfst+1; (k = html_subtoken_length(z+j))>0; j+=k){ |
| 2136 | if( fossil_isspace(z[j]) || z[j]=='=' ) continue; |
| 2137 | fossil_print("# %d %d %.*s\n", j, k, k, z+j); |
| 2138 | } |
| 2139 | } |
| 2140 | } |
| 2141 | blob_reset(&in); |
| 2142 | } |
| 2143 | } |
| 2144 | |
| 2145 | /* |
| 2146 | ** Attempt to reformat messy HTML to be easily readable by humans. |
| 2147 | ** |
| 2148 | ** * Try to keep lines less than 80 characters in length |
| @@ -2062,11 +2161,11 @@ | |
| 2161 | int nPre = 0; |
| 2162 | int iCur = 0; |
| 2163 | int wantSpace = 0; |
| 2164 | int omitSpace = 1; |
| 2165 | while( zIn[0] ){ |
| 2166 | n = html_token_length(zIn); |
| 2167 | if( zIn[0]=='<' && n>1 ){ |
| 2168 | int i, j; |
| 2169 | int isCloseTag; |
| 2170 | int eTag; |
| 2171 | int eType; |
| @@ -2181,11 +2280,11 @@ | |
| 2280 | int seenText = 0; /* True after first non-whitespace seen */ |
| 2281 | int nNL = 0; /* Number of \n characters at the end of pOut */ |
| 2282 | int nWS = 0; /* True if pOut ends with whitespace */ |
| 2283 | while( fossil_isspace(zIn[0]) ) zIn++; |
| 2284 | while( zIn[0] ){ |
| 2285 | n = html_token_length(zIn); |
| 2286 | if( zIn[0]=='<' && n>1 ){ |
| 2287 | int isCloseTag; |
| 2288 | int eTag; |
| 2289 | int eType; |
| 2290 | char zTag[32]; |
| @@ -2197,11 +2296,11 @@ | |
| 2296 | eTag = findTag(zTag); |
| 2297 | eType = aMarkup[eTag].iType; |
| 2298 | if( eTag==MARKUP_INVALID && fossil_strnicmp(zIn,"<style",6)==0 ){ |
| 2299 | zIn += n; |
| 2300 | while( zIn[0] ){ |
| 2301 | n = html_token_length(zIn); |
| 2302 | if( fossil_strnicmp(zIn, "</style",7)==0 ) break; |
| 2303 | zIn += n; |
| 2304 | } |
| 2305 | if( zIn[0]=='<' ) zIn += n; |
| 2306 | continue; |
| 2307 |
+80
-63
| --- www/customskin.md | ||
| +++ www/customskin.md | ||
| @@ -1,7 +1,6 @@ | ||
| 1 | -Theming | |
| 2 | -======= | |
| 1 | +# Skinning the Fossil Web Interface | |
| 3 | 2 | |
| 4 | 3 | Every HTML page generated by Fossil has the following basic structure: |
| 5 | 4 | |
| 6 | 5 | <blockquote><table border=1 cellpadding=10><tbody> |
| 7 | 6 | <tr><td style='background-color:lightblue;text-align:center;'>Header</td></tr> |
| @@ -9,43 +8,54 @@ | ||
| 9 | 8 | Fossil-Generated Content</td></tr> |
| 10 | 9 | <tr><td style='background-color:lightblue;text-align:center;'>Footer</td></tr> |
| 11 | 10 | <tr><td style='background-color:lightyellow;text-align:center;'>Javascript (optional)</td></tr> |
| 12 | 11 | </tbody></table></blockquote> |
| 13 | 12 | |
| 14 | -The header and footer control the "look" of Fossil pages. Those | |
| 15 | -two sections can be customized separately for each repository to | |
| 16 | -develop a new theme. | |
| 17 | - | |
| 18 | -The header will normally look something like this: | |
| 19 | - | |
| 20 | - <html> | |
| 21 | - <head> ... </head> | |
| 22 | - <body> | |
| 23 | - ... top banner and menu bar ... | |
| 24 | - <div class='content'> | |
| 25 | - | |
| 26 | -And the footer will look something like this: | |
| 27 | - | |
| 13 | +The default header looks something like this: | |
| 14 | + | |
| 15 | + <div class="header"> | |
| 16 | + <div class="title"><h1>$<project_name></h1>$<title></div> | |
| 17 | + ... top banner and menu bar ... | |
| 18 | + | |
| 19 | +The Fossil-generated content section looks like this: | |
| 20 | + | |
| 21 | + <div class="content"> | |
| 22 | + ... generated content here ... | |
| 23 | + </div> | |
| 24 | + | |
| 25 | +And the footer looks like this: | |
| 26 | + | |
| 27 | + <div class="footer"> | |
| 28 | + ... skin-specific stuff here ... | |
| 28 | 29 | </div> |
| 29 | - ... bottom material ... | |
| 30 | - </body> | |
| 31 | - </html> | |
| 32 | - | |
| 33 | -The <head> element in the header will normally reference the | |
| 34 | -/style.css CSS file that Fossil stores internally. (The $stylesheet_url | |
| 35 | -TH1 variable, described below, is useful for accomplishing this.) | |
| 36 | - | |
| 37 | -The middle "content" section comprised the bulk of most pages and | |
| 30 | + <script nonce=$nonce> | |
| 31 | + <th1>styleScript</th1> | |
| 32 | + </script> | |
| 33 | + | |
| 34 | +Notice that there are no `<html>` or `<head>` elements in the header, | |
| 35 | +nor is there an `</html>` closing tag in the footer. Fossil generates | |
| 36 | +this material automatically unless it sees that you have provided your | |
| 37 | +own HTML document header within the skin’s Header section. | |
| 38 | + | |
| 39 | +This design lets most users get the benefit of Fossil’s automatic HTML | |
| 40 | +document header, which takes care of quite a few different things for | |
| 41 | +you, while still allowing you to [override if at need](#headfoot). | |
| 42 | + | |
| 43 | +When overriding the default document header, you might want to use some | |
| 44 | +of the [TH1 variables documented below](#vars) such as `$stylesheet_url` | |
| 45 | +to avoid hand-writing code that Fossil can generate for you. | |
| 46 | + | |
| 47 | +The middle "content" section comprises the bulk of most pages and | |
| 38 | 48 | contains the actual Fossil-generated data |
| 39 | 49 | that the user is interested in seeing. The text of this content |
| 40 | 50 | section is not normally configurable. The content text can be styled |
| 41 | -using CSS, but it otherwise fixed. Hence it is the header and footer | |
| 51 | +using CSS, but it is otherwise fixed. Hence it is the header, the footer, | |
| 42 | 52 | and the CSS that determine the look of a repository. |
| 43 | 53 | We call the bundle of built-in CSS, header, and footer a "skin". |
| 44 | 54 | |
| 45 | -Built-in Skins | |
| --------------- | ||
| 55 | + | |
| 56 | +## <a name="builtin"></a>Built-in Skins | |
| 46 | 57 | |
| 47 | 58 | Fossil comes with several built-in skins. The sources to these built-ins can |
| 48 | 59 | be found in the Fossil source tree under the skins/ folder. The skins/ |
| 49 | 60 | folder contains a separate subfolder for each built-in skin, with each |
| 50 | 61 | subfolders holding four files, "css.txt", "details.txt", |
| @@ -59,12 +69,12 @@ | ||
| 59 | 69 | line option can be used for the |
| 60 | 70 | [fossil ui](../../../help?cmd=ui) or |
| 61 | 71 | [fossil server](../../../help?cmd=server) commands to force that particular |
| 62 | 72 | instance of Fossil to use the specified built-in skin. |
| 63 | 73 | |
| 64 | -Sharing Skins | |
| -------------- | ||
| 74 | + | |
| 75 | +## <a name="sharing"></a>Sharing Skins | |
| 65 | 76 | |
| 66 | 77 | The skin of a repository is not part of the versioned state and does not |
| 67 | 78 | "push" or "pull" like checked-in files. The skin is local to the |
| 68 | 79 | repository. However, skins can be shared between repositories using |
| 69 | 80 | the [fossil config](../../../help?cmd=configuration) command. |
| @@ -88,58 +98,51 @@ | ||
| 88 | 98 | necessary. |
| 89 | 99 | |
| 90 | 100 | When cloning a repository, the skin of new repository is initialized to |
| 91 | 101 | the skin of the repository from which it was cloned. |
| 92 | 102 | |
| 93 | -Header And Footer Processing | |
| ----------------------------- | ||
| 103 | + | |
| 104 | +## <a name="headfoot"></a>Header and Footer Processing | |
| 94 | 105 | |
| 95 | -The header.txt and footer.txt files of a skin are merely the HTML text | |
| 96 | -of the header and footer. Except, before being prepended and appended to | |
| 97 | -the content, the header and footer text are run through a | |
| 106 | +The `header.txt` and `footer.txt` files of a skin are merely the HTML text | |
| 107 | +of the header and footer, except that before being prepended and appended to | |
| 108 | +the content, their text content is run through a | |
| 98 | 109 | [TH1 interpreter](./th1.md) that might adjust the text as follows: |
| 99 | 110 | |
| 100 | 111 | * All text within <th1>...</th1> is elided from the |
| 101 | 112 | output and that text is instead run as a TH1 script. That TH1 |
| 102 | 113 | script has the opportunity to insert new text in place of itself, |
| 103 | 114 | or to inhibit or enable the output of subsequent text. |
| 104 | 115 | |
| 105 | - * Text for the form "$NAME" or "$<NAME>" is replace with | |
| 116 | + * Text of the form "$NAME" or "$<NAME>" is replaced with | |
| 106 | 117 | the value of the TH1 variable NAME. |
| 107 | 118 | |
| 108 | -For example, the following is the first few lines of a typical | |
| 109 | -header file: | |
| 110 | - | |
| 111 | - <html> | |
| 112 | - <head> | |
| 113 | - <base href="$baseurl/$current_page" /> | |
| 114 | - <title>$<project_name>: $<title></title> | |
| 115 | - <link rel="alternate" type="application/rss+xml" title="RSS Feed" | |
| 116 | - href="$home/timeline.rss" /> | |
| 117 | - <link rel="stylesheet" href="$stylesheet_url" type="text/css" | |
| 118 | - media="screen" /> | |
| 119 | - </head> | |
| 120 | - | |
| 121 | -After variables are substituted by TH1, the final header text | |
| 122 | -delivered to the web browser might look something like this: | |
| 123 | - | |
| 124 | - <html> | |
| 125 | - <head> | |
| 126 | - <base href="https://www.fossil-scm.org/skin2/timeline" /> | |
| 127 | - <title>Fossil: Timeline</title> | |
| 128 | - <link rel="alternate" type="application/rss+xml" title="RSS Feed" | |
| 129 | - href="/skin2/timeline.rss" /> | |
| 130 | - <link rel="stylesheet" href="/skin2/style.css?default" type="text/css" | |
| 131 | - media="screen" /> | |
| 132 | - </head> | |
| 119 | +Above, we saw the first few lines of a typical Fossil skin header: | |
| 120 | + | |
| 121 | + <div class="header"> | |
| 122 | + <div class="title"><h1>$<project_name></h1>$<title>/div> | |
| 123 | + | |
| 124 | +After variables are substituted by TH1, that will look more like this: | |
| 125 | + | |
| 126 | + <div class="header"> | |
| 127 | + <div class="title"><h1>Project Name</h1>Page Title</div> | |
| 128 | + | |
| 129 | +As you can see, two TH1 variable substitutions were done. | |
| 133 | 130 | |
| 134 | 131 | The same TH1 interpreter is used for both the header and the footer |
| 135 | 132 | and for all scripts contained within them both. Hence, any global |
| 136 | 133 | TH1 variables that are set by the header are available to the footer. |
| 137 | 134 | |
| 138 | -Customizing the ≡ Hamburger Menu | |
| --------------------------------- | ||
| 135 | +Fossil provides the HTML | |
| 136 | +document container tags `<html>`, `<head>`, and their inner content when | |
| 137 | +your skin’s header and footer don’t include them. This default header | |
| 138 | +declares the repository’s Content Security Policy (CSP) which is well | |
| 139 | +worth understanding, but since it is not strictly about skinning, we | |
| 140 | +cover that in [a separate document](./defcsp.md). | |
| 141 | + | |
| 142 | + | |
| 143 | +## <a name="menu"></a>Customizing the ≡ Hamburger Menu | |
| 139 | 144 | |
| 140 | 145 | The menu bar of the default skin has an entry to open a drop-down menu with |
| 141 | 146 | additional navigation links, represented by the ≡ button (hence the name |
| 142 | 147 | "hamburger menu"). The Javascript logic to open and close the hamburger menu |
| 143 | 148 | when the button is clicked is contained in the optional Javascript part (js.txt) |
| @@ -193,12 +196,12 @@ | ||
| 193 | 196 | The custom `data-anim-ms` attribute can be added to the panel element to direct |
| 194 | 197 | the Javascript logic to override the default menu animation duration of 400 ms. |
| 195 | 198 | A faster animation duration of 80-200 ms may be preferred for smaller menus. The |
| 196 | 199 | animation is disabled by setting the attribute to `"0"`. |
| 197 | 200 | |
| 198 | -TH1 Variables | |
| -------------- | ||
| 201 | + | |
| 202 | +## <a name="vars"></a>TH1 Variables | |
| 199 | 203 | |
| 200 | 204 | Before expanding the TH1 within the header and footer, Fossil first |
| 201 | 205 | initializes a number of TH1 variables to values that depend on |
| 202 | 206 | repository settings and the specific page being generated. |
| 203 | 207 | |
| @@ -235,11 +238,18 @@ | ||
| 235 | 238 | Examples: "timeline", "doc/trunk/README.txt", "wiki". |
| 236 | 239 | |
| 237 | 240 | * **csrf_token** - A token used to prevent cross-site request forgery. |
| 238 | 241 | |
| 239 | 242 | * **default_csp** - The content to be used within the default header |
| 240 | - for the "Content-Security-Policy" meta tag. | |
| 243 | + for the "Content-Security-Policy" `<meta>` tag. You can use | |
| 244 | + [Fossil’s default CSP](./defcsp.md) from this variable in your | |
| 245 | + [own custom `<head>`](#headfoot). Alternately, you can override | |
| 246 | + the default CSP from the [`th1-setup` script](./th1-hooks.md), | |
| 247 | + which runs before TH1 processing happens during skin processing, | |
| 248 | + allowing you to set a custom CSP without recompiling Fossil or | |
| 249 | + providing a hand-written `<head>` section in the Header section | |
| 250 | + of a custom skin. | |
| 241 | 251 | |
| 242 | 252 | * **nonce** - The value of the cryptographic nonce for the request |
| 243 | 253 | being processed. |
| 244 | 254 | |
| 245 | 255 | * **release_version** - The release version of Fossil. Ex: "1.31" |
| @@ -268,12 +278,12 @@ | ||
| 268 | 278 | All of the above are variables in the sense that either the header or the |
| 269 | 279 | footer is free to change or erase them. But they should probably be treated |
| 270 | 280 | as constants. New predefined values are likely to be added in future |
| 271 | 281 | releases of Fossil. |
| 272 | 282 | |
| 273 | -Suggested Skin Customization Procedure | |
| --------------------------------------- | ||
| 283 | + | |
| 284 | +## <a name="procedure"></a>Suggested Skin Customization Procedure | |
| 274 | 285 | |
| 275 | 286 | Developers are free, of course, to develop new skins using any method they |
| 276 | 287 | want, but the following is a technique that has worked well in the past and |
| 277 | 288 | can serve as a starting point for future work: |
| 278 | 289 | |
| @@ -302,9 +312,9 @@ | ||
| 302 | 312 | 4. Copy/paste the resulting css.txt, details.txt, |
| 303 | 313 | header.txt, and footer.txt files |
| 304 | 314 | into the CSS, details, header, and footer configuration screens |
| 305 | 315 | under the Admin/Skins menu. |
| 306 | 316 | |
| 307 | -See Also | |
| --------- | ||
| 317 | + | |
| 318 | +## See Also | |
| 308 | 319 | |
| 309 | 320 | * [Customizing the Timeline Graph](customgraph.md) |
| 310 | 321 | |
| 311 | 322 | ADDED www/defcsp.md |
| --- www/customskin.md | |
| +++ www/customskin.md | |
| @@ -1,7 +1,6 @@ | |
| 1 | Theming |
| 2 | ======= |
| 3 | |
| 4 | Every HTML page generated by Fossil has the following basic structure: |
| 5 | |
| 6 | <blockquote><table border=1 cellpadding=10><tbody> |
| 7 | <tr><td style='background-color:lightblue;text-align:center;'>Header</td></tr> |
| @@ -9,43 +8,54 @@ | |
| 9 | Fossil-Generated Content</td></tr> |
| 10 | <tr><td style='background-color:lightblue;text-align:center;'>Footer</td></tr> |
| 11 | <tr><td style='background-color:lightyellow;text-align:center;'>Javascript (optional)</td></tr> |
| 12 | </tbody></table></blockquote> |
| 13 | |
| 14 | The header and footer control the "look" of Fossil pages. Those |
| 15 | two sections can be customized separately for each repository to |
| 16 | develop a new theme. |
| 17 | |
| 18 | The header will normally look something like this: |
| 19 | |
| 20 | <html> |
| 21 | <head> ... </head> |
| 22 | <body> |
| 23 | ... top banner and menu bar ... |
| 24 | <div class='content'> |
| 25 | |
| 26 | And the footer will look something like this: |
| 27 | |
| 28 | </div> |
| 29 | ... bottom material ... |
| 30 | </body> |
| 31 | </html> |
| 32 | |
| 33 | The <head> element in the header will normally reference the |
| 34 | /style.css CSS file that Fossil stores internally. (The $stylesheet_url |
| 35 | TH1 variable, described below, is useful for accomplishing this.) |
| 36 | |
| 37 | The middle "content" section comprised the bulk of most pages and |
| 38 | contains the actual Fossil-generated data |
| 39 | that the user is interested in seeing. The text of this content |
| 40 | section is not normally configurable. The content text can be styled |
| 41 | using CSS, but it otherwise fixed. Hence it is the header and footer |
| 42 | and the CSS that determine the look of a repository. |
| 43 | We call the bundle of built-in CSS, header, and footer a "skin". |
| 44 | |
| 45 | Built-in Skins |
| --------------- | |
| 46 | |
| 47 | Fossil comes with several built-in skins. The sources to these built-ins can |
| 48 | be found in the Fossil source tree under the skins/ folder. The skins/ |
| 49 | folder contains a separate subfolder for each built-in skin, with each |
| 50 | subfolders holding four files, "css.txt", "details.txt", |
| @@ -59,12 +69,12 @@ | |
| 59 | line option can be used for the |
| 60 | [fossil ui](../../../help?cmd=ui) or |
| 61 | [fossil server](../../../help?cmd=server) commands to force that particular |
| 62 | instance of Fossil to use the specified built-in skin. |
| 63 | |
| 64 | Sharing Skins |
| -------------- | |
| 65 | |
| 66 | The skin of a repository is not part of the versioned state and does not |
| 67 | "push" or "pull" like checked-in files. The skin is local to the |
| 68 | repository. However, skins can be shared between repositories using |
| 69 | the [fossil config](../../../help?cmd=configuration) command. |
| @@ -88,58 +98,51 @@ | |
| 88 | necessary. |
| 89 | |
| 90 | When cloning a repository, the skin of new repository is initialized to |
| 91 | the skin of the repository from which it was cloned. |
| 92 | |
| 93 | Header And Footer Processing |
| ----------------------------- | |
| 94 | |
| 95 | The header.txt and footer.txt files of a skin are merely the HTML text |
| 96 | of the header and footer. Except, before being prepended and appended to |
| 97 | the content, the header and footer text are run through a |
| 98 | [TH1 interpreter](./th1.md) that might adjust the text as follows: |
| 99 | |
| 100 | * All text within <th1>...</th1> is elided from the |
| 101 | output and that text is instead run as a TH1 script. That TH1 |
| 102 | script has the opportunity to insert new text in place of itself, |
| 103 | or to inhibit or enable the output of subsequent text. |
| 104 | |
| 105 | * Text for the form "$NAME" or "$<NAME>" is replace with |
| 106 | the value of the TH1 variable NAME. |
| 107 | |
| 108 | For example, the following is the first few lines of a typical |
| 109 | header file: |
| 110 | |
| 111 | <html> |
| 112 | <head> |
| 113 | <base href="$baseurl/$current_page" /> |
| 114 | <title>$<project_name>: $<title></title> |
| 115 | <link rel="alternate" type="application/rss+xml" title="RSS Feed" |
| 116 | href="$home/timeline.rss" /> |
| 117 | <link rel="stylesheet" href="$stylesheet_url" type="text/css" |
| 118 | media="screen" /> |
| 119 | </head> |
| 120 | |
| 121 | After variables are substituted by TH1, the final header text |
| 122 | delivered to the web browser might look something like this: |
| 123 | |
| 124 | <html> |
| 125 | <head> |
| 126 | <base href="https://www.fossil-scm.org/skin2/timeline" /> |
| 127 | <title>Fossil: Timeline</title> |
| 128 | <link rel="alternate" type="application/rss+xml" title="RSS Feed" |
| 129 | href="/skin2/timeline.rss" /> |
| 130 | <link rel="stylesheet" href="/skin2/style.css?default" type="text/css" |
| 131 | media="screen" /> |
| 132 | </head> |
| 133 | |
| 134 | The same TH1 interpreter is used for both the header and the footer |
| 135 | and for all scripts contained within them both. Hence, any global |
| 136 | TH1 variables that are set by the header are available to the footer. |
| 137 | |
| 138 | Customizing the ≡ Hamburger Menu |
| --------------------------------- | |
| 139 | |
| 140 | The menu bar of the default skin has an entry to open a drop-down menu with |
| 141 | additional navigation links, represented by the ≡ button (hence the name |
| 142 | "hamburger menu"). The Javascript logic to open and close the hamburger menu |
| 143 | when the button is clicked is contained in the optional Javascript part (js.txt) |
| @@ -193,12 +196,12 @@ | |
| 193 | The custom `data-anim-ms` attribute can be added to the panel element to direct |
| 194 | the Javascript logic to override the default menu animation duration of 400 ms. |
| 195 | A faster animation duration of 80-200 ms may be preferred for smaller menus. The |
| 196 | animation is disabled by setting the attribute to `"0"`. |
| 197 | |
| 198 | TH1 Variables |
| -------------- | |
| 199 | |
| 200 | Before expanding the TH1 within the header and footer, Fossil first |
| 201 | initializes a number of TH1 variables to values that depend on |
| 202 | repository settings and the specific page being generated. |
| 203 | |
| @@ -235,11 +238,18 @@ | |
| 235 | Examples: "timeline", "doc/trunk/README.txt", "wiki". |
| 236 | |
| 237 | * **csrf_token** - A token used to prevent cross-site request forgery. |
| 238 | |
| 239 | * **default_csp** - The content to be used within the default header |
| 240 | for the "Content-Security-Policy" meta tag. |
| 241 | |
| 242 | * **nonce** - The value of the cryptographic nonce for the request |
| 243 | being processed. |
| 244 | |
| 245 | * **release_version** - The release version of Fossil. Ex: "1.31" |
| @@ -268,12 +278,12 @@ | |
| 268 | All of the above are variables in the sense that either the header or the |
| 269 | footer is free to change or erase them. But they should probably be treated |
| 270 | as constants. New predefined values are likely to be added in future |
| 271 | releases of Fossil. |
| 272 | |
| 273 | Suggested Skin Customization Procedure |
| --------------------------------------- | |
| 274 | |
| 275 | Developers are free, of course, to develop new skins using any method they |
| 276 | want, but the following is a technique that has worked well in the past and |
| 277 | can serve as a starting point for future work: |
| 278 | |
| @@ -302,9 +312,9 @@ | |
| 302 | 4. Copy/paste the resulting css.txt, details.txt, |
| 303 | header.txt, and footer.txt files |
| 304 | into the CSS, details, header, and footer configuration screens |
| 305 | under the Admin/Skins menu. |
| 306 | |
| 307 | See Also |
| --------- | |
| 308 | |
| 309 | * [Customizing the Timeline Graph](customgraph.md) |
| 310 | |
| 311 | DDED www/defcsp.md |
| --- www/customskin.md | |
| +++ www/customskin.md | |
| @@ -1,7 +1,6 @@ | |
| 1 | # Skinning the Fossil Web Interface |
| 2 | |
| 3 | Every HTML page generated by Fossil has the following basic structure: |
| 4 | |
| 5 | <blockquote><table border=1 cellpadding=10><tbody> |
| 6 | <tr><td style='background-color:lightblue;text-align:center;'>Header</td></tr> |
| @@ -9,43 +8,54 @@ | |
| 8 | Fossil-Generated Content</td></tr> |
| 9 | <tr><td style='background-color:lightblue;text-align:center;'>Footer</td></tr> |
| 10 | <tr><td style='background-color:lightyellow;text-align:center;'>Javascript (optional)</td></tr> |
| 11 | </tbody></table></blockquote> |
| 12 | |
| 13 | The default header looks something like this: |
| 14 | |
| 15 | <div class="header"> |
| 16 | <div class="title"><h1>$<project_name></h1>$<title></div> |
| 17 | ... top banner and menu bar ... |
| 18 | |
| 19 | The Fossil-generated content section looks like this: |
| 20 | |
| 21 | <div class="content"> |
| 22 | ... generated content here ... |
| 23 | </div> |
| 24 | |
| 25 | And the footer looks like this: |
| 26 | |
| 27 | <div class="footer"> |
| 28 | ... skin-specific stuff here ... |
| 29 | </div> |
| 30 | <script nonce=$nonce> |
| 31 | <th1>styleScript</th1> |
| 32 | </script> |
| 33 | |
| 34 | Notice that there are no `<html>` or `<head>` elements in the header, |
| 35 | nor is there an `</html>` closing tag in the footer. Fossil generates |
| 36 | this material automatically unless it sees that you have provided your |
| 37 | own HTML document header within the skin’s Header section. |
| 38 | |
| 39 | This design lets most users get the benefit of Fossil’s automatic HTML |
| 40 | document header, which takes care of quite a few different things for |
| 41 | you, while still allowing you to [override if at need](#headfoot). |
| 42 | |
| 43 | When overriding the default document header, you might want to use some |
| 44 | of the [TH1 variables documented below](#vars) such as `$stylesheet_url` |
| 45 | to avoid hand-writing code that Fossil can generate for you. |
| 46 | |
| 47 | The middle "content" section comprises the bulk of most pages and |
| 48 | contains the actual Fossil-generated data |
| 49 | that the user is interested in seeing. The text of this content |
| 50 | section is not normally configurable. The content text can be styled |
| 51 | using CSS, but it is otherwise fixed. Hence it is the header, the footer, |
| 52 | and the CSS that determine the look of a repository. |
| 53 | We call the bundle of built-in CSS, header, and footer a "skin". |
| 54 | |
| --------------- | |
| 55 | |
| 56 | ## <a name="builtin"></a>Built-in Skins |
| 57 | |
| 58 | Fossil comes with several built-in skins. The sources to these built-ins can |
| 59 | be found in the Fossil source tree under the skins/ folder. The skins/ |
| 60 | folder contains a separate subfolder for each built-in skin, with each |
| 61 | subfolders holding four files, "css.txt", "details.txt", |
| @@ -59,12 +69,12 @@ | |
| 69 | line option can be used for the |
| 70 | [fossil ui](../../../help?cmd=ui) or |
| 71 | [fossil server](../../../help?cmd=server) commands to force that particular |
| 72 | instance of Fossil to use the specified built-in skin. |
| 73 | |
| -------------- | |
| 74 | |
| 75 | ## <a name="sharing"></a>Sharing Skins |
| 76 | |
| 77 | The skin of a repository is not part of the versioned state and does not |
| 78 | "push" or "pull" like checked-in files. The skin is local to the |
| 79 | repository. However, skins can be shared between repositories using |
| 80 | the [fossil config](../../../help?cmd=configuration) command. |
| @@ -88,58 +98,51 @@ | |
| 98 | necessary. |
| 99 | |
| 100 | When cloning a repository, the skin of new repository is initialized to |
| 101 | the skin of the repository from which it was cloned. |
| 102 | |
| ----------------------------- | |
| 103 | |
| 104 | ## <a name="headfoot"></a>Header and Footer Processing |
| 105 | |
| 106 | The `header.txt` and `footer.txt` files of a skin are merely the HTML text |
| 107 | of the header and footer, except that before being prepended and appended to |
| 108 | the content, their text content is run through a |
| 109 | [TH1 interpreter](./th1.md) that might adjust the text as follows: |
| 110 | |
| 111 | * All text within <th1>...</th1> is elided from the |
| 112 | output and that text is instead run as a TH1 script. That TH1 |
| 113 | script has the opportunity to insert new text in place of itself, |
| 114 | or to inhibit or enable the output of subsequent text. |
| 115 | |
| 116 | * Text of the form "$NAME" or "$<NAME>" is replaced with |
| 117 | the value of the TH1 variable NAME. |
| 118 | |
| 119 | Above, we saw the first few lines of a typical Fossil skin header: |
| 120 | |
| 121 | <div class="header"> |
| 122 | <div class="title"><h1>$<project_name></h1>$<title>/div> |
| 123 | |
| 124 | After variables are substituted by TH1, that will look more like this: |
| 125 | |
| 126 | <div class="header"> |
| 127 | <div class="title"><h1>Project Name</h1>Page Title</div> |
| 128 | |
| 129 | As you can see, two TH1 variable substitutions were done. |
| 130 | |
| 131 | The same TH1 interpreter is used for both the header and the footer |
| 132 | and for all scripts contained within them both. Hence, any global |
| 133 | TH1 variables that are set by the header are available to the footer. |
| 134 | |
| --------------------------------- | |
| 135 | Fossil provides the HTML |
| 136 | document container tags `<html>`, `<head>`, and their inner content when |
| 137 | your skin’s header and footer don’t include them. This default header |
| 138 | declares the repository’s Content Security Policy (CSP) which is well |
| 139 | worth understanding, but since it is not strictly about skinning, we |
| 140 | cover that in [a separate document](./defcsp.md). |
| 141 | |
| 142 | |
| 143 | ## <a name="menu"></a>Customizing the ≡ Hamburger Menu |
| 144 | |
| 145 | The menu bar of the default skin has an entry to open a drop-down menu with |
| 146 | additional navigation links, represented by the ≡ button (hence the name |
| 147 | "hamburger menu"). The Javascript logic to open and close the hamburger menu |
| 148 | when the button is clicked is contained in the optional Javascript part (js.txt) |
| @@ -193,12 +196,12 @@ | |
| 196 | The custom `data-anim-ms` attribute can be added to the panel element to direct |
| 197 | the Javascript logic to override the default menu animation duration of 400 ms. |
| 198 | A faster animation duration of 80-200 ms may be preferred for smaller menus. The |
| 199 | animation is disabled by setting the attribute to `"0"`. |
| 200 | |
| -------------- | |
| 201 | |
| 202 | ## <a name="vars"></a>TH1 Variables |
| 203 | |
| 204 | Before expanding the TH1 within the header and footer, Fossil first |
| 205 | initializes a number of TH1 variables to values that depend on |
| 206 | repository settings and the specific page being generated. |
| 207 | |
| @@ -235,11 +238,18 @@ | |
| 238 | Examples: "timeline", "doc/trunk/README.txt", "wiki". |
| 239 | |
| 240 | * **csrf_token** - A token used to prevent cross-site request forgery. |
| 241 | |
| 242 | * **default_csp** - The content to be used within the default header |
| 243 | for the "Content-Security-Policy" `<meta>` tag. You can use |
| 244 | [Fossil’s default CSP](./defcsp.md) from this variable in your |
| 245 | [own custom `<head>`](#headfoot). Alternately, you can override |
| 246 | the default CSP from the [`th1-setup` script](./th1-hooks.md), |
| 247 | which runs before TH1 processing happens during skin processing, |
| 248 | allowing you to set a custom CSP without recompiling Fossil or |
| 249 | providing a hand-written `<head>` section in the Header section |
| 250 | of a custom skin. |
| 251 | |
| 252 | * **nonce** - The value of the cryptographic nonce for the request |
| 253 | being processed. |
| 254 | |
| 255 | * **release_version** - The release version of Fossil. Ex: "1.31" |
| @@ -268,12 +278,12 @@ | |
| 278 | All of the above are variables in the sense that either the header or the |
| 279 | footer is free to change or erase them. But they should probably be treated |
| 280 | as constants. New predefined values are likely to be added in future |
| 281 | releases of Fossil. |
| 282 | |
| --------------------------------------- | |
| 283 | |
| 284 | ## <a name="procedure"></a>Suggested Skin Customization Procedure |
| 285 | |
| 286 | Developers are free, of course, to develop new skins using any method they |
| 287 | want, but the following is a technique that has worked well in the past and |
| 288 | can serve as a starting point for future work: |
| 289 | |
| @@ -302,9 +312,9 @@ | |
| 312 | 4. Copy/paste the resulting css.txt, details.txt, |
| 313 | header.txt, and footer.txt files |
| 314 | into the CSS, details, header, and footer configuration screens |
| 315 | under the Admin/Skins menu. |
| 316 | |
| --------- | |
| 317 | |
| 318 | ## See Also |
| 319 | |
| 320 | * [Customizing the Timeline Graph](customgraph.md) |
| 321 | |
| 322 | DDED www/defcsp.md |
+11
| --- a/www/defcsp.md | ||
| +++ b/www/defcsp.md | ||
| @@ -0,0 +1,11 @@ | ||
| 1 | +javas=` attribute One of the most important things you have to know about the default | |
| 2 | +[Fossil-provided `<head>` textheadfoot) is the | |
| 3 | +[ute the | |
| 4 | +matches the %s ][csp] (CSP) it applies to your repository’s web | |
| 5 | +interface. The current version applies the f | |
| 6 | + | |
| 7 | + | |
| 8 | +##Lm@NC,6E@iJ,H:(./customskin.md)9w@oa,Bl@ys,2k@1x5,3: | |
| 9 | + | |
| 10 | + | |
| 11 | +1DQXgn; |
| --- a/www/defcsp.md | |
| +++ b/www/defcsp.md | |
| @@ -0,0 +1,11 @@ | |
| --- a/www/defcsp.md | |
| +++ b/www/defcsp.md | |
| @@ -0,0 +1,11 @@ | |
| 1 | javas=` attribute One of the most important things you have to know about the default |
| 2 | [Fossil-provided `<head>` textheadfoot) is the |
| 3 | [ute the |
| 4 | matches the %s ][csp] (CSP) it applies to your repository’s web |
| 5 | interface. The current version applies the f |
| 6 | |
| 7 | |
| 8 | ##Lm@NC,6E@iJ,H:(./customskin.md)9w@oa,Bl@ys,2k@1x5,3: |
| 9 | |
| 10 | |
| 11 | 1DQXgn; |
+1
-1
| --- a/www/defcsp.md | ||
| +++ b/www/defcsp.md | ||
| @@ -8,4 +8,4 @@ | ||
| 8 | 8 | ##Lm@NC,6E@iJ,H:(./customskin.md)9w@oa,Bl@ys,2k@1x5,3: |
| 9 | 9 | |
| 10 | 10 | |
| 11 | -1DQXgn;.wiki | |
| 11 | +1DQXgn; |
| --- a/www/defcsp.md | |
| +++ b/www/defcsp.md | |
| @@ -8,4 +8,4 @@ | |
| 8 | ##Lm@NC,6E@iJ,H:(./customskin.md)9w@oa,Bl@ys,2k@1x5,3: |
| 9 | |
| 10 | |
| 11 | 1DQXgn;.wiki |
| --- a/www/defcsp.md | |
| +++ b/www/defcsp.md | |
| @@ -8,4 +8,4 @@ | |
| 8 | ##Lm@NC,6E@iJ,H:(./customskin.md)9w@oa,Bl@ys,2k@1x5,3: |
| 9 | |
| 10 | |
| 11 | 1DQXgn; |
+8
| --- www/embeddeddoc.wiki | ||
| +++ www/embeddeddoc.wiki | ||
| @@ -93,10 +93,18 @@ | ||
| 93 | 93 | required for this to occur. The "data-title='...'" attribute is |
| 94 | 94 | optional, but if it is present the text will become the title displayed |
| 95 | 95 | in the Fossil header. An example of this can be seen in the text |
| 96 | 96 | of the [/artifact/84b4b3d041d93a?txt=1 | Index Of Fossil Documentation] |
| 97 | 97 | document. |
| 98 | + | |
| 99 | +Beware that such HTML files render in the same security context as all | |
| 100 | +other embedded documentation served from Fossil; they are not | |
| 101 | +fully-independent web pages. One practical consequence of this is that | |
| 102 | +embedded <tt><script></tt> tags will cause a | |
| 103 | +[https://developer.mozilla.org/en-US/docs/Web/HTTP/CSP | Content | |
| 104 | +Security Policy] error in your browser with the default CSP as served by | |
| 105 | +Fossil. | |
| 98 | 106 | |
| 99 | 107 | |
| 100 | 108 | <h2>Server-Side Text Substitution</h2> |
| 101 | 109 | |
| 102 | 110 | Fossil can do a few types of substitution of server-side information |
| 103 | 111 |
| --- www/embeddeddoc.wiki | |
| +++ www/embeddeddoc.wiki | |
| @@ -93,10 +93,18 @@ | |
| 93 | required for this to occur. The "data-title='...'" attribute is |
| 94 | optional, but if it is present the text will become the title displayed |
| 95 | in the Fossil header. An example of this can be seen in the text |
| 96 | of the [/artifact/84b4b3d041d93a?txt=1 | Index Of Fossil Documentation] |
| 97 | document. |
| 98 | |
| 99 | |
| 100 | <h2>Server-Side Text Substitution</h2> |
| 101 | |
| 102 | Fossil can do a few types of substitution of server-side information |
| 103 |
| --- www/embeddeddoc.wiki | |
| +++ www/embeddeddoc.wiki | |
| @@ -93,10 +93,18 @@ | |
| 93 | required for this to occur. The "data-title='...'" attribute is |
| 94 | optional, but if it is present the text will become the title displayed |
| 95 | in the Fossil header. An example of this can be seen in the text |
| 96 | of the [/artifact/84b4b3d041d93a?txt=1 | Index Of Fossil Documentation] |
| 97 | document. |
| 98 | |
| 99 | Beware that such HTML files render in the same security context as all |
| 100 | other embedded documentation served from Fossil; they are not |
| 101 | fully-independent web pages. One practical consequence of this is that |
| 102 | embedded <tt><script></tt> tags will cause a |
| 103 | [https://developer.mozilla.org/en-US/docs/Web/HTTP/CSP | Content |
| 104 | Security Policy] error in your browser with the default CSP as served by |
| 105 | Fossil. |
| 106 | |
| 107 | |
| 108 | <h2>Server-Side Text Substitution</h2> |
| 109 | |
| 110 | Fossil can do a few types of substitution of server-side information |
| 111 |
+8
| --- www/embeddeddoc.wiki | ||
| +++ www/embeddeddoc.wiki | ||
| @@ -93,10 +93,18 @@ | ||
| 93 | 93 | required for this to occur. The "data-title='...'" attribute is |
| 94 | 94 | optional, but if it is present the text will become the title displayed |
| 95 | 95 | in the Fossil header. An example of this can be seen in the text |
| 96 | 96 | of the [/artifact/84b4b3d041d93a?txt=1 | Index Of Fossil Documentation] |
| 97 | 97 | document. |
| 98 | + | |
| 99 | +Beware that such HTML files render in the same security context as all | |
| 100 | +other embedded documentation served from Fossil; they are not | |
| 101 | +fully-independent web pages. One practical consequence of this is that | |
| 102 | +embedded <tt><script></tt> tags will cause a | |
| 103 | +[https://developer.mozilla.org/en-US/docs/Web/HTTP/CSP | Content | |
| 104 | +Security Policy] error in your browser with the default CSP as served by | |
| 105 | +Fossil. | |
| 98 | 106 | |
| 99 | 107 | |
| 100 | 108 | <h2>Server-Side Text Substitution</h2> |
| 101 | 109 | |
| 102 | 110 | Fossil can do a few types of substitution of server-side information |
| 103 | 111 |
| --- www/embeddeddoc.wiki | |
| +++ www/embeddeddoc.wiki | |
| @@ -93,10 +93,18 @@ | |
| 93 | required for this to occur. The "data-title='...'" attribute is |
| 94 | optional, but if it is present the text will become the title displayed |
| 95 | in the Fossil header. An example of this can be seen in the text |
| 96 | of the [/artifact/84b4b3d041d93a?txt=1 | Index Of Fossil Documentation] |
| 97 | document. |
| 98 | |
| 99 | |
| 100 | <h2>Server-Side Text Substitution</h2> |
| 101 | |
| 102 | Fossil can do a few types of substitution of server-side information |
| 103 |
| --- www/embeddeddoc.wiki | |
| +++ www/embeddeddoc.wiki | |
| @@ -93,10 +93,18 @@ | |
| 93 | required for this to occur. The "data-title='...'" attribute is |
| 94 | optional, but if it is present the text will become the title displayed |
| 95 | in the Fossil header. An example of this can be seen in the text |
| 96 | of the [/artifact/84b4b3d041d93a?txt=1 | Index Of Fossil Documentation] |
| 97 | document. |
| 98 | |
| 99 | Beware that such HTML files render in the same security context as all |
| 100 | other embedded documentation served from Fossil; they are not |
| 101 | fully-independent web pages. One practical consequence of this is that |
| 102 | embedded <tt><script></tt> tags will cause a |
| 103 | [https://developer.mozilla.org/en-US/docs/Web/HTTP/CSP | Content |
| 104 | Security Policy] error in your browser with the default CSP as served by |
| 105 | Fossil. |
| 106 | |
| 107 | |
| 108 | <h2>Server-Side Text Substitution</h2> |
| 109 | |
| 110 | Fossil can do a few types of substitution of server-side information |
| 111 |
+7
-4
| --- www/fossil-v-git.wiki | ||
| +++ www/fossil-v-git.wiki | ||
| @@ -470,11 +470,11 @@ | ||
| 470 | 470 | get paid more by mastering arcane features of my DVCS?" Unless you have |
| 471 | 471 | a good answer to that, you probably do not want to be choosing a DVCS |
| 472 | 472 | based on how many arcane features it has. |
| 473 | 473 | |
| 474 | 474 | The argument is similar for other types of users: if you are a hobbyist, |
| 475 | -how much time do you want to spend mastering your DVCSs instead of on | |
| 475 | +how much time do you want to spend mastering your DVCS instead of on | |
| 476 | 476 | the hobby supported by use of that DVCS? |
| 477 | 477 | |
| 478 | 478 | There is some minimal set of features required to achieve the purposes |
| 479 | 479 | that drive our selection of a DVCS, but there is a level beyond which |
| 480 | 480 | more features only slow us down while we're learning the tool, since we |
| @@ -603,14 +603,17 @@ | ||
| 603 | 603 | [https://en.wikipedia.org/wiki/SHA-3|256-bit SHA-3] with |
| 604 | 604 | [./hashpolicy.wiki|full backwards compatibility] to old SHA-1 based |
| 605 | 605 | repositories. |
| 606 | 606 | |
| 607 | 607 | Here in mid-2019, that feature is now in every OS and package repository |
| 608 | -known to include Fossil so that the next release as of this writing | |
| 609 | -(Fossil 2.10) will default to enforcing SHA-3 hashes by default. This | |
| 608 | +known to include Fossil so that the next release | |
| 609 | +(Fossil 2.10) will begin using SHA-3 hashes even on repos currently | |
| 610 | +limited to SHA-1 for compatibility with Fossil 1.<i>x</i>, | |
| 611 | +effectively upgrading them to require Fossil 2.1 or newer. This | |
| 610 | 612 | not only solves the SHAttered problem, it should prevent a reoccurrence |
| 611 | -for the foreseeable future. Only repositories created before the | |
| 613 | +for the foreseeable future. With the current release (Fossil 2.9) only | |
| 614 | +repositories created before the | |
| 612 | 615 | transition to Fossil 2 are still using SHA-1, and then only if the |
| 613 | 616 | repository's maintainer chose not to switch them into SHA-3 mode some |
| 614 | 617 | time over the past 2 years. |
| 615 | 618 | |
| 616 | 619 | Meanwhile, the Git community took until August 2018 to announce |
| 617 | 620 |
| --- www/fossil-v-git.wiki | |
| +++ www/fossil-v-git.wiki | |
| @@ -470,11 +470,11 @@ | |
| 470 | get paid more by mastering arcane features of my DVCS?" Unless you have |
| 471 | a good answer to that, you probably do not want to be choosing a DVCS |
| 472 | based on how many arcane features it has. |
| 473 | |
| 474 | The argument is similar for other types of users: if you are a hobbyist, |
| 475 | how much time do you want to spend mastering your DVCSs instead of on |
| 476 | the hobby supported by use of that DVCS? |
| 477 | |
| 478 | There is some minimal set of features required to achieve the purposes |
| 479 | that drive our selection of a DVCS, but there is a level beyond which |
| 480 | more features only slow us down while we're learning the tool, since we |
| @@ -603,14 +603,17 @@ | |
| 603 | [https://en.wikipedia.org/wiki/SHA-3|256-bit SHA-3] with |
| 604 | [./hashpolicy.wiki|full backwards compatibility] to old SHA-1 based |
| 605 | repositories. |
| 606 | |
| 607 | Here in mid-2019, that feature is now in every OS and package repository |
| 608 | known to include Fossil so that the next release as of this writing |
| 609 | (Fossil 2.10) will default to enforcing SHA-3 hashes by default. This |
| 610 | not only solves the SHAttered problem, it should prevent a reoccurrence |
| 611 | for the foreseeable future. Only repositories created before the |
| 612 | transition to Fossil 2 are still using SHA-1, and then only if the |
| 613 | repository's maintainer chose not to switch them into SHA-3 mode some |
| 614 | time over the past 2 years. |
| 615 | |
| 616 | Meanwhile, the Git community took until August 2018 to announce |
| 617 |
| --- www/fossil-v-git.wiki | |
| +++ www/fossil-v-git.wiki | |
| @@ -470,11 +470,11 @@ | |
| 470 | get paid more by mastering arcane features of my DVCS?" Unless you have |
| 471 | a good answer to that, you probably do not want to be choosing a DVCS |
| 472 | based on how many arcane features it has. |
| 473 | |
| 474 | The argument is similar for other types of users: if you are a hobbyist, |
| 475 | how much time do you want to spend mastering your DVCS instead of on |
| 476 | the hobby supported by use of that DVCS? |
| 477 | |
| 478 | There is some minimal set of features required to achieve the purposes |
| 479 | that drive our selection of a DVCS, but there is a level beyond which |
| 480 | more features only slow us down while we're learning the tool, since we |
| @@ -603,14 +603,17 @@ | |
| 603 | [https://en.wikipedia.org/wiki/SHA-3|256-bit SHA-3] with |
| 604 | [./hashpolicy.wiki|full backwards compatibility] to old SHA-1 based |
| 605 | repositories. |
| 606 | |
| 607 | Here in mid-2019, that feature is now in every OS and package repository |
| 608 | known to include Fossil so that the next release |
| 609 | (Fossil 2.10) will begin using SHA-3 hashes even on repos currently |
| 610 | limited to SHA-1 for compatibility with Fossil 1.<i>x</i>, |
| 611 | effectively upgrading them to require Fossil 2.1 or newer. This |
| 612 | not only solves the SHAttered problem, it should prevent a reoccurrence |
| 613 | for the foreseeable future. With the current release (Fossil 2.9) only |
| 614 | repositories created before the |
| 615 | transition to Fossil 2 are still using SHA-1, and then only if the |
| 616 | repository's maintainer chose not to switch them into SHA-3 mode some |
| 617 | time over the past 2 years. |
| 618 | |
| 619 | Meanwhile, the Git community took until August 2018 to announce |
| 620 |
+7
-4
| --- www/fossil-v-git.wiki | ||
| +++ www/fossil-v-git.wiki | ||
| @@ -470,11 +470,11 @@ | ||
| 470 | 470 | get paid more by mastering arcane features of my DVCS?" Unless you have |
| 471 | 471 | a good answer to that, you probably do not want to be choosing a DVCS |
| 472 | 472 | based on how many arcane features it has. |
| 473 | 473 | |
| 474 | 474 | The argument is similar for other types of users: if you are a hobbyist, |
| 475 | -how much time do you want to spend mastering your DVCSs instead of on | |
| 475 | +how much time do you want to spend mastering your DVCS instead of on | |
| 476 | 476 | the hobby supported by use of that DVCS? |
| 477 | 477 | |
| 478 | 478 | There is some minimal set of features required to achieve the purposes |
| 479 | 479 | that drive our selection of a DVCS, but there is a level beyond which |
| 480 | 480 | more features only slow us down while we're learning the tool, since we |
| @@ -603,14 +603,17 @@ | ||
| 603 | 603 | [https://en.wikipedia.org/wiki/SHA-3|256-bit SHA-3] with |
| 604 | 604 | [./hashpolicy.wiki|full backwards compatibility] to old SHA-1 based |
| 605 | 605 | repositories. |
| 606 | 606 | |
| 607 | 607 | Here in mid-2019, that feature is now in every OS and package repository |
| 608 | -known to include Fossil so that the next release as of this writing | |
| 609 | -(Fossil 2.10) will default to enforcing SHA-3 hashes by default. This | |
| 608 | +known to include Fossil so that the next release | |
| 609 | +(Fossil 2.10) will begin using SHA-3 hashes even on repos currently | |
| 610 | +limited to SHA-1 for compatibility with Fossil 1.<i>x</i>, | |
| 611 | +effectively upgrading them to require Fossil 2.1 or newer. This | |
| 610 | 612 | not only solves the SHAttered problem, it should prevent a reoccurrence |
| 611 | -for the foreseeable future. Only repositories created before the | |
| 613 | +for the foreseeable future. With the current release (Fossil 2.9) only | |
| 614 | +repositories created before the | |
| 612 | 615 | transition to Fossil 2 are still using SHA-1, and then only if the |
| 613 | 616 | repository's maintainer chose not to switch them into SHA-3 mode some |
| 614 | 617 | time over the past 2 years. |
| 615 | 618 | |
| 616 | 619 | Meanwhile, the Git community took until August 2018 to announce |
| 617 | 620 |
| --- www/fossil-v-git.wiki | |
| +++ www/fossil-v-git.wiki | |
| @@ -470,11 +470,11 @@ | |
| 470 | get paid more by mastering arcane features of my DVCS?" Unless you have |
| 471 | a good answer to that, you probably do not want to be choosing a DVCS |
| 472 | based on how many arcane features it has. |
| 473 | |
| 474 | The argument is similar for other types of users: if you are a hobbyist, |
| 475 | how much time do you want to spend mastering your DVCSs instead of on |
| 476 | the hobby supported by use of that DVCS? |
| 477 | |
| 478 | There is some minimal set of features required to achieve the purposes |
| 479 | that drive our selection of a DVCS, but there is a level beyond which |
| 480 | more features only slow us down while we're learning the tool, since we |
| @@ -603,14 +603,17 @@ | |
| 603 | [https://en.wikipedia.org/wiki/SHA-3|256-bit SHA-3] with |
| 604 | [./hashpolicy.wiki|full backwards compatibility] to old SHA-1 based |
| 605 | repositories. |
| 606 | |
| 607 | Here in mid-2019, that feature is now in every OS and package repository |
| 608 | known to include Fossil so that the next release as of this writing |
| 609 | (Fossil 2.10) will default to enforcing SHA-3 hashes by default. This |
| 610 | not only solves the SHAttered problem, it should prevent a reoccurrence |
| 611 | for the foreseeable future. Only repositories created before the |
| 612 | transition to Fossil 2 are still using SHA-1, and then only if the |
| 613 | repository's maintainer chose not to switch them into SHA-3 mode some |
| 614 | time over the past 2 years. |
| 615 | |
| 616 | Meanwhile, the Git community took until August 2018 to announce |
| 617 |
| --- www/fossil-v-git.wiki | |
| +++ www/fossil-v-git.wiki | |
| @@ -470,11 +470,11 @@ | |
| 470 | get paid more by mastering arcane features of my DVCS?" Unless you have |
| 471 | a good answer to that, you probably do not want to be choosing a DVCS |
| 472 | based on how many arcane features it has. |
| 473 | |
| 474 | The argument is similar for other types of users: if you are a hobbyist, |
| 475 | how much time do you want to spend mastering your DVCS instead of on |
| 476 | the hobby supported by use of that DVCS? |
| 477 | |
| 478 | There is some minimal set of features required to achieve the purposes |
| 479 | that drive our selection of a DVCS, but there is a level beyond which |
| 480 | more features only slow us down while we're learning the tool, since we |
| @@ -603,14 +603,17 @@ | |
| 603 | [https://en.wikipedia.org/wiki/SHA-3|256-bit SHA-3] with |
| 604 | [./hashpolicy.wiki|full backwards compatibility] to old SHA-1 based |
| 605 | repositories. |
| 606 | |
| 607 | Here in mid-2019, that feature is now in every OS and package repository |
| 608 | known to include Fossil so that the next release |
| 609 | (Fossil 2.10) will begin using SHA-3 hashes even on repos currently |
| 610 | limited to SHA-1 for compatibility with Fossil 1.<i>x</i>, |
| 611 | effectively upgrading them to require Fossil 2.1 or newer. This |
| 612 | not only solves the SHAttered problem, it should prevent a reoccurrence |
| 613 | for the foreseeable future. With the current release (Fossil 2.9) only |
| 614 | repositories created before the |
| 615 | transition to Fossil 2 are still using SHA-1, and then only if the |
| 616 | repository's maintainer chose not to switch them into SHA-3 mode some |
| 617 | time over the past 2 years. |
| 618 | |
| 619 | Meanwhile, the Git community took until August 2018 to announce |
| 620 |
+1
| --- www/mkindex.tcl | ||
| +++ www/mkindex.tcl | ||
| @@ -30,10 +30,11 @@ | ||
| 30 | 30 | contribute.wiki {Contributing Code or Documentation To The Fossil Project} |
| 31 | 31 | customgraph.md {Theming: Customizing the Timeline Graph} |
| 32 | 32 | customskin.md {Theming: Customizing The Appearance of Web Pages} |
| 33 | 33 | customskin.md {Custom Skins} |
| 34 | 34 | custom_ticket.wiki {Customizing The Ticket System} |
| 35 | + defcsp.md {The Default Content Security Policy} | |
| 35 | 36 | delta_encoder_algorithm.wiki {Fossil Delta Encoding Algorithm} |
| 36 | 37 | delta_format.wiki {Fossil Delta Format} |
| 37 | 38 | embeddeddoc.wiki {Embedded Project Documentation} |
| 38 | 39 | encryptedrepos.wiki {How To Use Encrypted Repositories} |
| 39 | 40 | env-opts.md {Environment Variables and Global Options} |
| 40 | 41 |
| --- www/mkindex.tcl | |
| +++ www/mkindex.tcl | |
| @@ -30,10 +30,11 @@ | |
| 30 | contribute.wiki {Contributing Code or Documentation To The Fossil Project} |
| 31 | customgraph.md {Theming: Customizing the Timeline Graph} |
| 32 | customskin.md {Theming: Customizing The Appearance of Web Pages} |
| 33 | customskin.md {Custom Skins} |
| 34 | custom_ticket.wiki {Customizing The Ticket System} |
| 35 | delta_encoder_algorithm.wiki {Fossil Delta Encoding Algorithm} |
| 36 | delta_format.wiki {Fossil Delta Format} |
| 37 | embeddeddoc.wiki {Embedded Project Documentation} |
| 38 | encryptedrepos.wiki {How To Use Encrypted Repositories} |
| 39 | env-opts.md {Environment Variables and Global Options} |
| 40 |
| --- www/mkindex.tcl | |
| +++ www/mkindex.tcl | |
| @@ -30,10 +30,11 @@ | |
| 30 | contribute.wiki {Contributing Code or Documentation To The Fossil Project} |
| 31 | customgraph.md {Theming: Customizing the Timeline Graph} |
| 32 | customskin.md {Theming: Customizing The Appearance of Web Pages} |
| 33 | customskin.md {Custom Skins} |
| 34 | custom_ticket.wiki {Customizing The Ticket System} |
| 35 | defcsp.md {The Default Content Security Policy} |
| 36 | delta_encoder_algorithm.wiki {Fossil Delta Encoding Algorithm} |
| 37 | delta_format.wiki {Fossil Delta Format} |
| 38 | embeddeddoc.wiki {Embedded Project Documentation} |
| 39 | encryptedrepos.wiki {How To Use Encrypted Repositories} |
| 40 | env-opts.md {Environment Variables and Global Options} |
| 41 |
+1
| --- www/mkindex.tcl | ||
| +++ www/mkindex.tcl | ||
| @@ -30,10 +30,11 @@ | ||
| 30 | 30 | contribute.wiki {Contributing Code or Documentation To The Fossil Project} |
| 31 | 31 | customgraph.md {Theming: Customizing the Timeline Graph} |
| 32 | 32 | customskin.md {Theming: Customizing The Appearance of Web Pages} |
| 33 | 33 | customskin.md {Custom Skins} |
| 34 | 34 | custom_ticket.wiki {Customizing The Ticket System} |
| 35 | + defcsp.md {The Default Content Security Policy} | |
| 35 | 36 | delta_encoder_algorithm.wiki {Fossil Delta Encoding Algorithm} |
| 36 | 37 | delta_format.wiki {Fossil Delta Format} |
| 37 | 38 | embeddeddoc.wiki {Embedded Project Documentation} |
| 38 | 39 | encryptedrepos.wiki {How To Use Encrypted Repositories} |
| 39 | 40 | env-opts.md {Environment Variables and Global Options} |
| 40 | 41 |
| --- www/mkindex.tcl | |
| +++ www/mkindex.tcl | |
| @@ -30,10 +30,11 @@ | |
| 30 | contribute.wiki {Contributing Code or Documentation To The Fossil Project} |
| 31 | customgraph.md {Theming: Customizing the Timeline Graph} |
| 32 | customskin.md {Theming: Customizing The Appearance of Web Pages} |
| 33 | customskin.md {Custom Skins} |
| 34 | custom_ticket.wiki {Customizing The Ticket System} |
| 35 | delta_encoder_algorithm.wiki {Fossil Delta Encoding Algorithm} |
| 36 | delta_format.wiki {Fossil Delta Format} |
| 37 | embeddeddoc.wiki {Embedded Project Documentation} |
| 38 | encryptedrepos.wiki {How To Use Encrypted Repositories} |
| 39 | env-opts.md {Environment Variables and Global Options} |
| 40 |
| --- www/mkindex.tcl | |
| +++ www/mkindex.tcl | |
| @@ -30,10 +30,11 @@ | |
| 30 | contribute.wiki {Contributing Code or Documentation To The Fossil Project} |
| 31 | customgraph.md {Theming: Customizing the Timeline Graph} |
| 32 | customskin.md {Theming: Customizing The Appearance of Web Pages} |
| 33 | customskin.md {Custom Skins} |
| 34 | custom_ticket.wiki {Customizing The Ticket System} |
| 35 | defcsp.md {The Default Content Security Policy} |
| 36 | delta_encoder_algorithm.wiki {Fossil Delta Encoding Algorithm} |
| 37 | delta_format.wiki {Fossil Delta Format} |
| 38 | embeddeddoc.wiki {Embedded Project Documentation} |
| 39 | encryptedrepos.wiki {How To Use Encrypted Repositories} |
| 40 | env-opts.md {Environment Variables and Global Options} |
| 41 |
| --- www/permutedindex.html | ||
| +++ www/permutedindex.html | ||
| @@ -65,10 +65,11 @@ | ||
| 65 | 65 | <li><a href="build.wiki"><b>Compiling and Installing Fossil</b></a></li> |
| 66 | 66 | <li><a href="concepts.wiki">Concepts — Fossil Core</a></li> |
| 67 | 67 | <li><a href="cgi.wiki">Configuration Options — CGI Script</a></li> |
| 68 | 68 | <li><a href="server/">Configure A Fossil Server — How To</a></li> |
| 69 | 69 | <li><a href="shunning.wiki">Content From Fossil — Shunning: Deleting</a></li> |
| 70 | +<li><a href="defcsp.md">Content Security Policy — The Default</a></li> | |
| 70 | 71 | <li><a href="contribute.wiki"><b>Contributing Code or Documentation To The Fossil Project</b></a></li> |
| 71 | 72 | <li><a href="copyright-release.html"><b>Contributor License Agreement</b></a></li> |
| 72 | 73 | <li><a href="whyusefossil.wiki">Control — Benefits Of Version</a></li> |
| 73 | 74 | <li><a href="concepts.wiki">Core Concepts — Fossil</a></li> |
| 74 | 75 | <li><a href="newrepo.wiki">Create A New Fossil Repository — How To</a></li> |
| @@ -77,10 +78,11 @@ | ||
| 77 | 78 | <li><a href="customskin.md"><b>Custom Skins</b></a></li> |
| 78 | 79 | <li><a href="customskin.md">Customizing The Appearance of Web Pages — Theming:</a></li> |
| 79 | 80 | <li><a href="custom_ticket.wiki"><b>Customizing The Ticket System</b></a></li> |
| 80 | 81 | <li><a href="customgraph.md">Customizing the Timeline Graph — Theming:</a></li> |
| 81 | 82 | <li><a href="tech_overview.wiki">Databases Used By Fossil — SQLite</a></li> |
| 83 | +<li><a href="defcsp.md">Default Content Security Policy — The</a></li> | |
| 82 | 84 | <li><a href="antibot.wiki"><b>Defense against Spiders and Bots</b></a></li> |
| 83 | 85 | <li><a href="shunning.wiki">Deleting Content From Fossil — Shunning:</a></li> |
| 84 | 86 | <li><a href="private.wiki">Deleting Private Branches — Creating, Syncing, and</a></li> |
| 85 | 87 | <li><a href="delta_encoder_algorithm.wiki">Delta Encoding Algorithm — Fossil</a></li> |
| 86 | 88 | <li><a href="delta_format.wiki">Delta Format — Fossil</a></li> |
| @@ -195,10 +197,11 @@ | ||
| 195 | 197 | <li><a href="customskin.md">Pages — Theming: Customizing The Appearance of Web</a></li> |
| 196 | 198 | <li><a href="password.wiki"><b>Password Management And Authentication</b></a></li> |
| 197 | 199 | <li><a href="globs.md">Patterns — File Name Glob</a></li> |
| 198 | 200 | <li><a href="quotes.wiki">People Are Saying About Fossil, Git, and DVCSes in General — Quotes: What</a></li> |
| 199 | 201 | <li><a href="stats.wiki"><b>Performance Statistics</b></a></li> |
| 202 | +<li><a href="defcsp.md">Policy — The Default Content Security</a></li> | |
| 200 | 203 | <li><a href="hashpolicy.wiki">Policy: Choosing Between SHA1 and SHA3-256 — Hash</a></li> |
| 201 | 204 | <li><a href="grep.md">POSIX grep — Fossil grep vs</a></li> |
| 202 | 205 | <li><a href="../test/release-checklist.wiki"><b>Pre-Release Testing Checklist</b></a></li> |
| 203 | 206 | <li><a href="pop.wiki"><b>Principles Of Operation</b></a></li> |
| 204 | 207 | <li><a href="private.wiki">Private Branches — Creating, Syncing, and Deleting</a></li> |
| @@ -226,10 +229,11 @@ | ||
| 226 | 229 | <li><a href="fiveminutes.wiki">Running in 5 Minutes as a Single User — Up and</a></li> |
| 227 | 230 | <li><a href="quotes.wiki">Saying About Fossil, Git, and DVCSes in General — Quotes: What People Are</a></li> |
| 228 | 231 | <li><a href="cgi.wiki">Script Configuration Options — CGI</a></li> |
| 229 | 232 | <li><a href="th1.md">Scripting Language — The TH1</a></li> |
| 230 | 233 | <li><a href="serverext.wiki">Scripts — Adding Extensions To A Fossil Server Using CGI</a></li> |
| 234 | +<li><a href="defcsp.md">Security Policy — The Default Content</a></li> | |
| 231 | 235 | <li><a href="selfcheck.wiki">Self Checks — Fossil Repository Integrity</a></li> |
| 232 | 236 | <li><a href="selfhost.wiki">Self Hosting Repositories — Fossil</a></li> |
| 233 | 237 | <li><a href="server/">Server — How To Configure A Fossil</a></li> |
| 234 | 238 | <li><a href="serverext.wiki">Server Extensions — CGI</a></li> |
| 235 | 239 | <li><a href="serverext.wiki">Server Using CGI Scripts — Adding Extensions To A Fossil</a></li> |
| @@ -258,10 +262,11 @@ | ||
| 258 | 262 | <li><a href="tech_overview.wiki">Technical Overview Of The Design And Implementation Of Fossil — A</a></li> |
| 259 | 263 | <li><a href="../test/release-checklist.wiki">Testing Checklist — Pre-Release</a></li> |
| 260 | 264 | <li><a href="th1.md">TH1 Scripting Language — The</a></li> |
| 261 | 265 | <li><a href="backoffice.md"><b>The "Backoffice" mechanism of Fossil</b></a></li> |
| 262 | 266 | <li><a href="blame.wiki"><b>The Annotate/Blame Algorithm Of Fossil</b></a></li> |
| 267 | +<li><a href="defcsp.md"><b>The Default Content Security Policy</b></a></li> | |
| 263 | 268 | <li><a href="admin-v-setup.md"><b>The Differences Between the Setup and Admin User Capabilities</b></a></li> |
| 264 | 269 | <li><a href="makefile.wiki"><b>The Fossil Build Process</b></a></li> |
| 265 | 270 | <li><a href="sync.wiki"><b>The Fossil Sync Protocol</b></a></li> |
| 266 | 271 | <li><a href="tickets.wiki"><b>The Fossil Ticket System</b></a></li> |
| 267 | 272 | <li><a href="webui.wiki"><b>The Fossil Web Interface</b></a></li> |
| 268 | 273 |
| --- www/permutedindex.html | |
| +++ www/permutedindex.html | |
| @@ -65,10 +65,11 @@ | |
| 65 | <li><a href="build.wiki"><b>Compiling and Installing Fossil</b></a></li> |
| 66 | <li><a href="concepts.wiki">Concepts — Fossil Core</a></li> |
| 67 | <li><a href="cgi.wiki">Configuration Options — CGI Script</a></li> |
| 68 | <li><a href="server/">Configure A Fossil Server — How To</a></li> |
| 69 | <li><a href="shunning.wiki">Content From Fossil — Shunning: Deleting</a></li> |
| 70 | <li><a href="contribute.wiki"><b>Contributing Code or Documentation To The Fossil Project</b></a></li> |
| 71 | <li><a href="copyright-release.html"><b>Contributor License Agreement</b></a></li> |
| 72 | <li><a href="whyusefossil.wiki">Control — Benefits Of Version</a></li> |
| 73 | <li><a href="concepts.wiki">Core Concepts — Fossil</a></li> |
| 74 | <li><a href="newrepo.wiki">Create A New Fossil Repository — How To</a></li> |
| @@ -77,10 +78,11 @@ | |
| 77 | <li><a href="customskin.md"><b>Custom Skins</b></a></li> |
| 78 | <li><a href="customskin.md">Customizing The Appearance of Web Pages — Theming:</a></li> |
| 79 | <li><a href="custom_ticket.wiki"><b>Customizing The Ticket System</b></a></li> |
| 80 | <li><a href="customgraph.md">Customizing the Timeline Graph — Theming:</a></li> |
| 81 | <li><a href="tech_overview.wiki">Databases Used By Fossil — SQLite</a></li> |
| 82 | <li><a href="antibot.wiki"><b>Defense against Spiders and Bots</b></a></li> |
| 83 | <li><a href="shunning.wiki">Deleting Content From Fossil — Shunning:</a></li> |
| 84 | <li><a href="private.wiki">Deleting Private Branches — Creating, Syncing, and</a></li> |
| 85 | <li><a href="delta_encoder_algorithm.wiki">Delta Encoding Algorithm — Fossil</a></li> |
| 86 | <li><a href="delta_format.wiki">Delta Format — Fossil</a></li> |
| @@ -195,10 +197,11 @@ | |
| 195 | <li><a href="customskin.md">Pages — Theming: Customizing The Appearance of Web</a></li> |
| 196 | <li><a href="password.wiki"><b>Password Management And Authentication</b></a></li> |
| 197 | <li><a href="globs.md">Patterns — File Name Glob</a></li> |
| 198 | <li><a href="quotes.wiki">People Are Saying About Fossil, Git, and DVCSes in General — Quotes: What</a></li> |
| 199 | <li><a href="stats.wiki"><b>Performance Statistics</b></a></li> |
| 200 | <li><a href="hashpolicy.wiki">Policy: Choosing Between SHA1 and SHA3-256 — Hash</a></li> |
| 201 | <li><a href="grep.md">POSIX grep — Fossil grep vs</a></li> |
| 202 | <li><a href="../test/release-checklist.wiki"><b>Pre-Release Testing Checklist</b></a></li> |
| 203 | <li><a href="pop.wiki"><b>Principles Of Operation</b></a></li> |
| 204 | <li><a href="private.wiki">Private Branches — Creating, Syncing, and Deleting</a></li> |
| @@ -226,10 +229,11 @@ | |
| 226 | <li><a href="fiveminutes.wiki">Running in 5 Minutes as a Single User — Up and</a></li> |
| 227 | <li><a href="quotes.wiki">Saying About Fossil, Git, and DVCSes in General — Quotes: What People Are</a></li> |
| 228 | <li><a href="cgi.wiki">Script Configuration Options — CGI</a></li> |
| 229 | <li><a href="th1.md">Scripting Language — The TH1</a></li> |
| 230 | <li><a href="serverext.wiki">Scripts — Adding Extensions To A Fossil Server Using CGI</a></li> |
| 231 | <li><a href="selfcheck.wiki">Self Checks — Fossil Repository Integrity</a></li> |
| 232 | <li><a href="selfhost.wiki">Self Hosting Repositories — Fossil</a></li> |
| 233 | <li><a href="server/">Server — How To Configure A Fossil</a></li> |
| 234 | <li><a href="serverext.wiki">Server Extensions — CGI</a></li> |
| 235 | <li><a href="serverext.wiki">Server Using CGI Scripts — Adding Extensions To A Fossil</a></li> |
| @@ -258,10 +262,11 @@ | |
| 258 | <li><a href="tech_overview.wiki">Technical Overview Of The Design And Implementation Of Fossil — A</a></li> |
| 259 | <li><a href="../test/release-checklist.wiki">Testing Checklist — Pre-Release</a></li> |
| 260 | <li><a href="th1.md">TH1 Scripting Language — The</a></li> |
| 261 | <li><a href="backoffice.md"><b>The "Backoffice" mechanism of Fossil</b></a></li> |
| 262 | <li><a href="blame.wiki"><b>The Annotate/Blame Algorithm Of Fossil</b></a></li> |
| 263 | <li><a href="admin-v-setup.md"><b>The Differences Between the Setup and Admin User Capabilities</b></a></li> |
| 264 | <li><a href="makefile.wiki"><b>The Fossil Build Process</b></a></li> |
| 265 | <li><a href="sync.wiki"><b>The Fossil Sync Protocol</b></a></li> |
| 266 | <li><a href="tickets.wiki"><b>The Fossil Ticket System</b></a></li> |
| 267 | <li><a href="webui.wiki"><b>The Fossil Web Interface</b></a></li> |
| 268 |
| --- www/permutedindex.html | |
| +++ www/permutedindex.html | |
| @@ -65,10 +65,11 @@ | |
| 65 | <li><a href="build.wiki"><b>Compiling and Installing Fossil</b></a></li> |
| 66 | <li><a href="concepts.wiki">Concepts — Fossil Core</a></li> |
| 67 | <li><a href="cgi.wiki">Configuration Options — CGI Script</a></li> |
| 68 | <li><a href="server/">Configure A Fossil Server — How To</a></li> |
| 69 | <li><a href="shunning.wiki">Content From Fossil — Shunning: Deleting</a></li> |
| 70 | <li><a href="defcsp.md">Content Security Policy — The Default</a></li> |
| 71 | <li><a href="contribute.wiki"><b>Contributing Code or Documentation To The Fossil Project</b></a></li> |
| 72 | <li><a href="copyright-release.html"><b>Contributor License Agreement</b></a></li> |
| 73 | <li><a href="whyusefossil.wiki">Control — Benefits Of Version</a></li> |
| 74 | <li><a href="concepts.wiki">Core Concepts — Fossil</a></li> |
| 75 | <li><a href="newrepo.wiki">Create A New Fossil Repository — How To</a></li> |
| @@ -77,10 +78,11 @@ | |
| 78 | <li><a href="customskin.md"><b>Custom Skins</b></a></li> |
| 79 | <li><a href="customskin.md">Customizing The Appearance of Web Pages — Theming:</a></li> |
| 80 | <li><a href="custom_ticket.wiki"><b>Customizing The Ticket System</b></a></li> |
| 81 | <li><a href="customgraph.md">Customizing the Timeline Graph — Theming:</a></li> |
| 82 | <li><a href="tech_overview.wiki">Databases Used By Fossil — SQLite</a></li> |
| 83 | <li><a href="defcsp.md">Default Content Security Policy — The</a></li> |
| 84 | <li><a href="antibot.wiki"><b>Defense against Spiders and Bots</b></a></li> |
| 85 | <li><a href="shunning.wiki">Deleting Content From Fossil — Shunning:</a></li> |
| 86 | <li><a href="private.wiki">Deleting Private Branches — Creating, Syncing, and</a></li> |
| 87 | <li><a href="delta_encoder_algorithm.wiki">Delta Encoding Algorithm — Fossil</a></li> |
| 88 | <li><a href="delta_format.wiki">Delta Format — Fossil</a></li> |
| @@ -195,10 +197,11 @@ | |
| 197 | <li><a href="customskin.md">Pages — Theming: Customizing The Appearance of Web</a></li> |
| 198 | <li><a href="password.wiki"><b>Password Management And Authentication</b></a></li> |
| 199 | <li><a href="globs.md">Patterns — File Name Glob</a></li> |
| 200 | <li><a href="quotes.wiki">People Are Saying About Fossil, Git, and DVCSes in General — Quotes: What</a></li> |
| 201 | <li><a href="stats.wiki"><b>Performance Statistics</b></a></li> |
| 202 | <li><a href="defcsp.md">Policy — The Default Content Security</a></li> |
| 203 | <li><a href="hashpolicy.wiki">Policy: Choosing Between SHA1 and SHA3-256 — Hash</a></li> |
| 204 | <li><a href="grep.md">POSIX grep — Fossil grep vs</a></li> |
| 205 | <li><a href="../test/release-checklist.wiki"><b>Pre-Release Testing Checklist</b></a></li> |
| 206 | <li><a href="pop.wiki"><b>Principles Of Operation</b></a></li> |
| 207 | <li><a href="private.wiki">Private Branches — Creating, Syncing, and Deleting</a></li> |
| @@ -226,10 +229,11 @@ | |
| 229 | <li><a href="fiveminutes.wiki">Running in 5 Minutes as a Single User — Up and</a></li> |
| 230 | <li><a href="quotes.wiki">Saying About Fossil, Git, and DVCSes in General — Quotes: What People Are</a></li> |
| 231 | <li><a href="cgi.wiki">Script Configuration Options — CGI</a></li> |
| 232 | <li><a href="th1.md">Scripting Language — The TH1</a></li> |
| 233 | <li><a href="serverext.wiki">Scripts — Adding Extensions To A Fossil Server Using CGI</a></li> |
| 234 | <li><a href="defcsp.md">Security Policy — The Default Content</a></li> |
| 235 | <li><a href="selfcheck.wiki">Self Checks — Fossil Repository Integrity</a></li> |
| 236 | <li><a href="selfhost.wiki">Self Hosting Repositories — Fossil</a></li> |
| 237 | <li><a href="server/">Server — How To Configure A Fossil</a></li> |
| 238 | <li><a href="serverext.wiki">Server Extensions — CGI</a></li> |
| 239 | <li><a href="serverext.wiki">Server Using CGI Scripts — Adding Extensions To A Fossil</a></li> |
| @@ -258,10 +262,11 @@ | |
| 262 | <li><a href="tech_overview.wiki">Technical Overview Of The Design And Implementation Of Fossil — A</a></li> |
| 263 | <li><a href="../test/release-checklist.wiki">Testing Checklist — Pre-Release</a></li> |
| 264 | <li><a href="th1.md">TH1 Scripting Language — The</a></li> |
| 265 | <li><a href="backoffice.md"><b>The "Backoffice" mechanism of Fossil</b></a></li> |
| 266 | <li><a href="blame.wiki"><b>The Annotate/Blame Algorithm Of Fossil</b></a></li> |
| 267 | <li><a href="defcsp.md"><b>The Default Content Security Policy</b></a></li> |
| 268 | <li><a href="admin-v-setup.md"><b>The Differences Between the Setup and Admin User Capabilities</b></a></li> |
| 269 | <li><a href="makefile.wiki"><b>The Fossil Build Process</b></a></li> |
| 270 | <li><a href="sync.wiki"><b>The Fossil Sync Protocol</b></a></li> |
| 271 | <li><a href="tickets.wiki"><b>The Fossil Ticket System</b></a></li> |
| 272 | <li><a href="webui.wiki"><b>The Fossil Web Interface</b></a></li> |
| 273 |
| --- www/permutedindex.html | ||
| +++ www/permutedindex.html | ||
| @@ -65,10 +65,11 @@ | ||
| 65 | 65 | <li><a href="build.wiki"><b>Compiling and Installing Fossil</b></a></li> |
| 66 | 66 | <li><a href="concepts.wiki">Concepts — Fossil Core</a></li> |
| 67 | 67 | <li><a href="cgi.wiki">Configuration Options — CGI Script</a></li> |
| 68 | 68 | <li><a href="server/">Configure A Fossil Server — How To</a></li> |
| 69 | 69 | <li><a href="shunning.wiki">Content From Fossil — Shunning: Deleting</a></li> |
| 70 | +<li><a href="defcsp.md">Content Security Policy — The Default</a></li> | |
| 70 | 71 | <li><a href="contribute.wiki"><b>Contributing Code or Documentation To The Fossil Project</b></a></li> |
| 71 | 72 | <li><a href="copyright-release.html"><b>Contributor License Agreement</b></a></li> |
| 72 | 73 | <li><a href="whyusefossil.wiki">Control — Benefits Of Version</a></li> |
| 73 | 74 | <li><a href="concepts.wiki">Core Concepts — Fossil</a></li> |
| 74 | 75 | <li><a href="newrepo.wiki">Create A New Fossil Repository — How To</a></li> |
| @@ -77,10 +78,11 @@ | ||
| 77 | 78 | <li><a href="customskin.md"><b>Custom Skins</b></a></li> |
| 78 | 79 | <li><a href="customskin.md">Customizing The Appearance of Web Pages — Theming:</a></li> |
| 79 | 80 | <li><a href="custom_ticket.wiki"><b>Customizing The Ticket System</b></a></li> |
| 80 | 81 | <li><a href="customgraph.md">Customizing the Timeline Graph — Theming:</a></li> |
| 81 | 82 | <li><a href="tech_overview.wiki">Databases Used By Fossil — SQLite</a></li> |
| 83 | +<li><a href="defcsp.md">Default Content Security Policy — The</a></li> | |
| 82 | 84 | <li><a href="antibot.wiki"><b>Defense against Spiders and Bots</b></a></li> |
| 83 | 85 | <li><a href="shunning.wiki">Deleting Content From Fossil — Shunning:</a></li> |
| 84 | 86 | <li><a href="private.wiki">Deleting Private Branches — Creating, Syncing, and</a></li> |
| 85 | 87 | <li><a href="delta_encoder_algorithm.wiki">Delta Encoding Algorithm — Fossil</a></li> |
| 86 | 88 | <li><a href="delta_format.wiki">Delta Format — Fossil</a></li> |
| @@ -195,10 +197,11 @@ | ||
| 195 | 197 | <li><a href="customskin.md">Pages — Theming: Customizing The Appearance of Web</a></li> |
| 196 | 198 | <li><a href="password.wiki"><b>Password Management And Authentication</b></a></li> |
| 197 | 199 | <li><a href="globs.md">Patterns — File Name Glob</a></li> |
| 198 | 200 | <li><a href="quotes.wiki">People Are Saying About Fossil, Git, and DVCSes in General — Quotes: What</a></li> |
| 199 | 201 | <li><a href="stats.wiki"><b>Performance Statistics</b></a></li> |
| 202 | +<li><a href="defcsp.md">Policy — The Default Content Security</a></li> | |
| 200 | 203 | <li><a href="hashpolicy.wiki">Policy: Choosing Between SHA1 and SHA3-256 — Hash</a></li> |
| 201 | 204 | <li><a href="grep.md">POSIX grep — Fossil grep vs</a></li> |
| 202 | 205 | <li><a href="../test/release-checklist.wiki"><b>Pre-Release Testing Checklist</b></a></li> |
| 203 | 206 | <li><a href="pop.wiki"><b>Principles Of Operation</b></a></li> |
| 204 | 207 | <li><a href="private.wiki">Private Branches — Creating, Syncing, and Deleting</a></li> |
| @@ -226,10 +229,11 @@ | ||
| 226 | 229 | <li><a href="fiveminutes.wiki">Running in 5 Minutes as a Single User — Up and</a></li> |
| 227 | 230 | <li><a href="quotes.wiki">Saying About Fossil, Git, and DVCSes in General — Quotes: What People Are</a></li> |
| 228 | 231 | <li><a href="cgi.wiki">Script Configuration Options — CGI</a></li> |
| 229 | 232 | <li><a href="th1.md">Scripting Language — The TH1</a></li> |
| 230 | 233 | <li><a href="serverext.wiki">Scripts — Adding Extensions To A Fossil Server Using CGI</a></li> |
| 234 | +<li><a href="defcsp.md">Security Policy — The Default Content</a></li> | |
| 231 | 235 | <li><a href="selfcheck.wiki">Self Checks — Fossil Repository Integrity</a></li> |
| 232 | 236 | <li><a href="selfhost.wiki">Self Hosting Repositories — Fossil</a></li> |
| 233 | 237 | <li><a href="server/">Server — How To Configure A Fossil</a></li> |
| 234 | 238 | <li><a href="serverext.wiki">Server Extensions — CGI</a></li> |
| 235 | 239 | <li><a href="serverext.wiki">Server Using CGI Scripts — Adding Extensions To A Fossil</a></li> |
| @@ -258,10 +262,11 @@ | ||
| 258 | 262 | <li><a href="tech_overview.wiki">Technical Overview Of The Design And Implementation Of Fossil — A</a></li> |
| 259 | 263 | <li><a href="../test/release-checklist.wiki">Testing Checklist — Pre-Release</a></li> |
| 260 | 264 | <li><a href="th1.md">TH1 Scripting Language — The</a></li> |
| 261 | 265 | <li><a href="backoffice.md"><b>The "Backoffice" mechanism of Fossil</b></a></li> |
| 262 | 266 | <li><a href="blame.wiki"><b>The Annotate/Blame Algorithm Of Fossil</b></a></li> |
| 267 | +<li><a href="defcsp.md"><b>The Default Content Security Policy</b></a></li> | |
| 263 | 268 | <li><a href="admin-v-setup.md"><b>The Differences Between the Setup and Admin User Capabilities</b></a></li> |
| 264 | 269 | <li><a href="makefile.wiki"><b>The Fossil Build Process</b></a></li> |
| 265 | 270 | <li><a href="sync.wiki"><b>The Fossil Sync Protocol</b></a></li> |
| 266 | 271 | <li><a href="tickets.wiki"><b>The Fossil Ticket System</b></a></li> |
| 267 | 272 | <li><a href="webui.wiki"><b>The Fossil Web Interface</b></a></li> |
| 268 | 273 |
| --- www/permutedindex.html | |
| +++ www/permutedindex.html | |
| @@ -65,10 +65,11 @@ | |
| 65 | <li><a href="build.wiki"><b>Compiling and Installing Fossil</b></a></li> |
| 66 | <li><a href="concepts.wiki">Concepts — Fossil Core</a></li> |
| 67 | <li><a href="cgi.wiki">Configuration Options — CGI Script</a></li> |
| 68 | <li><a href="server/">Configure A Fossil Server — How To</a></li> |
| 69 | <li><a href="shunning.wiki">Content From Fossil — Shunning: Deleting</a></li> |
| 70 | <li><a href="contribute.wiki"><b>Contributing Code or Documentation To The Fossil Project</b></a></li> |
| 71 | <li><a href="copyright-release.html"><b>Contributor License Agreement</b></a></li> |
| 72 | <li><a href="whyusefossil.wiki">Control — Benefits Of Version</a></li> |
| 73 | <li><a href="concepts.wiki">Core Concepts — Fossil</a></li> |
| 74 | <li><a href="newrepo.wiki">Create A New Fossil Repository — How To</a></li> |
| @@ -77,10 +78,11 @@ | |
| 77 | <li><a href="customskin.md"><b>Custom Skins</b></a></li> |
| 78 | <li><a href="customskin.md">Customizing The Appearance of Web Pages — Theming:</a></li> |
| 79 | <li><a href="custom_ticket.wiki"><b>Customizing The Ticket System</b></a></li> |
| 80 | <li><a href="customgraph.md">Customizing the Timeline Graph — Theming:</a></li> |
| 81 | <li><a href="tech_overview.wiki">Databases Used By Fossil — SQLite</a></li> |
| 82 | <li><a href="antibot.wiki"><b>Defense against Spiders and Bots</b></a></li> |
| 83 | <li><a href="shunning.wiki">Deleting Content From Fossil — Shunning:</a></li> |
| 84 | <li><a href="private.wiki">Deleting Private Branches — Creating, Syncing, and</a></li> |
| 85 | <li><a href="delta_encoder_algorithm.wiki">Delta Encoding Algorithm — Fossil</a></li> |
| 86 | <li><a href="delta_format.wiki">Delta Format — Fossil</a></li> |
| @@ -195,10 +197,11 @@ | |
| 195 | <li><a href="customskin.md">Pages — Theming: Customizing The Appearance of Web</a></li> |
| 196 | <li><a href="password.wiki"><b>Password Management And Authentication</b></a></li> |
| 197 | <li><a href="globs.md">Patterns — File Name Glob</a></li> |
| 198 | <li><a href="quotes.wiki">People Are Saying About Fossil, Git, and DVCSes in General — Quotes: What</a></li> |
| 199 | <li><a href="stats.wiki"><b>Performance Statistics</b></a></li> |
| 200 | <li><a href="hashpolicy.wiki">Policy: Choosing Between SHA1 and SHA3-256 — Hash</a></li> |
| 201 | <li><a href="grep.md">POSIX grep — Fossil grep vs</a></li> |
| 202 | <li><a href="../test/release-checklist.wiki"><b>Pre-Release Testing Checklist</b></a></li> |
| 203 | <li><a href="pop.wiki"><b>Principles Of Operation</b></a></li> |
| 204 | <li><a href="private.wiki">Private Branches — Creating, Syncing, and Deleting</a></li> |
| @@ -226,10 +229,11 @@ | |
| 226 | <li><a href="fiveminutes.wiki">Running in 5 Minutes as a Single User — Up and</a></li> |
| 227 | <li><a href="quotes.wiki">Saying About Fossil, Git, and DVCSes in General — Quotes: What People Are</a></li> |
| 228 | <li><a href="cgi.wiki">Script Configuration Options — CGI</a></li> |
| 229 | <li><a href="th1.md">Scripting Language — The TH1</a></li> |
| 230 | <li><a href="serverext.wiki">Scripts — Adding Extensions To A Fossil Server Using CGI</a></li> |
| 231 | <li><a href="selfcheck.wiki">Self Checks — Fossil Repository Integrity</a></li> |
| 232 | <li><a href="selfhost.wiki">Self Hosting Repositories — Fossil</a></li> |
| 233 | <li><a href="server/">Server — How To Configure A Fossil</a></li> |
| 234 | <li><a href="serverext.wiki">Server Extensions — CGI</a></li> |
| 235 | <li><a href="serverext.wiki">Server Using CGI Scripts — Adding Extensions To A Fossil</a></li> |
| @@ -258,10 +262,11 @@ | |
| 258 | <li><a href="tech_overview.wiki">Technical Overview Of The Design And Implementation Of Fossil — A</a></li> |
| 259 | <li><a href="../test/release-checklist.wiki">Testing Checklist — Pre-Release</a></li> |
| 260 | <li><a href="th1.md">TH1 Scripting Language — The</a></li> |
| 261 | <li><a href="backoffice.md"><b>The "Backoffice" mechanism of Fossil</b></a></li> |
| 262 | <li><a href="blame.wiki"><b>The Annotate/Blame Algorithm Of Fossil</b></a></li> |
| 263 | <li><a href="admin-v-setup.md"><b>The Differences Between the Setup and Admin User Capabilities</b></a></li> |
| 264 | <li><a href="makefile.wiki"><b>The Fossil Build Process</b></a></li> |
| 265 | <li><a href="sync.wiki"><b>The Fossil Sync Protocol</b></a></li> |
| 266 | <li><a href="tickets.wiki"><b>The Fossil Ticket System</b></a></li> |
| 267 | <li><a href="webui.wiki"><b>The Fossil Web Interface</b></a></li> |
| 268 |
| --- www/permutedindex.html | |
| +++ www/permutedindex.html | |
| @@ -65,10 +65,11 @@ | |
| 65 | <li><a href="build.wiki"><b>Compiling and Installing Fossil</b></a></li> |
| 66 | <li><a href="concepts.wiki">Concepts — Fossil Core</a></li> |
| 67 | <li><a href="cgi.wiki">Configuration Options — CGI Script</a></li> |
| 68 | <li><a href="server/">Configure A Fossil Server — How To</a></li> |
| 69 | <li><a href="shunning.wiki">Content From Fossil — Shunning: Deleting</a></li> |
| 70 | <li><a href="defcsp.md">Content Security Policy — The Default</a></li> |
| 71 | <li><a href="contribute.wiki"><b>Contributing Code or Documentation To The Fossil Project</b></a></li> |
| 72 | <li><a href="copyright-release.html"><b>Contributor License Agreement</b></a></li> |
| 73 | <li><a href="whyusefossil.wiki">Control — Benefits Of Version</a></li> |
| 74 | <li><a href="concepts.wiki">Core Concepts — Fossil</a></li> |
| 75 | <li><a href="newrepo.wiki">Create A New Fossil Repository — How To</a></li> |
| @@ -77,10 +78,11 @@ | |
| 78 | <li><a href="customskin.md"><b>Custom Skins</b></a></li> |
| 79 | <li><a href="customskin.md">Customizing The Appearance of Web Pages — Theming:</a></li> |
| 80 | <li><a href="custom_ticket.wiki"><b>Customizing The Ticket System</b></a></li> |
| 81 | <li><a href="customgraph.md">Customizing the Timeline Graph — Theming:</a></li> |
| 82 | <li><a href="tech_overview.wiki">Databases Used By Fossil — SQLite</a></li> |
| 83 | <li><a href="defcsp.md">Default Content Security Policy — The</a></li> |
| 84 | <li><a href="antibot.wiki"><b>Defense against Spiders and Bots</b></a></li> |
| 85 | <li><a href="shunning.wiki">Deleting Content From Fossil — Shunning:</a></li> |
| 86 | <li><a href="private.wiki">Deleting Private Branches — Creating, Syncing, and</a></li> |
| 87 | <li><a href="delta_encoder_algorithm.wiki">Delta Encoding Algorithm — Fossil</a></li> |
| 88 | <li><a href="delta_format.wiki">Delta Format — Fossil</a></li> |
| @@ -195,10 +197,11 @@ | |
| 197 | <li><a href="customskin.md">Pages — Theming: Customizing The Appearance of Web</a></li> |
| 198 | <li><a href="password.wiki"><b>Password Management And Authentication</b></a></li> |
| 199 | <li><a href="globs.md">Patterns — File Name Glob</a></li> |
| 200 | <li><a href="quotes.wiki">People Are Saying About Fossil, Git, and DVCSes in General — Quotes: What</a></li> |
| 201 | <li><a href="stats.wiki"><b>Performance Statistics</b></a></li> |
| 202 | <li><a href="defcsp.md">Policy — The Default Content Security</a></li> |
| 203 | <li><a href="hashpolicy.wiki">Policy: Choosing Between SHA1 and SHA3-256 — Hash</a></li> |
| 204 | <li><a href="grep.md">POSIX grep — Fossil grep vs</a></li> |
| 205 | <li><a href="../test/release-checklist.wiki"><b>Pre-Release Testing Checklist</b></a></li> |
| 206 | <li><a href="pop.wiki"><b>Principles Of Operation</b></a></li> |
| 207 | <li><a href="private.wiki">Private Branches — Creating, Syncing, and Deleting</a></li> |
| @@ -226,10 +229,11 @@ | |
| 229 | <li><a href="fiveminutes.wiki">Running in 5 Minutes as a Single User — Up and</a></li> |
| 230 | <li><a href="quotes.wiki">Saying About Fossil, Git, and DVCSes in General — Quotes: What People Are</a></li> |
| 231 | <li><a href="cgi.wiki">Script Configuration Options — CGI</a></li> |
| 232 | <li><a href="th1.md">Scripting Language — The TH1</a></li> |
| 233 | <li><a href="serverext.wiki">Scripts — Adding Extensions To A Fossil Server Using CGI</a></li> |
| 234 | <li><a href="defcsp.md">Security Policy — The Default Content</a></li> |
| 235 | <li><a href="selfcheck.wiki">Self Checks — Fossil Repository Integrity</a></li> |
| 236 | <li><a href="selfhost.wiki">Self Hosting Repositories — Fossil</a></li> |
| 237 | <li><a href="server/">Server — How To Configure A Fossil</a></li> |
| 238 | <li><a href="serverext.wiki">Server Extensions — CGI</a></li> |
| 239 | <li><a href="serverext.wiki">Server Using CGI Scripts — Adding Extensions To A Fossil</a></li> |
| @@ -258,10 +262,11 @@ | |
| 262 | <li><a href="tech_overview.wiki">Technical Overview Of The Design And Implementation Of Fossil — A</a></li> |
| 263 | <li><a href="../test/release-checklist.wiki">Testing Checklist — Pre-Release</a></li> |
| 264 | <li><a href="th1.md">TH1 Scripting Language — The</a></li> |
| 265 | <li><a href="backoffice.md"><b>The "Backoffice" mechanism of Fossil</b></a></li> |
| 266 | <li><a href="blame.wiki"><b>The Annotate/Blame Algorithm Of Fossil</b></a></li> |
| 267 | <li><a href="defcsp.md"><b>The Default Content Security Policy</b></a></li> |
| 268 | <li><a href="admin-v-setup.md"><b>The Differences Between the Setup and Admin User Capabilities</b></a></li> |
| 269 | <li><a href="makefile.wiki"><b>The Fossil Build Process</b></a></li> |
| 270 | <li><a href="sync.wiki"><b>The Fossil Sync Protocol</b></a></li> |
| 271 | <li><a href="tickets.wiki"><b>The Fossil Ticket System</b></a></li> |
| 272 | <li><a href="webui.wiki"><b>The Fossil Web Interface</b></a></li> |
| 273 |