Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

proposal: html/template: export filters and escapers #70375

Open
apleshkov opened this issue Nov 15, 2024 · 5 comments
Open

proposal: html/template: export filters and escapers #70375

apleshkov opened this issue Nov 15, 2024 · 5 comments
Labels
Milestone

Comments

@apleshkov
Copy link

Proposal Details

I try to create a tool to translate text/template and html/template to go source code.

For example:

<div>{{.}}</div>

translates to smth like this:

func Render(w io.Writer, data string) {
  io.WriteString(w, HTMLEscape(data))
}

Go has great escaping mechanism for html, but it's non-published API unfortunately.

From go v1.23 the //go:linkname directive is restricted, so it has made some things impossible. Re-implementing the whole escaping mechanism from scratch feels like very bad option.

It's possible to enrich the template tree by calling the html.template's Execute method, and it doesn't matter if it fails or not, cause the current implementation adds additional escapers before the actual execution. This trick works now, but could be broken at any moment, so it'd be great to publish the escape method https://cs.opensource.google/go/go/+/refs/tags/go1.23.3:src/html/template/template.go;l=96

The other huge problem is the unpublished filters and escapers themselves: https://cs.opensource.google/go/go/+/refs/tags/go1.23.3:src/html/template/escape.go;l=64

I couldn't find a way to call them w/o //go:linkname. It's possible to create a special template like {{_html_template_attrescaper .}} and execute it. It does work, but it's very slow. So it would be awesome to expose all the escapers from the funcMap variable.

These updates shouldn't break the API, but instead other tools can reuse it. It could be similar translators, or even other html template engines, cause escaping is the core part anyway.

@gopherbot gopherbot added this to the Proposal milestone Nov 15, 2024
@seankhliao
Copy link
Member

what exactly are you proposing? things like the html escaper are already public
https://pkg.go.dev/html/template#HTMLEscapeString

@seankhliao seankhliao added the WaitingForInfo Issue is not actionable because of missing required information, which needs to be provided. label Nov 15, 2024
@apleshkov
Copy link
Author

apleshkov commented Nov 15, 2024

They are, but I need other escapers & filters.

So basically just renaming of:

func (*Template) escape() error             -> func (*Template) Escape() error

func attrEscaper(...any) string             -> func AttrEscaper(...any) string
func commentEscaper(...any) string          -> func CommentEscaper(...any) string
func cssEscaper(...any) string              -> func CSSEscaper(...any) string
func cssValueFilter(...any) string          -> func CSSValueFilter(...any) string
func htmlNameFilter(...any) string          -> func HTMLNameFilter(...any) string
func htmlEscaper(...any) string             -> func HTMLEscaper(...any) string
func jsRegexpEscaper(...any) string         -> func JSRegexpEscaper(...any) string
func jsStrEscaper(...any) string            -> func JSStrEscaper(...any) string
func jsTmplLitEscaper(...any) string        -> func JSTmplLitEscaper(...any) string
func jsValEscaper(...any) string            -> func JSValEscaper(...any) string
func htmlNospaceEscaper(...any) string      -> func HTMLNospaceEscaper(...any) string
func rcdataEscaper(...any) string           -> func RCDataEscaper(...any) string
func srcsetFilterAndEscaper(...any) string  -> func SrcsetFilterAndEscaper(...any) string
func urlEscaper(...any) string              -> func URLEscaper(...any) string
func urlFilter(...any) string               -> func URLFilter(...any) string
func urlNormalizer(...any) string           -> func URLNormalizer(...any) string

to make them available from the outside code solves the issue.

@seankhliao seankhliao removed the WaitingForInfo Issue is not actionable because of missing required information, which needs to be provided. label Nov 15, 2024
@seankhliao
Copy link
Member

It seems other packages do fine with implementing their own escapers, it's not clear to me that this is worth expanding the html/template API surface for this?

e.g. https://pkg.go.dev/github.com/a-h/templ#section-readme

@ianlancetaylor ianlancetaylor moved this to Incoming in Proposals Nov 15, 2024
@apleshkov
Copy link
Author

apleshkov commented Nov 16, 2024

The current functions are already well-tested, ready for production, and get all necessary patches, especially sucurity-related.
Also some escapers are already public. Even the IsTrue function is.

P.S.
Did a quick research about templ and found this: https://github.com/a-h/templ/blob/v0.2.793/safehtml/style.go#L1,
which led me to https://github.com/google/safehtml. It's cool, but unfortunately claimed unofficial by the authors.

@seankhliao seankhliao changed the title proposal: html/template: expose filters and escapers proposal: html/template: export filters and escapers Nov 21, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
Status: Incoming
Development

No branches or pull requests

4 participants