[racket] Escaping things in templates?
web-server/template and Scribble produce strings, that's why you
create a response by plopping in the string from include-template. The
Web Server has no idea what kind of string you making, so it imposes
no special XML rules.
The template-less version your servlet does exactly what you seem to want:
#lang web-server/insta
(require web-server/templates)
(define (start req)
(let ([some-input
(if (exists-binding? 'some-input (request-bindings req))
(extract-binding/single 'some-input (request-bindings req))
"nothing yet")])
(response/xexpr
`(html
(head (title "Testing"))
(body
(h1 "You said:" ,some-input)
(form ([method "get"] [action "#"])
(input ([name "some-input"] [type "text"]))
(input ([type "submit"]))))))))
But if you want to use templates to produce XML strings and get XML
quoting, then you have to quote explicitly by treating your user's
string as if it is a string Xexpr (the representation for XML in the
Web Server):
#lang web-server/insta
(require web-server/templates
xml)
(define (start req)
(let ([some-input
(xexpr->string
(if (exists-binding? 'some-input (request-bindings req))
(extract-binding/single 'some-input (request-bindings req))
"nothing yet"))])
(response/full 200 #"Okay" (current-seconds) TEXT/HTML-MIME-TYPE
empty
(list (string->bytes/utf-8 (include-template
"static.htm"))))))
Notice the addition of the (require xml) and the single call to
(xexpr->string ...) around the user's input.
Jay
On Sat, Oct 22, 2011 at 8:38 PM, Michael W <mwilber at uccs.edu> wrote:
> Hello! Thanks for making racket! It's the coolest.
>
> The web server template documentation:
> http://docs.racket-lang.org/web-server/templates.html has several
> great examples of templates, but it doesn't mention whether
> strings included in templates are entity-escaped XML or not.
>
> More seriously, searching for "escape" in the help desk doesn't
> even mention anything useful. It looks like the only way of
> creating templates that escape the variables included in them is
> by adding (require xml/private/writer) to the top of your script
> and saying @escape[foo escape-table] every single time you use a
> variable in your templates! Surely there must be a better way?
>
> Am I doing it wrong? Take a look at this simple servlet, which
> simply spits out what you type in a form:
> https://gist.github.com/1306759 Try typing <u>test</u> for
> example, or perhaps some javascript.
>
> Certain web frameworks try to implicitly protect you from these
> kinds of mistakes. Take Django, for example.
> https://docs.djangoproject.com/en/dev/ref/templates/builtins/?from=olddocs
> The Django team are so upfront about their template system's
> escaping behavior that it's literally the first thing they
> mention in the first section of their documentation.
>
> Other template systems intentionally make it harder to include
> unescaped content by using syntactic differentiation. Mustache,
> for example, requires you to use triple braces like
> {{{some-input}}} if you want to include some-input as unescaped.
> https://github.com/janl/mustache.js/
>
> What's the best way of solving this? Obviously we can't change
> scribble, but could we have, say, (include-template) add an
> @escape[...] function to the namespace just before it evaluates
> the template?
>
> If I'm missing something, please feel free to flame away. ;) If
> not, I'd love to help fix this by writing a patch or some
> documentation or something.
>
> Thanks again for such a nice framework.
>
> --
> For the Future!
> _mike
> _________________________________________________
> For list-related administrative tasks:
> http://lists.racket-lang.org/listinfo/users
>
--
Jay McCarthy <jay at cs.byu.edu>
Assistant Professor / Brigham Young University
http://faculty.cs.byu.edu/~jay
"The glory of God is Intelligence" - D&C 93