Fossil SCM
Change the action= attribute of <form> elements using javascript, as an additional defense against spam-bots.
Commit
dfa3579455cd3491bf159e9af3ef18c78477a065
Parent
fb04f278294a8ca…
7 files changed
+4
-4
+3
-3
+2
-2
+3
-3
+30
-2
+2
-2
+9
-7
+4
-4
| --- src/attach.c | ||
| +++ src/attach.c | ||
| @@ -318,12 +318,12 @@ | ||
| 318 | 318 | db_end_transaction(0); |
| 319 | 319 | cgi_redirect(zFrom); |
| 320 | 320 | } |
| 321 | 321 | style_header("Add Attachment"); |
| 322 | 322 | @ <h2>Add Attachment To %s(zTargetType)</h2> |
| 323 | - @ <form action="%s(g.zTop)/attachadd" method="post" | |
| 324 | - @ enctype="multipart/form-data"><div> | |
| 323 | + form_begin("enctype='multipart/form-data'", "%R/attachadd"); | |
| 324 | + @ <div> | |
| 325 | 325 | @ File to Attach: |
| 326 | 326 | @ <input type="file" name="f" size="60" /><br /> |
| 327 | 327 | @ Description:<br /> |
| 328 | 328 | @ <textarea name="comment" cols="80" rows="5" wrap="virtual"></textarea><br /> |
| 329 | 329 | if( zTkt ){ |
| @@ -433,11 +433,11 @@ | ||
| 433 | 433 | } |
| 434 | 434 | |
| 435 | 435 | if( P("del") |
| 436 | 436 | && ((zTktUuid && g.perm.WrTkt) || (zWikiName && g.perm.WrWiki)) |
| 437 | 437 | ){ |
| 438 | - @ <form method="post" action="%R/ainfo/%s(zUuid)"> | |
| 438 | + form_begin(0, "%R/ainfo/%s", zUuid); | |
| 439 | 439 | @ <p>Confirm you want to delete the attachment shown below. |
| 440 | 440 | @ <input type="submit" name="confirm" value="Confirm"> |
| 441 | 441 | @ </form> |
| 442 | 442 | } |
| 443 | 443 | |
| @@ -497,11 +497,11 @@ | ||
| 497 | 497 | @ </table> |
| 498 | 498 | |
| 499 | 499 | if( isModerator && modPending ){ |
| 500 | 500 | @ <div class="section">Moderation</div> |
| 501 | 501 | @ <blockquote> |
| 502 | - @ <form method="POST" action="%R/ainfo/%s(zUuid)"> | |
| 502 | + form_begin(0, "%R/ainfo/%s", zUuid); | |
| 503 | 503 | @ <label><input type="radio" name="modaction" value="delete"> |
| 504 | 504 | @ Delete this change</label><br /> |
| 505 | 505 | @ <label><input type="radio" name="modaction" value="approve"> |
| 506 | 506 | @ Approve this change</label><br /> |
| 507 | 507 | @ <input type="submit" value="Submit"> |
| 508 | 508 |
| --- src/attach.c | |
| +++ src/attach.c | |
| @@ -318,12 +318,12 @@ | |
| 318 | db_end_transaction(0); |
| 319 | cgi_redirect(zFrom); |
| 320 | } |
| 321 | style_header("Add Attachment"); |
| 322 | @ <h2>Add Attachment To %s(zTargetType)</h2> |
| 323 | @ <form action="%s(g.zTop)/attachadd" method="post" |
| 324 | @ enctype="multipart/form-data"><div> |
| 325 | @ File to Attach: |
| 326 | @ <input type="file" name="f" size="60" /><br /> |
| 327 | @ Description:<br /> |
| 328 | @ <textarea name="comment" cols="80" rows="5" wrap="virtual"></textarea><br /> |
| 329 | if( zTkt ){ |
| @@ -433,11 +433,11 @@ | |
| 433 | } |
| 434 | |
| 435 | if( P("del") |
| 436 | && ((zTktUuid && g.perm.WrTkt) || (zWikiName && g.perm.WrWiki)) |
| 437 | ){ |
| 438 | @ <form method="post" action="%R/ainfo/%s(zUuid)"> |
| 439 | @ <p>Confirm you want to delete the attachment shown below. |
| 440 | @ <input type="submit" name="confirm" value="Confirm"> |
| 441 | @ </form> |
| 442 | } |
| 443 | |
| @@ -497,11 +497,11 @@ | |
| 497 | @ </table> |
| 498 | |
| 499 | if( isModerator && modPending ){ |
| 500 | @ <div class="section">Moderation</div> |
| 501 | @ <blockquote> |
| 502 | @ <form method="POST" action="%R/ainfo/%s(zUuid)"> |
| 503 | @ <label><input type="radio" name="modaction" value="delete"> |
| 504 | @ Delete this change</label><br /> |
| 505 | @ <label><input type="radio" name="modaction" value="approve"> |
| 506 | @ Approve this change</label><br /> |
| 507 | @ <input type="submit" value="Submit"> |
| 508 |
| --- src/attach.c | |
| +++ src/attach.c | |
| @@ -318,12 +318,12 @@ | |
| 318 | db_end_transaction(0); |
| 319 | cgi_redirect(zFrom); |
| 320 | } |
| 321 | style_header("Add Attachment"); |
| 322 | @ <h2>Add Attachment To %s(zTargetType)</h2> |
| 323 | form_begin("enctype='multipart/form-data'", "%R/attachadd"); |
| 324 | @ <div> |
| 325 | @ File to Attach: |
| 326 | @ <input type="file" name="f" size="60" /><br /> |
| 327 | @ Description:<br /> |
| 328 | @ <textarea name="comment" cols="80" rows="5" wrap="virtual"></textarea><br /> |
| 329 | if( zTkt ){ |
| @@ -433,11 +433,11 @@ | |
| 433 | } |
| 434 | |
| 435 | if( P("del") |
| 436 | && ((zTktUuid && g.perm.WrTkt) || (zWikiName && g.perm.WrWiki)) |
| 437 | ){ |
| 438 | form_begin(0, "%R/ainfo/%s", zUuid); |
| 439 | @ <p>Confirm you want to delete the attachment shown below. |
| 440 | @ <input type="submit" name="confirm" value="Confirm"> |
| 441 | @ </form> |
| 442 | } |
| 443 | |
| @@ -497,11 +497,11 @@ | |
| 497 | @ </table> |
| 498 | |
| 499 | if( isModerator && modPending ){ |
| 500 | @ <div class="section">Moderation</div> |
| 501 | @ <blockquote> |
| 502 | form_begin(0, "%R/ainfo/%s", zUuid); |
| 503 | @ <label><input type="radio" name="modaction" value="delete"> |
| 504 | @ Delete this change</label><br /> |
| 505 | @ <label><input type="radio" name="modaction" value="approve"> |
| 506 | @ Approve this change</label><br /> |
| 507 | @ <input type="submit" value="Submit"> |
| 508 |
+3
-3
| --- src/captcha.c | ||
| +++ src/captcha.c | ||
| @@ -252,11 +252,11 @@ | ||
| 252 | 252 | |
| 253 | 253 | /* 3 */ |
| 254 | 254 | " ____ ", |
| 255 | 255 | "|___ \\ ", |
| 256 | 256 | " __) |", |
| 257 | - " |__ < ", | |
| 257 | + " |__ < ", | |
| 258 | 258 | " ___) |", |
| 259 | 259 | "|____/ ", |
| 260 | 260 | |
| 261 | 261 | /* 4 */ |
| 262 | 262 | " _ _ ", |
| @@ -292,11 +292,11 @@ | ||
| 292 | 292 | |
| 293 | 293 | /* 8 */ |
| 294 | 294 | " ___ ", |
| 295 | 295 | " / _ \\ ", |
| 296 | 296 | "| (_) |", |
| 297 | - " > _ < ", | |
| 297 | + " > _ < ", | |
| 298 | 298 | "| (_) |", |
| 299 | 299 | " \\___/ ", |
| 300 | 300 | |
| 301 | 301 | /* 9 */ |
| 302 | 302 | " ___ ", |
| @@ -316,11 +316,11 @@ | ||
| 316 | 316 | |
| 317 | 317 | /* B */ |
| 318 | 318 | " ____ ", |
| 319 | 319 | "| _ \\ ", |
| 320 | 320 | "| |_) |", |
| 321 | - "| _ < ", | |
| 321 | + "| _ < ", | |
| 322 | 322 | "| |_) |", |
| 323 | 323 | "|____/ ", |
| 324 | 324 | |
| 325 | 325 | /* C */ |
| 326 | 326 | " _____ ", |
| 327 | 327 |
| --- src/captcha.c | |
| +++ src/captcha.c | |
| @@ -252,11 +252,11 @@ | |
| 252 | |
| 253 | /* 3 */ |
| 254 | " ____ ", |
| 255 | "|___ \\ ", |
| 256 | " __) |", |
| 257 | " |__ < ", |
| 258 | " ___) |", |
| 259 | "|____/ ", |
| 260 | |
| 261 | /* 4 */ |
| 262 | " _ _ ", |
| @@ -292,11 +292,11 @@ | |
| 292 | |
| 293 | /* 8 */ |
| 294 | " ___ ", |
| 295 | " / _ \\ ", |
| 296 | "| (_) |", |
| 297 | " > _ < ", |
| 298 | "| (_) |", |
| 299 | " \\___/ ", |
| 300 | |
| 301 | /* 9 */ |
| 302 | " ___ ", |
| @@ -316,11 +316,11 @@ | |
| 316 | |
| 317 | /* B */ |
| 318 | " ____ ", |
| 319 | "| _ \\ ", |
| 320 | "| |_) |", |
| 321 | "| _ < ", |
| 322 | "| |_) |", |
| 323 | "|____/ ", |
| 324 | |
| 325 | /* C */ |
| 326 | " _____ ", |
| 327 |
| --- src/captcha.c | |
| +++ src/captcha.c | |
| @@ -252,11 +252,11 @@ | |
| 252 | |
| 253 | /* 3 */ |
| 254 | " ____ ", |
| 255 | "|___ \\ ", |
| 256 | " __) |", |
| 257 | " |__ < ", |
| 258 | " ___) |", |
| 259 | "|____/ ", |
| 260 | |
| 261 | /* 4 */ |
| 262 | " _ _ ", |
| @@ -292,11 +292,11 @@ | |
| 292 | |
| 293 | /* 8 */ |
| 294 | " ___ ", |
| 295 | " / _ \\ ", |
| 296 | "| (_) |", |
| 297 | " > _ < ", |
| 298 | "| (_) |", |
| 299 | " \\___/ ", |
| 300 | |
| 301 | /* 9 */ |
| 302 | " ___ ", |
| @@ -316,11 +316,11 @@ | |
| 316 | |
| 317 | /* B */ |
| 318 | " ____ ", |
| 319 | "| _ \\ ", |
| 320 | "| |_) |", |
| 321 | "| _ < ", |
| 322 | "| |_) |", |
| 323 | "|____/ ", |
| 324 | |
| 325 | /* C */ |
| 326 | " _____ ", |
| 327 |
+2
-2
| --- src/info.c | ||
| +++ src/info.c | ||
| @@ -2183,13 +2183,13 @@ | ||
| 2183 | 2183 | @ <hr /> |
| 2184 | 2184 | blob_reset(&suffix); |
| 2185 | 2185 | } |
| 2186 | 2186 | @ <p>Make changes to attributes of check-in |
| 2187 | 2187 | @ [%z(href("%R/ci/%s",zUuid))%s(zUuid)</a>]:</p> |
| 2188 | - @ <form action="%s(g.zTop)/ci_edit" method="post"><div> | |
| 2188 | + form_begin(0, "%R/ci_edit"); | |
| 2189 | 2189 | login_insert_csrf_secret(); |
| 2190 | - @ <input type="hidden" name="r" value="%S(zUuid)" /> | |
| 2190 | + @ <div><input type="hidden" name="r" value="%S(zUuid)" /> | |
| 2191 | 2191 | @ <table border="0" cellspacing="10"> |
| 2192 | 2192 | |
| 2193 | 2193 | @ <tr><td align="right" valign="top"><b>User:</b></td> |
| 2194 | 2194 | @ <td valign="top"> |
| 2195 | 2195 | @ <input type="text" name="u" size="20" value="%h(zNewUser)" /> |
| 2196 | 2196 |
| --- src/info.c | |
| +++ src/info.c | |
| @@ -2183,13 +2183,13 @@ | |
| 2183 | @ <hr /> |
| 2184 | blob_reset(&suffix); |
| 2185 | } |
| 2186 | @ <p>Make changes to attributes of check-in |
| 2187 | @ [%z(href("%R/ci/%s",zUuid))%s(zUuid)</a>]:</p> |
| 2188 | @ <form action="%s(g.zTop)/ci_edit" method="post"><div> |
| 2189 | login_insert_csrf_secret(); |
| 2190 | @ <input type="hidden" name="r" value="%S(zUuid)" /> |
| 2191 | @ <table border="0" cellspacing="10"> |
| 2192 | |
| 2193 | @ <tr><td align="right" valign="top"><b>User:</b></td> |
| 2194 | @ <td valign="top"> |
| 2195 | @ <input type="text" name="u" size="20" value="%h(zNewUser)" /> |
| 2196 |
| --- src/info.c | |
| +++ src/info.c | |
| @@ -2183,13 +2183,13 @@ | |
| 2183 | @ <hr /> |
| 2184 | blob_reset(&suffix); |
| 2185 | } |
| 2186 | @ <p>Make changes to attributes of check-in |
| 2187 | @ [%z(href("%R/ci/%s",zUuid))%s(zUuid)</a>]:</p> |
| 2188 | form_begin(0, "%R/ci_edit"); |
| 2189 | login_insert_csrf_secret(); |
| 2190 | @ <div><input type="hidden" name="r" value="%S(zUuid)" /> |
| 2191 | @ <table border="0" cellspacing="10"> |
| 2192 | |
| 2193 | @ <tr><td align="right" valign="top"><b>User:</b></td> |
| 2194 | @ <td valign="top"> |
| 2195 | @ <input type="text" name="u" size="20" value="%h(zNewUser)" /> |
| 2196 |
+3
-3
| --- src/login.c | ||
| +++ src/login.c | ||
| @@ -565,11 +565,11 @@ | ||
| 565 | 565 | style_header("Login/Logout"); |
| 566 | 566 | @ %s(zErrMsg) |
| 567 | 567 | if( zGoto && P("anon")==0 ){ |
| 568 | 568 | @ <p>A login is required for <a href="%h(zGoto)">%h(zGoto)</a>.</p> |
| 569 | 569 | } |
| 570 | - @ <form action="login" method="post"> | |
| 570 | + form_begin(0, "%R/login"); | |
| 571 | 571 | if( zGoto ){ |
| 572 | 572 | @ <input type="hidden" name="g" value="%h(zGoto)" /> |
| 573 | 573 | } |
| 574 | 574 | @ <table class="login_out"> |
| 575 | 575 | @ <tr> |
| @@ -652,11 +652,11 @@ | ||
| 652 | 652 | if( g.perm.Password ){ |
| 653 | 653 | @ <hr /> |
| 654 | 654 | @ <p>To change your password, enter your old password and your |
| 655 | 655 | @ new password twice below then press the "Change Password" |
| 656 | 656 | @ button.</p> |
| 657 | - @ <form action="login" method="post"> | |
| 657 | + form_begin(0, "%R/login"); | |
| 658 | 658 | @ <table> |
| 659 | 659 | @ <tr><td class="login_out_label">Old Password:</td> |
| 660 | 660 | @ <td><input type="password" name="p" size="30" /></td></tr> |
| 661 | 661 | @ <tr><td class="login_out_label">New Password:</td> |
| 662 | 662 | @ <td><input type="password" name="n1" size="30" /></td></tr> |
| @@ -1260,11 +1260,11 @@ | ||
| 1260 | 1260 | uSeed = captcha_seed(); |
| 1261 | 1261 | zDecoded = captcha_decode(uSeed); |
| 1262 | 1262 | zCaptcha = captcha_render(zDecoded); |
| 1263 | 1263 | |
| 1264 | 1264 | /* Print out the registration form. */ |
| 1265 | - @ <form action="register" method="post"> | |
| 1265 | + form_begin(0, "%R/register"); | |
| 1266 | 1266 | if( P("g") ){ |
| 1267 | 1267 | @ <input type="hidden" name="g" value="%h(P("g"))" /> |
| 1268 | 1268 | } |
| 1269 | 1269 | @ <p><input type="hidden" name="cs" value="%u(uSeed)" /> |
| 1270 | 1270 | @ <table class="login_out"> |
| 1271 | 1271 |
| --- src/login.c | |
| +++ src/login.c | |
| @@ -565,11 +565,11 @@ | |
| 565 | style_header("Login/Logout"); |
| 566 | @ %s(zErrMsg) |
| 567 | if( zGoto && P("anon")==0 ){ |
| 568 | @ <p>A login is required for <a href="%h(zGoto)">%h(zGoto)</a>.</p> |
| 569 | } |
| 570 | @ <form action="login" method="post"> |
| 571 | if( zGoto ){ |
| 572 | @ <input type="hidden" name="g" value="%h(zGoto)" /> |
| 573 | } |
| 574 | @ <table class="login_out"> |
| 575 | @ <tr> |
| @@ -652,11 +652,11 @@ | |
| 652 | if( g.perm.Password ){ |
| 653 | @ <hr /> |
| 654 | @ <p>To change your password, enter your old password and your |
| 655 | @ new password twice below then press the "Change Password" |
| 656 | @ button.</p> |
| 657 | @ <form action="login" method="post"> |
| 658 | @ <table> |
| 659 | @ <tr><td class="login_out_label">Old Password:</td> |
| 660 | @ <td><input type="password" name="p" size="30" /></td></tr> |
| 661 | @ <tr><td class="login_out_label">New Password:</td> |
| 662 | @ <td><input type="password" name="n1" size="30" /></td></tr> |
| @@ -1260,11 +1260,11 @@ | |
| 1260 | uSeed = captcha_seed(); |
| 1261 | zDecoded = captcha_decode(uSeed); |
| 1262 | zCaptcha = captcha_render(zDecoded); |
| 1263 | |
| 1264 | /* Print out the registration form. */ |
| 1265 | @ <form action="register" method="post"> |
| 1266 | if( P("g") ){ |
| 1267 | @ <input type="hidden" name="g" value="%h(P("g"))" /> |
| 1268 | } |
| 1269 | @ <p><input type="hidden" name="cs" value="%u(uSeed)" /> |
| 1270 | @ <table class="login_out"> |
| 1271 |
| --- src/login.c | |
| +++ src/login.c | |
| @@ -565,11 +565,11 @@ | |
| 565 | style_header("Login/Logout"); |
| 566 | @ %s(zErrMsg) |
| 567 | if( zGoto && P("anon")==0 ){ |
| 568 | @ <p>A login is required for <a href="%h(zGoto)">%h(zGoto)</a>.</p> |
| 569 | } |
| 570 | form_begin(0, "%R/login"); |
| 571 | if( zGoto ){ |
| 572 | @ <input type="hidden" name="g" value="%h(zGoto)" /> |
| 573 | } |
| 574 | @ <table class="login_out"> |
| 575 | @ <tr> |
| @@ -652,11 +652,11 @@ | |
| 652 | if( g.perm.Password ){ |
| 653 | @ <hr /> |
| 654 | @ <p>To change your password, enter your old password and your |
| 655 | @ new password twice below then press the "Change Password" |
| 656 | @ button.</p> |
| 657 | form_begin(0, "%R/login"); |
| 658 | @ <table> |
| 659 | @ <tr><td class="login_out_label">Old Password:</td> |
| 660 | @ <td><input type="password" name="p" size="30" /></td></tr> |
| 661 | @ <tr><td class="login_out_label">New Password:</td> |
| 662 | @ <td><input type="password" name="n1" size="30" /></td></tr> |
| @@ -1260,11 +1260,11 @@ | |
| 1260 | uSeed = captcha_seed(); |
| 1261 | zDecoded = captcha_decode(uSeed); |
| 1262 | zCaptcha = captcha_render(zDecoded); |
| 1263 | |
| 1264 | /* Print out the registration form. */ |
| 1265 | form_begin(0, "%R/register"); |
| 1266 | if( P("g") ){ |
| 1267 | @ <input type="hidden" name="g" value="%h(P("g"))" /> |
| 1268 | } |
| 1269 | @ <p><input type="hidden" name="cs" value="%u(uSeed)" /> |
| 1270 | @ <table class="login_out"> |
| 1271 |
+30
-2
| --- src/style.c | ||
| +++ src/style.c | ||
| @@ -47,16 +47,18 @@ | ||
| 47 | 47 | */ |
| 48 | 48 | static int sideboxUsed = 0; |
| 49 | 49 | |
| 50 | 50 | |
| 51 | 51 | /* |
| 52 | -** List of hyperlinks that need to be resolved by javascript in | |
| 52 | +** List of hyperlinks and forms that need to be resolved by javascript in | |
| 53 | 53 | ** the footer. |
| 54 | 54 | */ |
| 55 | 55 | char **aHref = 0; |
| 56 | 56 | int nHref = 0; |
| 57 | 57 | int nHrefAlloc = 0; |
| 58 | +char **aFormAction = 0; | |
| 59 | +int nFormAction = 0; | |
| 58 | 60 | |
| 59 | 61 | /* |
| 60 | 62 | ** Generate and return a anchor tag like this: |
| 61 | 63 | ** |
| 62 | 64 | ** <a href="URL"> |
| @@ -119,23 +121,49 @@ | ||
| 119 | 121 | aHref = fossil_realloc(aHref, nHrefAlloc*sizeof(aHref[0])); |
| 120 | 122 | } |
| 121 | 123 | aHref[nHref++] = zUrl; |
| 122 | 124 | return mprintf("<a id=%d>", nHref); |
| 123 | 125 | } |
| 126 | + | |
| 127 | +/* | |
| 128 | +** Generate <form method="post" action=ARG>. The ARG value is inserted | |
| 129 | +** by javascript. | |
| 130 | +*/ | |
| 131 | +void form_begin(const char *zOtherArgs, const char *zAction, ...){ | |
| 132 | + char *zLink; | |
| 133 | + va_list ap; | |
| 134 | + if( zOtherArgs==0 ) zOtherArgs = ""; | |
| 135 | + va_start(ap, zAction); | |
| 136 | + zLink = vmprintf(zAction, ap); | |
| 137 | + va_end(ap); | |
| 138 | + if( g.perm.Hyperlink && !g.javascriptHyperlink ){ | |
| 139 | + @ <form method="POST" action="%z(zLink)" %s(zOtherArgs)> | |
| 140 | + }else{ | |
| 141 | + int n; | |
| 142 | + aFormAction = fossil_realloc(aFormAction, (nFormAction+1)*sizeof(char*)); | |
| 143 | + aFormAction[nFormAction++] = zLink; | |
| 144 | + n = nFormAction; | |
| 145 | + @ <form id="form%d(n)" method="POST" action='%R/login' %s(zOtherArgs)> | |
| 146 | + } | |
| 147 | +} | |
| 124 | 148 | |
| 125 | 149 | /* |
| 126 | 150 | ** Generate javascript that will set the href= attribute on all anchors. |
| 127 | 151 | */ |
| 128 | 152 | void style_resolve_href(void){ |
| 129 | 153 | int i; |
| 130 | - if( !g.perm.Hyperlink || !g.javascriptHyperlink || nHref==0 ) return; | |
| 154 | + if( !g.perm.Hyperlink || !g.javascriptHyperlink ) return; | |
| 155 | + if( nHref==0 && nFormAction==0 ) return; | |
| 131 | 156 | @ <script type="text/JavaScript"> |
| 132 | 157 | @ /* <![CDATA[ */ |
| 133 | 158 | @ function u(i,h){gebi(i).href=h;} |
| 134 | 159 | for(i=0; i<nHref; i++){ |
| 135 | 160 | @ u(%d(i+1),"%s(aHref[i])"); |
| 136 | 161 | } |
| 162 | + for(i=0; i<nFormAction; i++){ | |
| 163 | + @ gebi("form%d(i+1)").action="%s(aFormAction[i])"; | |
| 164 | + } | |
| 137 | 165 | @ /* ]]> */ |
| 138 | 166 | @ </script> |
| 139 | 167 | } |
| 140 | 168 | |
| 141 | 169 | /* |
| 142 | 170 |
| --- src/style.c | |
| +++ src/style.c | |
| @@ -47,16 +47,18 @@ | |
| 47 | */ |
| 48 | static int sideboxUsed = 0; |
| 49 | |
| 50 | |
| 51 | /* |
| 52 | ** List of hyperlinks that need to be resolved by javascript in |
| 53 | ** the footer. |
| 54 | */ |
| 55 | char **aHref = 0; |
| 56 | int nHref = 0; |
| 57 | int nHrefAlloc = 0; |
| 58 | |
| 59 | /* |
| 60 | ** Generate and return a anchor tag like this: |
| 61 | ** |
| 62 | ** <a href="URL"> |
| @@ -119,23 +121,49 @@ | |
| 119 | aHref = fossil_realloc(aHref, nHrefAlloc*sizeof(aHref[0])); |
| 120 | } |
| 121 | aHref[nHref++] = zUrl; |
| 122 | return mprintf("<a id=%d>", nHref); |
| 123 | } |
| 124 | |
| 125 | /* |
| 126 | ** Generate javascript that will set the href= attribute on all anchors. |
| 127 | */ |
| 128 | void style_resolve_href(void){ |
| 129 | int i; |
| 130 | if( !g.perm.Hyperlink || !g.javascriptHyperlink || nHref==0 ) return; |
| 131 | @ <script type="text/JavaScript"> |
| 132 | @ /* <![CDATA[ */ |
| 133 | @ function u(i,h){gebi(i).href=h;} |
| 134 | for(i=0; i<nHref; i++){ |
| 135 | @ u(%d(i+1),"%s(aHref[i])"); |
| 136 | } |
| 137 | @ /* ]]> */ |
| 138 | @ </script> |
| 139 | } |
| 140 | |
| 141 | /* |
| 142 |
| --- src/style.c | |
| +++ src/style.c | |
| @@ -47,16 +47,18 @@ | |
| 47 | */ |
| 48 | static int sideboxUsed = 0; |
| 49 | |
| 50 | |
| 51 | /* |
| 52 | ** List of hyperlinks and forms that need to be resolved by javascript in |
| 53 | ** the footer. |
| 54 | */ |
| 55 | char **aHref = 0; |
| 56 | int nHref = 0; |
| 57 | int nHrefAlloc = 0; |
| 58 | char **aFormAction = 0; |
| 59 | int nFormAction = 0; |
| 60 | |
| 61 | /* |
| 62 | ** Generate and return a anchor tag like this: |
| 63 | ** |
| 64 | ** <a href="URL"> |
| @@ -119,23 +121,49 @@ | |
| 121 | aHref = fossil_realloc(aHref, nHrefAlloc*sizeof(aHref[0])); |
| 122 | } |
| 123 | aHref[nHref++] = zUrl; |
| 124 | return mprintf("<a id=%d>", nHref); |
| 125 | } |
| 126 | |
| 127 | /* |
| 128 | ** Generate <form method="post" action=ARG>. The ARG value is inserted |
| 129 | ** by javascript. |
| 130 | */ |
| 131 | void form_begin(const char *zOtherArgs, const char *zAction, ...){ |
| 132 | char *zLink; |
| 133 | va_list ap; |
| 134 | if( zOtherArgs==0 ) zOtherArgs = ""; |
| 135 | va_start(ap, zAction); |
| 136 | zLink = vmprintf(zAction, ap); |
| 137 | va_end(ap); |
| 138 | if( g.perm.Hyperlink && !g.javascriptHyperlink ){ |
| 139 | @ <form method="POST" action="%z(zLink)" %s(zOtherArgs)> |
| 140 | }else{ |
| 141 | int n; |
| 142 | aFormAction = fossil_realloc(aFormAction, (nFormAction+1)*sizeof(char*)); |
| 143 | aFormAction[nFormAction++] = zLink; |
| 144 | n = nFormAction; |
| 145 | @ <form id="form%d(n)" method="POST" action='%R/login' %s(zOtherArgs)> |
| 146 | } |
| 147 | } |
| 148 | |
| 149 | /* |
| 150 | ** Generate javascript that will set the href= attribute on all anchors. |
| 151 | */ |
| 152 | void style_resolve_href(void){ |
| 153 | int i; |
| 154 | if( !g.perm.Hyperlink || !g.javascriptHyperlink ) return; |
| 155 | if( nHref==0 && nFormAction==0 ) return; |
| 156 | @ <script type="text/JavaScript"> |
| 157 | @ /* <![CDATA[ */ |
| 158 | @ function u(i,h){gebi(i).href=h;} |
| 159 | for(i=0; i<nHref; i++){ |
| 160 | @ u(%d(i+1),"%s(aHref[i])"); |
| 161 | } |
| 162 | for(i=0; i<nFormAction; i++){ |
| 163 | @ gebi("form%d(i+1)").action="%s(aFormAction[i])"; |
| 164 | } |
| 165 | @ /* ]]> */ |
| 166 | @ </script> |
| 167 | } |
| 168 | |
| 169 | /* |
| 170 |
+2
-2
| --- src/tkt.c | ||
| +++ src/tkt.c | ||
| @@ -522,11 +522,11 @@ | ||
| 522 | 522 | if( g.thTrace ) Th_Trace("BEGIN_TKTNEW<br />\n", -1); |
| 523 | 523 | ticket_init(); |
| 524 | 524 | getAllTicketFields(); |
| 525 | 525 | initializeVariablesFromDb(); |
| 526 | 526 | initializeVariablesFromCGI(); |
| 527 | - @ <form method="post" action="%s(g.zTop)/%s(g.zPath)"><p> | |
| 527 | + form_begin(0, "%R/%s", g.zPath); | |
| 528 | 528 | login_insert_csrf_secret(); |
| 529 | 529 | if( P("date_override") && g.perm.Setup ){ |
| 530 | 530 | @ <input type="hidden" name="date_override" value="%h(P("date_override"))"> |
| 531 | 531 | } |
| 532 | 532 | @ </p> |
| @@ -591,11 +591,11 @@ | ||
| 591 | 591 | if( g.thTrace ) Th_Trace("BEGIN_TKTEDIT<br />\n", -1); |
| 592 | 592 | ticket_init(); |
| 593 | 593 | getAllTicketFields(); |
| 594 | 594 | initializeVariablesFromCGI(); |
| 595 | 595 | initializeVariablesFromDb(); |
| 596 | - @ <form method="post" action="%s(g.zTop)/%s(g.zPath)"><p> | |
| 596 | + form_begin(0, "%R/%s", g.zPath); | |
| 597 | 597 | @ <input type="hidden" name="name" value="%s(zName)" /> |
| 598 | 598 | login_insert_csrf_secret(); |
| 599 | 599 | @ </p> |
| 600 | 600 | zScript = ticket_editpage_code(); |
| 601 | 601 | Th_Store("login", g.zLogin); |
| 602 | 602 |
| --- src/tkt.c | |
| +++ src/tkt.c | |
| @@ -522,11 +522,11 @@ | |
| 522 | if( g.thTrace ) Th_Trace("BEGIN_TKTNEW<br />\n", -1); |
| 523 | ticket_init(); |
| 524 | getAllTicketFields(); |
| 525 | initializeVariablesFromDb(); |
| 526 | initializeVariablesFromCGI(); |
| 527 | @ <form method="post" action="%s(g.zTop)/%s(g.zPath)"><p> |
| 528 | login_insert_csrf_secret(); |
| 529 | if( P("date_override") && g.perm.Setup ){ |
| 530 | @ <input type="hidden" name="date_override" value="%h(P("date_override"))"> |
| 531 | } |
| 532 | @ </p> |
| @@ -591,11 +591,11 @@ | |
| 591 | if( g.thTrace ) Th_Trace("BEGIN_TKTEDIT<br />\n", -1); |
| 592 | ticket_init(); |
| 593 | getAllTicketFields(); |
| 594 | initializeVariablesFromCGI(); |
| 595 | initializeVariablesFromDb(); |
| 596 | @ <form method="post" action="%s(g.zTop)/%s(g.zPath)"><p> |
| 597 | @ <input type="hidden" name="name" value="%s(zName)" /> |
| 598 | login_insert_csrf_secret(); |
| 599 | @ </p> |
| 600 | zScript = ticket_editpage_code(); |
| 601 | Th_Store("login", g.zLogin); |
| 602 |
| --- src/tkt.c | |
| +++ src/tkt.c | |
| @@ -522,11 +522,11 @@ | |
| 522 | if( g.thTrace ) Th_Trace("BEGIN_TKTNEW<br />\n", -1); |
| 523 | ticket_init(); |
| 524 | getAllTicketFields(); |
| 525 | initializeVariablesFromDb(); |
| 526 | initializeVariablesFromCGI(); |
| 527 | form_begin(0, "%R/%s", g.zPath); |
| 528 | login_insert_csrf_secret(); |
| 529 | if( P("date_override") && g.perm.Setup ){ |
| 530 | @ <input type="hidden" name="date_override" value="%h(P("date_override"))"> |
| 531 | } |
| 532 | @ </p> |
| @@ -591,11 +591,11 @@ | |
| 591 | if( g.thTrace ) Th_Trace("BEGIN_TKTEDIT<br />\n", -1); |
| 592 | ticket_init(); |
| 593 | getAllTicketFields(); |
| 594 | initializeVariablesFromCGI(); |
| 595 | initializeVariablesFromDb(); |
| 596 | form_begin(0, "%R/%s", g.zPath); |
| 597 | @ <input type="hidden" name="name" value="%s(zName)" /> |
| 598 | login_insert_csrf_secret(); |
| 599 | @ </p> |
| 600 | zScript = ticket_editpage_code(); |
| 601 | Th_Store("login", g.zLogin); |
| 602 |
+9
-7
| --- src/wiki.c | ||
| +++ src/wiki.c | ||
| @@ -160,12 +160,13 @@ | ||
| 160 | 160 | @ <li> %z(href("%R/wcontent"))List of All Wiki Pages</a> |
| 161 | 161 | @ available on this server.</li> |
| 162 | 162 | if( g.perm.ModWiki ){ |
| 163 | 163 | @ <li> %z(href("%R/modreq"))Tend to pending moderation requests</a></li> |
| 164 | 164 | } |
| 165 | - @ <li> <form method="get" action="%s(g.zTop)/wfind"><div> | |
| 166 | - @ Search wiki titles: <input type="text" name="title"/> | |
| 165 | + @ <li> | |
| 166 | + form_begin(0, "%R/wfind"); | |
| 167 | + @ <div>Search wiki titles: <input type="text" name="title"/> | |
| 167 | 168 | @ <input type="submit" /></div></form> |
| 168 | 169 | @ </li> |
| 169 | 170 | @ </ul> |
| 170 | 171 | style_footer(); |
| 171 | 172 | return; |
| @@ -357,11 +358,12 @@ | ||
| 357 | 358 | } |
| 358 | 359 | if( n<20 ) n = 20; |
| 359 | 360 | if( n>30 ) n = 30; |
| 360 | 361 | if( !isWysiwyg ){ |
| 361 | 362 | /* Traditional markup-only editing */ |
| 362 | - @ <form method="post" action="%s(g.zTop)/wikiedit"><div> | |
| 363 | + form_begin(0, "%R/wikiedit"); | |
| 364 | + @ <div> | |
| 363 | 365 | @ <textarea name="w" class="wikiedit" cols="80" |
| 364 | 366 | @ rows="%d(n)" wrap="virtual">%h(zBody)</textarea> |
| 365 | 367 | @ <br /> |
| 366 | 368 | if( db_get_boolean("wysiwyg-wiki", 0) ){ |
| 367 | 369 | @ <input type="submit" name="edit-wysiwyg" value="Wysiwyg Editor" |
| @@ -369,12 +371,12 @@ | ||
| 369 | 371 | } |
| 370 | 372 | @ <input type="submit" name="preview" value="Preview Your Changes" /> |
| 371 | 373 | }else{ |
| 372 | 374 | /* Wysiwyg editing */ |
| 373 | 375 | Blob html, temp; |
| 374 | - @ <form method="post" action="%s(g.zTop)/wikiedit" | |
| 375 | - @ onsubmit="wysiwygSubmit()"><div> | |
| 376 | + form_begin("onsubmit='wysiwygSubmit()'", "%R/wikiedit"); | |
| 377 | + @ <div> | |
| 376 | 378 | @ <input type="hidden" name="wysiwyg" value="1" /> |
| 377 | 379 | blob_zero(&temp); |
| 378 | 380 | wiki_convert(&wiki, &temp, 0); |
| 379 | 381 | blob_zero(&html); |
| 380 | 382 | htmlTidy(blob_str(&temp), &html); |
| @@ -419,11 +421,11 @@ | ||
| 419 | 421 | } |
| 420 | 422 | } |
| 421 | 423 | style_header("Create A New Wiki Page"); |
| 422 | 424 | @ <p>Rules for wiki page names:</p> |
| 423 | 425 | well_formed_wiki_name_rules(); |
| 424 | - @ <form method="post" action="%s(g.zTop)/wikinew"> | |
| 426 | + form_begin(0, "%R/wikinew"); | |
| 425 | 427 | @ <p>Name of new wiki page: |
| 426 | 428 | @ <input style="width: 35;" type="text" name="name" value="%h(zName)" /> |
| 427 | 429 | @ <input type="submit" value="Create" /> |
| 428 | 430 | @ </p></form> |
| 429 | 431 | if( zName[0] ){ |
| @@ -544,11 +546,11 @@ | ||
| 544 | 546 | wiki_convert(&preview, 0, 0); |
| 545 | 547 | @ <hr> |
| 546 | 548 | blob_reset(&preview); |
| 547 | 549 | } |
| 548 | 550 | zUser = PD("u", g.zLogin); |
| 549 | - @ <form method="post" action="%s(g.zTop)/wikiappend"> | |
| 551 | + form_begin(0, "%R/wikiappend"); | |
| 550 | 552 | login_insert_csrf_secret(); |
| 551 | 553 | @ <input type="hidden" name="name" value="%h(zPageName)" /> |
| 552 | 554 | @ Your Name: |
| 553 | 555 | @ <input type="text" name="u" size="20" value="%h(zUser)" /><br /> |
| 554 | 556 | @ Comment to append:<br /> |
| 555 | 557 |
| --- src/wiki.c | |
| +++ src/wiki.c | |
| @@ -160,12 +160,13 @@ | |
| 160 | @ <li> %z(href("%R/wcontent"))List of All Wiki Pages</a> |
| 161 | @ available on this server.</li> |
| 162 | if( g.perm.ModWiki ){ |
| 163 | @ <li> %z(href("%R/modreq"))Tend to pending moderation requests</a></li> |
| 164 | } |
| 165 | @ <li> <form method="get" action="%s(g.zTop)/wfind"><div> |
| 166 | @ Search wiki titles: <input type="text" name="title"/> |
| 167 | @ <input type="submit" /></div></form> |
| 168 | @ </li> |
| 169 | @ </ul> |
| 170 | style_footer(); |
| 171 | return; |
| @@ -357,11 +358,12 @@ | |
| 357 | } |
| 358 | if( n<20 ) n = 20; |
| 359 | if( n>30 ) n = 30; |
| 360 | if( !isWysiwyg ){ |
| 361 | /* Traditional markup-only editing */ |
| 362 | @ <form method="post" action="%s(g.zTop)/wikiedit"><div> |
| 363 | @ <textarea name="w" class="wikiedit" cols="80" |
| 364 | @ rows="%d(n)" wrap="virtual">%h(zBody)</textarea> |
| 365 | @ <br /> |
| 366 | if( db_get_boolean("wysiwyg-wiki", 0) ){ |
| 367 | @ <input type="submit" name="edit-wysiwyg" value="Wysiwyg Editor" |
| @@ -369,12 +371,12 @@ | |
| 369 | } |
| 370 | @ <input type="submit" name="preview" value="Preview Your Changes" /> |
| 371 | }else{ |
| 372 | /* Wysiwyg editing */ |
| 373 | Blob html, temp; |
| 374 | @ <form method="post" action="%s(g.zTop)/wikiedit" |
| 375 | @ onsubmit="wysiwygSubmit()"><div> |
| 376 | @ <input type="hidden" name="wysiwyg" value="1" /> |
| 377 | blob_zero(&temp); |
| 378 | wiki_convert(&wiki, &temp, 0); |
| 379 | blob_zero(&html); |
| 380 | htmlTidy(blob_str(&temp), &html); |
| @@ -419,11 +421,11 @@ | |
| 419 | } |
| 420 | } |
| 421 | style_header("Create A New Wiki Page"); |
| 422 | @ <p>Rules for wiki page names:</p> |
| 423 | well_formed_wiki_name_rules(); |
| 424 | @ <form method="post" action="%s(g.zTop)/wikinew"> |
| 425 | @ <p>Name of new wiki page: |
| 426 | @ <input style="width: 35;" type="text" name="name" value="%h(zName)" /> |
| 427 | @ <input type="submit" value="Create" /> |
| 428 | @ </p></form> |
| 429 | if( zName[0] ){ |
| @@ -544,11 +546,11 @@ | |
| 544 | wiki_convert(&preview, 0, 0); |
| 545 | @ <hr> |
| 546 | blob_reset(&preview); |
| 547 | } |
| 548 | zUser = PD("u", g.zLogin); |
| 549 | @ <form method="post" action="%s(g.zTop)/wikiappend"> |
| 550 | login_insert_csrf_secret(); |
| 551 | @ <input type="hidden" name="name" value="%h(zPageName)" /> |
| 552 | @ Your Name: |
| 553 | @ <input type="text" name="u" size="20" value="%h(zUser)" /><br /> |
| 554 | @ Comment to append:<br /> |
| 555 |
| --- src/wiki.c | |
| +++ src/wiki.c | |
| @@ -160,12 +160,13 @@ | |
| 160 | @ <li> %z(href("%R/wcontent"))List of All Wiki Pages</a> |
| 161 | @ available on this server.</li> |
| 162 | if( g.perm.ModWiki ){ |
| 163 | @ <li> %z(href("%R/modreq"))Tend to pending moderation requests</a></li> |
| 164 | } |
| 165 | @ <li> |
| 166 | form_begin(0, "%R/wfind"); |
| 167 | @ <div>Search wiki titles: <input type="text" name="title"/> |
| 168 | @ <input type="submit" /></div></form> |
| 169 | @ </li> |
| 170 | @ </ul> |
| 171 | style_footer(); |
| 172 | return; |
| @@ -357,11 +358,12 @@ | |
| 358 | } |
| 359 | if( n<20 ) n = 20; |
| 360 | if( n>30 ) n = 30; |
| 361 | if( !isWysiwyg ){ |
| 362 | /* Traditional markup-only editing */ |
| 363 | form_begin(0, "%R/wikiedit"); |
| 364 | @ <div> |
| 365 | @ <textarea name="w" class="wikiedit" cols="80" |
| 366 | @ rows="%d(n)" wrap="virtual">%h(zBody)</textarea> |
| 367 | @ <br /> |
| 368 | if( db_get_boolean("wysiwyg-wiki", 0) ){ |
| 369 | @ <input type="submit" name="edit-wysiwyg" value="Wysiwyg Editor" |
| @@ -369,12 +371,12 @@ | |
| 371 | } |
| 372 | @ <input type="submit" name="preview" value="Preview Your Changes" /> |
| 373 | }else{ |
| 374 | /* Wysiwyg editing */ |
| 375 | Blob html, temp; |
| 376 | form_begin("onsubmit='wysiwygSubmit()'", "%R/wikiedit"); |
| 377 | @ <div> |
| 378 | @ <input type="hidden" name="wysiwyg" value="1" /> |
| 379 | blob_zero(&temp); |
| 380 | wiki_convert(&wiki, &temp, 0); |
| 381 | blob_zero(&html); |
| 382 | htmlTidy(blob_str(&temp), &html); |
| @@ -419,11 +421,11 @@ | |
| 421 | } |
| 422 | } |
| 423 | style_header("Create A New Wiki Page"); |
| 424 | @ <p>Rules for wiki page names:</p> |
| 425 | well_formed_wiki_name_rules(); |
| 426 | form_begin(0, "%R/wikinew"); |
| 427 | @ <p>Name of new wiki page: |
| 428 | @ <input style="width: 35;" type="text" name="name" value="%h(zName)" /> |
| 429 | @ <input type="submit" value="Create" /> |
| 430 | @ </p></form> |
| 431 | if( zName[0] ){ |
| @@ -544,11 +546,11 @@ | |
| 546 | wiki_convert(&preview, 0, 0); |
| 547 | @ <hr> |
| 548 | blob_reset(&preview); |
| 549 | } |
| 550 | zUser = PD("u", g.zLogin); |
| 551 | form_begin(0, "%R/wikiappend"); |
| 552 | login_insert_csrf_secret(); |
| 553 | @ <input type="hidden" name="name" value="%h(zPageName)" /> |
| 554 | @ Your Name: |
| 555 | @ <input type="text" name="u" size="20" value="%h(zUser)" /><br /> |
| 556 | @ Comment to append:<br /> |
| 557 |