[racket] Dynamic Templates?

From: Jay McCarthy (jay.mccarthy at gmail.com)
Date: Wed Jun 5 16:45:56 EDT 2013

While it is supposed to be pithy, it is also serious.

When I wrote it, I imagine that people would do something like this:

#lang racket/base
(require web-server/templates)

(define (template-content t x)
  (eval #`(let ([x #,x]) (include-template #,t))))

(template-content "t.txt" 5)
(template-content "t.txt" 6)

and trust that the template wouldn't include @(system "rm -fr /"). I
think that a simple eval works just fine for when you, the programmer,
want to change the content dynamic (although I'd say it is better to
use the web-server language so you can restart with the same
continuations, etc.)

Your solution is great for a template that a user provides, although
it has the hole that the template could call @include-template and
maybe find itself and go into a infinite loop, so it's not totally
"secure" unless you use a sandbox.


On Wed, Jun 5, 2013 at 1:53 PM, Joe Gibbs Politz <joe at cs.brown.edu> wrote:
> I'm writing a web server in a #lang that doesn't support macros or
> syntactic abstraction.  I would like to be able to use some sort of
> templating dynamically with bindings given by values, e.g.
> template.render("page-with-hole-for-username.html", { username: "Joe" })
> The FAQ (http://docs.racket-lang.org/web-server/faq.html#(part._.How_do_.I_use_templates__dynamically__))
> in the documentation for templates ends with this pithy
> recommendation:
> "If you insist on dynamicism, there is always eval."
> I assume this isn't intended seriously, and instead to discourage what
> I'm asking about, but I'm unfortunately not seeing another way to
> write my program.  The code at the end of this message seems like the
> best I can do while being relatively safe, but also like a dubious
> inclusion on a web server given the eval.
> Is this the best I can hope for?  Is there another collection I should
> be looking into?  Any other recommendations?
> Thanks!
> Joe P.
> #lang racket/base
> (require
>   web-server/templates)
> (define (render-template filename dict)
>   (define namespace-for-template (make-empty-namespace))
>   (namespace-attach-module (current-namespace) 'web-server/templates
> namespace-for-template)
>   (hash-map dict
>     (lambda (key value)
>       (define name-of-identifier (string->symbol key))
>       (namespace-set-variable-value!
>         name-of-identifier
>         value
>         #f
>         namespace-for-template)))
>   (parameterize [(current-namespace namespace-for-template)]
>     (namespace-require 'web-server/templates))
>   (define to-eval #`(include-template #,(datum->syntax
> #'render-template filename)))
>   (eval to-eval namespace-for-template))
> ____________________
>   Racket Users list:
>   http://lists.racket-lang.org/users

Jay McCarthy <jay at cs.byu.edu>
Assistant Professor / Brigham Young University

"The glory of God is Intelligence" - D&C 93

Posted on the users mailing list.