Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
Comment: | Add a Makefile for MacOS. Add wapp-param. Add the %string(...) substitution for wapp-subst. |
---|---|
Downloads: | Tarball | ZIP archive |
Timelines: | family | ancestors | descendants | both | trunk |
Files: | files | file ages | folders |
SHA3-256: |
1b25f9e6edc26e4ad1d156436006967e |
User & Date: | drh 2018-01-28 19:46:52.281 |
Context
2018-01-28
| ||
20:04 | Add the wapp-trim command. (check-in: ba9c27b26a user: drh tags: trunk) | |
19:46 | Add a Makefile for MacOS. Add wapp-param. Add the %string(...) substitution for wapp-subst. (check-in: 1b25f9e6ed user: drh tags: trunk) | |
17:45 | When the value of a cookie is an empty string, set its max age to 1 second so that it will be cleared from the browser. (check-in: b76fa41ae9 user: drh tags: trunk) | |
Changes
Added Makefile.macos.
> > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | #!/usr/bin/make CC = gcc -O0 -framework CoreFoundation TCLLIB = /Users/drh/tcl/lib/libtcl8.7.a -lm -lz -lpthread -ldl TCLINC = /Users/drh/tcl/include TCLSH = /Users/drh/tcl/bin/tclsh8.7 all: wapptclsh wapptclsh: wapptclsh.c $(CC) -I. -I$(TCLINC) -o $@ wapptclsh.c $(TCLLIB) wapptclsh.c: wapptclsh.c.in wapp.tcl wapptclsh.tcl tclsqlite3.c mkccode.tcl $(TCLSH) mkccode.tcl wapptclsh.c.in >$@ clean: rm wapptclsh wapptclsh.c |
Changes to README.md.
︙ | ︙ | |||
88 89 90 91 92 93 94 | Information about each HTTP request is encoded in the global ::wapp dict variable. The following sample program shows the information available in ::wapp. > package require wapp proc wapp-default {} { | < | | 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 | Information about each HTTP request is encoded in the global ::wapp dict variable. The following sample program shows the information available in ::wapp. > package require wapp proc wapp-default {} { wapp-subst {<h1>Hello, World!</h1>\n} set B [wapp-param BASE_URL] wapp-subst {<p>See the <a href='%html($B)/env'>Wapp } wapp-subst {Environment</a></p>\n} } proc wapp-page-env {} { global wapp wapp-subst {<h1>Wapp Environment</h1>\n<pre>\n} foreach var [lsort [dict keys $wapp]] { |
︙ | ︙ | |||
258 259 260 261 262 263 264 | Add _TEXT_ to the web page output currently under construction. _TEXT_ must not contain any TCL variable or command substitutions. + **wapp-subst** _TEXT_ The _TEXT_ argument should be enclosed in {...} to prevent substitutions. The "wapp-subst" command itself will do all necessary backslash substitutions. Command and variable substitutions only occur within | | > > | > | > > > | | | | 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 | Add _TEXT_ to the web page output currently under construction. _TEXT_ must not contain any TCL variable or command substitutions. + **wapp-subst** _TEXT_ The _TEXT_ argument should be enclosed in {...} to prevent substitutions. The "wapp-subst" command itself will do all necessary backslash substitutions. Command and variable substitutions only occur within "%html(...)", "%url(...)", "%qp(...)", "%string(...)", and "%unsafe(...)". The substitutions are escaped (except in the case of "%unsafe(...)") so that the result is safe for inclusion within the body of an HTML document, a URL, a query parameter, or a javascript string literal, respectively. + **wapp-mimetype** _MIMETYPE_ Set the MIME-type for the generated web page. The default is "text/html". + **wapp-reply-code** _CODE_ Set the reply-code for the HTTP request. The default is "200 Ok". + **wapp-redirect** _TARGET-URL_ Cause an HTTP redirect to the specified URL. + **wapp-reset** Reset the web page under construction back to an empty string. + **wapp-set-cookie** _NAME_ _VALUE_ Cause the cookie _NAME_ to be set to _VALUE_. + **wapp-clear-cookie** _NAME_ Erase the cookie _NAME_. + **wapp-safety-check** Examine all TCL procedures in the application and report errors about unsafe usage of "wapp". + **wapp-unsafe** _TEXT_ Add _TEXT_ to the web page under construction even though _TEXT_ does contain TCL variable and command substitutions. The application developer must ensure that the variable and command substitutions does not allow XSS attacks. Avoid using this command. The use of "wapp-subst" is preferred in most situations. + **wapp-escape-html** _TEXT_ Add _TEXT_ to the web page under construction after first escaping any HTML markup contained with _TEXT_. This command is equivalent to "wapp-subst {%html(_TEXT_)}". + **wapp-escape-url** _TEXT_ Add _TEXT_ to the web page under construction after first escaping any characters so that the result is safe to include as the value of a query parameter on a URL. This command is equivalent to "wapp-subst {%url(_TEXT_)}". The following additional interfaces are envisioned, but are not yet |
︙ | ︙ |
Changes to test01.tcl.
1 2 3 4 5 6 | # Invoke as "tclsh test01.tcl" and then surf the website that pops up # to verify the logic in wapp. # source wapp.tcl proc wapp-default {} { global wapp | | | > > > | | | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 | # Invoke as "tclsh test01.tcl" and then surf the website that pops up # to verify the logic in wapp. # source wapp.tcl proc wapp-default {} { global wapp set B [wapp-param BASE_URL] set R [wapp-param SCRIPT_NAME] wapp "<h1>Hello, World!</h1>\n" wapp "<ol>" wapp-unsafe "<li><p><a href='$R/env'>Wapp Environment</a></p>\n" wapp-subst {<li><p><a href='%html($B)/fullenv'>Full Environment</a>\n} set crazy [lsort [dict keys $wapp]] wapp-subst {<li><p><a href='%html($B)/env?keys=%url($crazy)'>} wapp "Environment with crazy URL\n" wapp-subst {<li><p><a href='%html($B)/lint'>Lint</a>\n} wapp-subst {<li><p><a href='%html($B)/errorout'>Deliberate error</a>\n} wapp-subst {<li><p><a href='%html($B)/encodings'>Encoding checks</a>\n} wapp-subst {<li><p><a href='%html($B)/redirect'>Redirect to env</a>\n} set x "%string(...)" set v abc'def\"ghi\\jkl wapp-subst {<li>%html($x) substitution test: "%string($v)"\n} wapp "</ol>" if {[dict exists $wapp showenv]} { wapp-page-env } } proc wapp-page-redirect {} { wapp-redirect env } proc wapp-page-env {} { global wapp wapp-set-cookie env-cookie simple wapp "<h1>Wapp Environment</h1>\n" wapp-unsafe "<form method='GET' action='[wapp-param SELF_URL]'>\n" wapp "<input type='checkbox' name='showhdr'" if {[dict exists $wapp showhdr]} { wapp " checked" } wapp "> Show Header\n" wapp "<input type='submit' value='Go'>\n" wapp "</form>" wapp "<pre>\n" foreach var [lsort [dict keys $wapp]] { if {[string index $var 0]=="." && ($var!=".header" || ![dict exists $wapp showhdr])} continue wapp-escape-html "$var = [list [dict get $wapp $var]]\n" } wapp "</pre>" wapp-unsafe "<p><a href='[wapp-param BASE_URL]/'>Home</a></p>\n" } proc wapp-page-fullenv {} { global wapp wapp-set-cookie env-cookie full wapp "<h1>Wapp Full Environment</h1>\n" wapp-unsafe "<form method='POST' action='[wapp-param SELF_URL]'>\n" wapp "<input type='checkbox' name='var1'" if {[dict exists $wapp showhdr]} { wapp " checked" } wapp "> Var1\n" wapp "<input type='submit' name='s1' value='Go'>\n" wapp "<input type='hidden' name='hidden-parameter-1' " |
︙ | ︙ |
Changes to wapp.tcl.
︙ | ︙ | |||
58 59 60 61 62 63 64 | # escaped for safe insertion into HTML. %url(...) substitions encode the # argument for safe insertion into query parameters of URLs. Backslash # substitutions are also performed, but variable substitutions are not, # except within %html() and %url(). # proc wapp-subst {txt} { global wapp | | > > > | 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 | # escaped for safe insertion into HTML. %url(...) substitions encode the # argument for safe insertion into query parameters of URLs. Backslash # substitutions are also performed, but variable substitutions are not, # except within %html() and %url(). # proc wapp-subst {txt} { global wapp regsub -all {%(html|url|qp|string|unsafe)\(([^)]+)\)} $txt \ {[wappInt-enc-\1 "\2"]} txt dict append wapp .reply [uplevel 1 [list subst -novariables $txt]] } # There must be a wappInt-enc-NAME routine for each possible substitution # in wapp-subst. Thus there are routines for "html", "url", "qp", and "unsafe". # # wappInt-enc-html Escape text so that it is safe to use in the # body of an HTML document. # # wappInt-enc-url Escape text so that it is safe to pass as an # argument to href= and src= attributes in HTML. # # wappInt-enc-qp Escape text so that it is safe to use as the # value of a query parameter in a URL or in # post data or in a cookie. # # wappInt-enc-string Escape ", ', and \ for using inside of a # javascript string literal. # # wappInt-enc-unsafe Perform no encoding at all. Unsafe. # proc wappInt-enc-html {txt} { return [string map {& & < < > >} $txt] } proc wappInt-enc-unsafe {txt} { |
︙ | ︙ | |||
102 103 104 105 106 107 108 109 110 111 112 113 114 115 | set s [subst -novar -noback $s] } if {[regsub -all {[{}]} $s {[wappInt-%HHchar \\&]} s]} { set s [subst -novar -noback $s] } return $s } # This is a helper routine for wappInt-enc-url and wappInt-enc-qp. It returns # an appropriate %HH encoding for the single character c. If c is a unicode # character, then this routine might return multiple bytes: %HH%HH%HH # proc wappInt-%HHchar {c} { if {$c==" "} {return +} | > > > | 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 | set s [subst -novar -noback $s] } if {[regsub -all {[{}]} $s {[wappInt-%HHchar \\&]} s]} { set s [subst -novar -noback $s] } return $s } proc wappInt-enc-string {s} { return [string map {\\ \\\\ \" \\\" ' \\'} $s] } # This is a helper routine for wappInt-enc-url and wappInt-enc-qp. It returns # an appropriate %HH encoding for the single character c. If c is a unicode # character, then this routine might return multiple bytes: %HH%HH%HH # proc wappInt-%HHchar {c} { if {$c==" "} {return +} |
︙ | ︙ | |||
178 179 180 181 182 183 184 185 186 187 188 189 190 191 | # Redirect to a different web page # proc wapp-redirect {uri} { wapp-reply-code {302 found} wapp-reply-extra Location $uri } # Examine the bodys of all procedures in this program looking for # unsafe calls to "wapp". Return a text string containing warnings. # Return an empty string if all is ok. # # This routine is advisory only. It misses some constructs that are # dangerous and flags others that are safe. | > > > > > > > > | 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 | # Redirect to a different web page # proc wapp-redirect {uri} { wapp-reply-code {302 found} wapp-reply-extra Location $uri } # Return the value of a query parameter or environment variable. # proc wapp-param {name {dflt {}}} { global wapp if {![dict exists $wapp $name]} {return $dflt} return [dict get $wapp $name] } # Examine the bodys of all procedures in this program looking for # unsafe calls to "wapp". Return a text string containing warnings. # Return an empty string if all is ok. # # This routine is advisory only. It misses some constructs that are # dangerous and flags others that are safe. |
︙ | ︙ |