• Russ Cox's avatar
    html/template, text/template: docs and fixes for template redefinition · 604146ce
    Russ Cox authored
    All prior versions of Go have allowed redefining empty templates
    to become non-empty. Unfortunately, that has never consistently
    taken effect in html/template after the first execution:
    
    	// define and execute
    	t := template.New("root")
    	t.Parse(`{{define "T"}}{{end}}<a href="{{template "T"}}">`)
    	t.Execute(w, nil) // <a href="">
    
    	// redefine
    	t.Parse(`{{define "T"}}my.url{{end}}`) // succeeds, but ignored
    	t.Execute(w, nil) // <a href="">
    
    When Go 1.6 added {{block...}} to text/template, that loosened the
    redefinition rules to allow redefinition at any time. The loosening was
    undone a bit in html/template, although inconsistently:
    
    	// define and execute
    	t := template.New("root")
    	t.Parse(`{{define "T"}}body{{end}}`)
    	t.Lookup("T").Execute(ioutil.Discard, nil)
    
    	// attempt to redefine
    	t.Parse(`{{define "T"}}body{{end}}`) // rejected in all Go versions
    	t.Lookup("T").Parse("body") // OK as of Go 1.6, likely unintentionally
    
    Like in the empty->non-empty case, whether future execution takes
    notice of a redefinition basically can't be explained without going into
    the details of the template escape analysis.
    
    Address both the original inconsistencies in whether a redefinition
    would have any effect and the new inconsistencies about whether a
    redefinition is allowed by adopting a new rule: no parsing or modifying
    any templates after the first execution of any template in the same set.
    Template analysis begins at first execution, and once template analysis
    has begun, we simply don't have the right logic to update the analysis
    for incremental modifications (and never have).
    
    If this new rule breaks existing uses of templates that we decide need
    to be supported, we can try to invalidate all escape analysis for the
    entire set after any modifications. But let's wait on that until we know
    we need to and why.
    
    Also fix documentation of text/template redefinition policy
    (redefinition is always OK).
    
    Fixes #15761.
    
    Change-Id: I7d58d7c08a7d9df2440ee0d651a5b2ecaff3006c
    Reviewed-on: https://go-review.googlesource.com/31464
    Run-TryBot: Russ Cox <rsc@golang.org>
    TryBot-Result: Gobot Gobot <gobot@golang.org>
    Reviewed-by: 's avatarAndrew Gerrand <adg@golang.org>
    604146ce
template.go 6.7 KB