With the current model, I’d make a first pass of this sort of functionality by 
doing:

1. Define a HtmlEncoded wrapping struct that indicated a value was meant to be 
safe to output directly, rather than be encoded. This would make encoding safe 
by default (opt out)
2. HTML content built via string interpolation would escape any data input not 
wrapped in a HtmlEncoded struct.
3. Define functions for the common tags which output nested html data, rather 
than having people write the tags themselves.

With all that, your code would probably be:

let title = "<script>boom();</script>"
result.render(h1(title)); // outputs '<h1>&lt;script>boom();&lt;/script></h1>'

4. (maybe) HtmlEncoded is ExpressibleByStringInterpolation, so that

var username = “<script>boom();</script>”
var encoded:HtmlEncoded = “Hello, \(username)”
print(encoded) //  ‘Hello, &lt;script>boom();&lt;/script>'

This is somewhat analogous to Rails 3’s String.html_safe functionality, and 
avoids interpreting string safety based on a string being a literal .

-DW

> On Jan 20, 2017, at 9:27 AM, Gwendal Roué via swift-evolution 
> <[email protected]> wrote:
> 
>> One ask - make string interpolation great again?
> 
> I have a dream, that ExpressibleByStringInterpolation would allow to 
> distinguish literal segments and embedded inputs.
> 
> Today, the documentation of this protocol [1] says:
> 
>       "One cookie: $\(price), \(number) cookies: $\(price * number)."
>       // <=>
>       let message = String(stringInterpolation:
>               String(stringInterpolationSegment: "One cookie: $"),
>               String(stringInterpolationSegment: price),
>               String(stringInterpolationSegment: ", "),
>               String(stringInterpolationSegment: number),
>               String(stringInterpolationSegment: " cookies: $"),
>               String(stringInterpolationSegment: price * number),
>               String(stringInterpolationSegment: "."))
> 
> This means that ExpressibleByStringInterpolation can't distinguish "foo" from 
> `bar` in "foo\(bar)".
> 
> If this distinction were possible, some nice features could emerge, such as 
> context-sensitive escaping:
> 
>       // func render(_ html: HTML)
>       let title = "<script>boom();</script>"
>       render("<h1>\(title)</h1>") // escapes input
>       
>       // func query(_ sql: SQL)
>       let name = "Robert'); DROP TABLE students; --"
>       query("SELECT * FROM students WHERE name = \(name)") // avoids SQL 
> injection
> 
> Ideally, a solution for multi-line literals (for strings and interpolated 
> strings) would be found, too.
> 
> I wish the manifesto would address these topics as well :-)
> 
> Regards,
> Gwendal Roué
> 
> [1] 
> https://developer.apple.com/reference/swift/expressiblebystringinterpolation
> 
> _______________________________________________
> swift-evolution mailing list
> [email protected]
> https://lists.swift.org/mailman/listinfo/swift-evolution

_______________________________________________
swift-evolution mailing list
[email protected]
https://lists.swift.org/mailman/listinfo/swift-evolution

Reply via email to