Fossil SCM
Add the 'nonce' command to TH1. Improve clarity of the 'default_csp' variable handling and add comments.
Commit
68e6b07ebaf1ba674345311ca28bd1a7caae21566449a62a8f3d81ccfa65cdf8
Parent
0b885bb952c66ba…
4 files changed
+11
-6
+21
+2
-3
+8
+11
-6
| --- src/style.c | ||
| +++ src/style.c | ||
| @@ -405,24 +405,29 @@ | ||
| 405 | 405 | /* |
| 406 | 406 | ** Initialize all the default TH1 variables |
| 407 | 407 | */ |
| 408 | 408 | static void style_init_th1_vars(const char *zTitle){ |
| 409 | 409 | const char *zNonce = style_nonce(); |
| 410 | - Th_Store("nonce", zNonce); | |
| 411 | - Th_Store("project_name", db_get("project-name","Unnamed Fossil Project")); | |
| 412 | - Th_Store("project_description", db_get("project-description","")); | |
| 413 | - if( zTitle ) Th_Store("title", zTitle); | |
| 414 | - Th_Store("baseurl", g.zBaseURL); | |
| 415 | - Th_Store("secureurl", fossil_wants_https(1)? g.zHttpsURL: g.zBaseURL); | |
| 410 | + /* | |
| 411 | + ** Do not overwrite the TH1 variable "default_csp" if it exists, as this | |
| 412 | + ** allows it to be properly overridden via the TH1 setup script (i.e. it | |
| 413 | + ** is evaluated before the header is rendered). | |
| 414 | + */ | |
| 416 | 415 | if( !Th_ExistsVar(g.interp, "default_csp", -1) ){ |
| 417 | 416 | char *zDfltCsp = sqlite3_mprintf("default-src 'self' data: ; " |
| 418 | 417 | "script-src 'self' 'nonce-%s' ; " |
| 419 | 418 | "style-src 'self' 'unsafe-inline'", |
| 420 | 419 | zNonce); |
| 421 | 420 | Th_Store("default_csp", zDfltCsp); |
| 422 | 421 | sqlite3_free(zDfltCsp); |
| 423 | 422 | } |
| 423 | + Th_Store("nonce", zNonce); | |
| 424 | + Th_Store("project_name", db_get("project-name","Unnamed Fossil Project")); | |
| 425 | + Th_Store("project_description", db_get("project-description","")); | |
| 426 | + if( zTitle ) Th_Store("title", zTitle); | |
| 427 | + Th_Store("baseurl", g.zBaseURL); | |
| 428 | + Th_Store("secureurl", fossil_wants_https(1)? g.zHttpsURL: g.zBaseURL); | |
| 424 | 429 | Th_Store("home", g.zTop); |
| 425 | 430 | Th_Store("index_page", db_get("index-page","/home")); |
| 426 | 431 | if( local_zCurrentPage==0 ) style_set_current_page("%T", g.zPath); |
| 427 | 432 | Th_Store("current_page", local_zCurrentPage); |
| 428 | 433 | Th_Store("csrf_token", g.zCsrfToken); |
| 429 | 434 |
| --- src/style.c | |
| +++ src/style.c | |
| @@ -405,24 +405,29 @@ | |
| 405 | /* |
| 406 | ** Initialize all the default TH1 variables |
| 407 | */ |
| 408 | static void style_init_th1_vars(const char *zTitle){ |
| 409 | const char *zNonce = style_nonce(); |
| 410 | Th_Store("nonce", zNonce); |
| 411 | Th_Store("project_name", db_get("project-name","Unnamed Fossil Project")); |
| 412 | Th_Store("project_description", db_get("project-description","")); |
| 413 | if( zTitle ) Th_Store("title", zTitle); |
| 414 | Th_Store("baseurl", g.zBaseURL); |
| 415 | Th_Store("secureurl", fossil_wants_https(1)? g.zHttpsURL: g.zBaseURL); |
| 416 | if( !Th_ExistsVar(g.interp, "default_csp", -1) ){ |
| 417 | char *zDfltCsp = sqlite3_mprintf("default-src 'self' data: ; " |
| 418 | "script-src 'self' 'nonce-%s' ; " |
| 419 | "style-src 'self' 'unsafe-inline'", |
| 420 | zNonce); |
| 421 | Th_Store("default_csp", zDfltCsp); |
| 422 | sqlite3_free(zDfltCsp); |
| 423 | } |
| 424 | Th_Store("home", g.zTop); |
| 425 | Th_Store("index_page", db_get("index-page","/home")); |
| 426 | if( local_zCurrentPage==0 ) style_set_current_page("%T", g.zPath); |
| 427 | Th_Store("current_page", local_zCurrentPage); |
| 428 | Th_Store("csrf_token", g.zCsrfToken); |
| 429 |
| --- src/style.c | |
| +++ src/style.c | |
| @@ -405,24 +405,29 @@ | |
| 405 | /* |
| 406 | ** Initialize all the default TH1 variables |
| 407 | */ |
| 408 | static void style_init_th1_vars(const char *zTitle){ |
| 409 | const char *zNonce = style_nonce(); |
| 410 | /* |
| 411 | ** Do not overwrite the TH1 variable "default_csp" if it exists, as this |
| 412 | ** allows it to be properly overridden via the TH1 setup script (i.e. it |
| 413 | ** is evaluated before the header is rendered). |
| 414 | */ |
| 415 | if( !Th_ExistsVar(g.interp, "default_csp", -1) ){ |
| 416 | char *zDfltCsp = sqlite3_mprintf("default-src 'self' data: ; " |
| 417 | "script-src 'self' 'nonce-%s' ; " |
| 418 | "style-src 'self' 'unsafe-inline'", |
| 419 | zNonce); |
| 420 | Th_Store("default_csp", zDfltCsp); |
| 421 | sqlite3_free(zDfltCsp); |
| 422 | } |
| 423 | Th_Store("nonce", zNonce); |
| 424 | Th_Store("project_name", db_get("project-name","Unnamed Fossil Project")); |
| 425 | Th_Store("project_description", db_get("project-description","")); |
| 426 | if( zTitle ) Th_Store("title", zTitle); |
| 427 | Th_Store("baseurl", g.zBaseURL); |
| 428 | Th_Store("secureurl", fossil_wants_https(1)? g.zHttpsURL: g.zBaseURL); |
| 429 | Th_Store("home", g.zTop); |
| 430 | Th_Store("index_page", db_get("index-page","/home")); |
| 431 | if( local_zCurrentPage==0 ) style_set_current_page("%T", g.zPath); |
| 432 | Th_Store("current_page", local_zCurrentPage); |
| 433 | Th_Store("csrf_token", g.zCsrfToken); |
| 434 |
+21
| --- src/th_main.c | ||
| +++ src/th_main.c | ||
| @@ -411,10 +411,30 @@ | ||
| 411 | 411 | } |
| 412 | 412 | } |
| 413 | 413 | Th_SetResult(interp, "file name not found in manifest", -1); |
| 414 | 414 | return 0; |
| 415 | 415 | } |
| 416 | + | |
| 417 | +/* | |
| 418 | +** TH1 command: nonce | |
| 419 | +** | |
| 420 | +** Returns the value of the cryptographic nonce for the request being | |
| 421 | +** processed. | |
| 422 | +*/ | |
| 423 | +static int nonceCmd( | |
| 424 | + Th_Interp *interp, | |
| 425 | + void *pConvert, | |
| 426 | + int argc, | |
| 427 | + const char **argv, | |
| 428 | + int *argl | |
| 429 | +){ | |
| 430 | + if( argc!=1 ){ | |
| 431 | + return Th_WrongNumArgs(interp, "nonce"); | |
| 432 | + } | |
| 433 | + Th_SetResult(interp, style_nonce(), -1); | |
| 434 | + return TH_OK; | |
| 435 | +} | |
| 416 | 436 | |
| 417 | 437 | /* |
| 418 | 438 | ** TH1 command: puts STRING |
| 419 | 439 | ** TH1 command: html STRING |
| 420 | 440 | ** |
| @@ -2021,10 +2041,11 @@ | ||
| 2021 | 2041 | {"htmlize", htmlizeCmd, 0}, |
| 2022 | 2042 | {"http", httpCmd, 0}, |
| 2023 | 2043 | {"insertCsrf", insertCsrfCmd, 0}, |
| 2024 | 2044 | {"linecount", linecntCmd, 0}, |
| 2025 | 2045 | {"markdown", markdownCmd, 0}, |
| 2046 | + {"nonce", nonceCmd, 0}, | |
| 2026 | 2047 | {"puts", putsCmd, (void*)&aFlags[1]}, |
| 2027 | 2048 | {"query", queryCmd, 0}, |
| 2028 | 2049 | {"randhex", randhexCmd, 0}, |
| 2029 | 2050 | {"redirect", redirectCmd, 0}, |
| 2030 | 2051 | {"regexp", regexpCmd, 0}, |
| 2031 | 2052 |
| --- src/th_main.c | |
| +++ src/th_main.c | |
| @@ -411,10 +411,30 @@ | |
| 411 | } |
| 412 | } |
| 413 | Th_SetResult(interp, "file name not found in manifest", -1); |
| 414 | return 0; |
| 415 | } |
| 416 | |
| 417 | /* |
| 418 | ** TH1 command: puts STRING |
| 419 | ** TH1 command: html STRING |
| 420 | ** |
| @@ -2021,10 +2041,11 @@ | |
| 2021 | {"htmlize", htmlizeCmd, 0}, |
| 2022 | {"http", httpCmd, 0}, |
| 2023 | {"insertCsrf", insertCsrfCmd, 0}, |
| 2024 | {"linecount", linecntCmd, 0}, |
| 2025 | {"markdown", markdownCmd, 0}, |
| 2026 | {"puts", putsCmd, (void*)&aFlags[1]}, |
| 2027 | {"query", queryCmd, 0}, |
| 2028 | {"randhex", randhexCmd, 0}, |
| 2029 | {"redirect", redirectCmd, 0}, |
| 2030 | {"regexp", regexpCmd, 0}, |
| 2031 |
| --- src/th_main.c | |
| +++ src/th_main.c | |
| @@ -411,10 +411,30 @@ | |
| 411 | } |
| 412 | } |
| 413 | Th_SetResult(interp, "file name not found in manifest", -1); |
| 414 | return 0; |
| 415 | } |
| 416 | |
| 417 | /* |
| 418 | ** TH1 command: nonce |
| 419 | ** |
| 420 | ** Returns the value of the cryptographic nonce for the request being |
| 421 | ** processed. |
| 422 | */ |
| 423 | static int nonceCmd( |
| 424 | Th_Interp *interp, |
| 425 | void *pConvert, |
| 426 | int argc, |
| 427 | const char **argv, |
| 428 | int *argl |
| 429 | ){ |
| 430 | if( argc!=1 ){ |
| 431 | return Th_WrongNumArgs(interp, "nonce"); |
| 432 | } |
| 433 | Th_SetResult(interp, style_nonce(), -1); |
| 434 | return TH_OK; |
| 435 | } |
| 436 | |
| 437 | /* |
| 438 | ** TH1 command: puts STRING |
| 439 | ** TH1 command: html STRING |
| 440 | ** |
| @@ -2021,10 +2041,11 @@ | |
| 2041 | {"htmlize", htmlizeCmd, 0}, |
| 2042 | {"http", httpCmd, 0}, |
| 2043 | {"insertCsrf", insertCsrfCmd, 0}, |
| 2044 | {"linecount", linecntCmd, 0}, |
| 2045 | {"markdown", markdownCmd, 0}, |
| 2046 | {"nonce", nonceCmd, 0}, |
| 2047 | {"puts", putsCmd, (void*)&aFlags[1]}, |
| 2048 | {"query", queryCmd, 0}, |
| 2049 | {"randhex", randhexCmd, 0}, |
| 2050 | {"redirect", redirectCmd, 0}, |
| 2051 | {"regexp", regexpCmd, 0}, |
| 2052 |
+2
-3
| --- test/th1.test | ||
| +++ test/th1.test | ||
| @@ -1032,21 +1032,20 @@ | ||
| 1032 | 1032 | protOut "Sorted: $sorted_result" |
| 1033 | 1033 | set base_commands {anoncap anycap array artifact break breakpoint catch\ |
| 1034 | 1034 | cgiHeaderLine checkout combobox continue date decorate dir enable_output \ |
| 1035 | 1035 | encode64 error expr for getParameter glob_match globalState hascap \ |
| 1036 | 1036 | hasfeature html htmlize http httpize if info insertCsrf lindex linecount \ |
| 1037 | - list llength lsearch markdown proc puts query randhex redirect regexp\ | |
| 1038 | - reinitialize rename render repository return searchable set\ | |
| 1037 | + list llength lsearch markdown nonce proc puts query randhex redirect\ | |
| 1038 | + regexp reinitialize rename render repository return searchable set\ | |
| 1039 | 1039 | setParameter setting stime string styleFooter styleHeader styleScript\ |
| 1040 | 1040 | tclReady trace unset unversioned uplevel upvar utime verifyCsrf wiki} |
| 1041 | 1041 | set tcl_commands {tclEval tclExpr tclInvoke tclIsSafe tclMakeSafe} |
| 1042 | 1042 | if {$th1Tcl} { |
| 1043 | 1043 | test th1-info-commands-1 {$sorted_result eq [lsort "$base_commands $tcl_commands"]} |
| 1044 | 1044 | } else { |
| 1045 | 1045 | test th1-info-commands-1 {$sorted_result eq [lsort "$base_commands"]} |
| 1046 | 1046 | } |
| 1047 | - | |
| 1048 | 1047 | |
| 1049 | 1048 | ############################################################################### |
| 1050 | 1049 | |
| 1051 | 1050 | fossil test-th-eval "info vars" |
| 1052 | 1051 | |
| 1053 | 1052 |
| --- test/th1.test | |
| +++ test/th1.test | |
| @@ -1032,21 +1032,20 @@ | |
| 1032 | protOut "Sorted: $sorted_result" |
| 1033 | set base_commands {anoncap anycap array artifact break breakpoint catch\ |
| 1034 | cgiHeaderLine checkout combobox continue date decorate dir enable_output \ |
| 1035 | encode64 error expr for getParameter glob_match globalState hascap \ |
| 1036 | hasfeature html htmlize http httpize if info insertCsrf lindex linecount \ |
| 1037 | list llength lsearch markdown proc puts query randhex redirect regexp\ |
| 1038 | reinitialize rename render repository return searchable set\ |
| 1039 | setParameter setting stime string styleFooter styleHeader styleScript\ |
| 1040 | tclReady trace unset unversioned uplevel upvar utime verifyCsrf wiki} |
| 1041 | set tcl_commands {tclEval tclExpr tclInvoke tclIsSafe tclMakeSafe} |
| 1042 | if {$th1Tcl} { |
| 1043 | test th1-info-commands-1 {$sorted_result eq [lsort "$base_commands $tcl_commands"]} |
| 1044 | } else { |
| 1045 | test th1-info-commands-1 {$sorted_result eq [lsort "$base_commands"]} |
| 1046 | } |
| 1047 | |
| 1048 | |
| 1049 | ############################################################################### |
| 1050 | |
| 1051 | fossil test-th-eval "info vars" |
| 1052 | |
| 1053 |
| --- test/th1.test | |
| +++ test/th1.test | |
| @@ -1032,21 +1032,20 @@ | |
| 1032 | protOut "Sorted: $sorted_result" |
| 1033 | set base_commands {anoncap anycap array artifact break breakpoint catch\ |
| 1034 | cgiHeaderLine checkout combobox continue date decorate dir enable_output \ |
| 1035 | encode64 error expr for getParameter glob_match globalState hascap \ |
| 1036 | hasfeature html htmlize http httpize if info insertCsrf lindex linecount \ |
| 1037 | list llength lsearch markdown nonce proc puts query randhex redirect\ |
| 1038 | regexp reinitialize rename render repository return searchable set\ |
| 1039 | setParameter setting stime string styleFooter styleHeader styleScript\ |
| 1040 | tclReady trace unset unversioned uplevel upvar utime verifyCsrf wiki} |
| 1041 | set tcl_commands {tclEval tclExpr tclInvoke tclIsSafe tclMakeSafe} |
| 1042 | if {$th1Tcl} { |
| 1043 | test th1-info-commands-1 {$sorted_result eq [lsort "$base_commands $tcl_commands"]} |
| 1044 | } else { |
| 1045 | test th1-info-commands-1 {$sorted_result eq [lsort "$base_commands"]} |
| 1046 | } |
| 1047 | |
| 1048 | ############################################################################### |
| 1049 | |
| 1050 | fossil test-th-eval "info vars" |
| 1051 | |
| 1052 |
+8
| --- www/th1.md | ||
| +++ www/th1.md | ||
| @@ -187,10 +187,11 @@ | ||
| 187 | 187 | * http |
| 188 | 188 | * httpize |
| 189 | 189 | * insertCsrf |
| 190 | 190 | * linecount |
| 191 | 191 | * markdown |
| 192 | + * nonce | |
| 192 | 193 | * puts |
| 193 | 194 | * query |
| 194 | 195 | * randhex |
| 195 | 196 | * redirect |
| 196 | 197 | * regexp |
| @@ -453,10 +454,17 @@ | ||
| 453 | 454 | |
| 454 | 455 | Renders the input string as markdown. The result is a two-element list. |
| 455 | 456 | The first element contains the body, rendered as HTML. The second element |
| 456 | 457 | is the text-only title string. |
| 457 | 458 | |
| 459 | +<a name="nonce"></a>TH1 nonce Command | |
| 460 | +------------------------------------- | |
| 461 | + | |
| 462 | + * nonce | |
| 463 | + | |
| 464 | +Returns the value of the cryptographic nonce for the request being processed. | |
| 465 | + | |
| 458 | 466 | <a name="puts"></a>TH1 puts Command |
| 459 | 467 | ----------------------------------- |
| 460 | 468 | |
| 461 | 469 | * puts STRING |
| 462 | 470 | |
| 463 | 471 |
| --- www/th1.md | |
| +++ www/th1.md | |
| @@ -187,10 +187,11 @@ | |
| 187 | * http |
| 188 | * httpize |
| 189 | * insertCsrf |
| 190 | * linecount |
| 191 | * markdown |
| 192 | * puts |
| 193 | * query |
| 194 | * randhex |
| 195 | * redirect |
| 196 | * regexp |
| @@ -453,10 +454,17 @@ | |
| 453 | |
| 454 | Renders the input string as markdown. The result is a two-element list. |
| 455 | The first element contains the body, rendered as HTML. The second element |
| 456 | is the text-only title string. |
| 457 | |
| 458 | <a name="puts"></a>TH1 puts Command |
| 459 | ----------------------------------- |
| 460 | |
| 461 | * puts STRING |
| 462 | |
| 463 |
| --- www/th1.md | |
| +++ www/th1.md | |
| @@ -187,10 +187,11 @@ | |
| 187 | * http |
| 188 | * httpize |
| 189 | * insertCsrf |
| 190 | * linecount |
| 191 | * markdown |
| 192 | * nonce |
| 193 | * puts |
| 194 | * query |
| 195 | * randhex |
| 196 | * redirect |
| 197 | * regexp |
| @@ -453,10 +454,17 @@ | |
| 454 | |
| 455 | Renders the input string as markdown. The result is a two-element list. |
| 456 | The first element contains the body, rendered as HTML. The second element |
| 457 | is the text-only title string. |
| 458 | |
| 459 | <a name="nonce"></a>TH1 nonce Command |
| 460 | ------------------------------------- |
| 461 | |
| 462 | * nonce |
| 463 | |
| 464 | Returns the value of the cryptographic nonce for the request being processed. |
| 465 | |
| 466 | <a name="puts"></a>TH1 puts Command |
| 467 | ----------------------------------- |
| 468 | |
| 469 | * puts STRING |
| 470 | |
| 471 |