Remix.run Logo
itishappy 9 days ago

Oh, I'm pretty sure I didn't understand your example and am probably missing something obvious. That's why I'm here asking dumb questions!

I think I'm following more, and I see how you can accomplish this by encapsulating the rendering, but I'm still not seeing how this is possible with user facing f-strings. Think you can write up a quick example?

ratorx 9 days ago | parent [-]

Added example to parent comment.

itishappy 9 days ago | parent [-]

Thanks mate! (BTW: Indenting code with four spaces makes HN format it like code.)

So the thing I'm still not getting from your example is allowing the template itself to be customized.

   evil = "<script>alert('evil')</script>"
   template1 = t"<p>{evil}</p>"
   template2 = t"<h1>{evil}</h1>"
   html(template1)
   html(template2)
ratorx 9 days ago | parent [-]

template1 is a function that takes in a parameter evil (with a SanitisedString type that wraps a regular str) and returns the fully expanded str. It is implemented by just returning an f-string equivalent to the t-string in your example. Same with template2.

Using the SanitisedString type forces the user to explicitly call a sanitiser function that returns a SanitisedString and prevents them from passing in an unsanitised str.

itishappy 8 days ago | parent [-]

You're just handing off responsibility for sanitization to the user instead of the library author.

With t-strings the rendering function is responsible for sanitization, and users can pass unrendered templates to it.

With f-strings there's no concept of an unrendered template, it just immediately becomes a string. Whoever is creating the template therefore has to be careful what they put in it.