diff options
Diffstat (limited to 'src/html/template/html.go')
| -rw-r--r-- | src/html/template/html.go | 13 |
1 files changed, 8 insertions, 5 deletions
diff --git a/src/html/template/html.go b/src/html/template/html.go index 9c069efd1d..de4aa4abb2 100644 --- a/src/html/template/html.go +++ b/src/html/template/html.go @@ -138,21 +138,24 @@ var htmlNospaceNormReplacementTable = []string{ // and when badRunes is true, certain bad runes are allowed through unescaped. func htmlReplacer(s string, replacementTable []string, badRunes bool) string { written, b := 0, new(bytes.Buffer) - for i, r := range s { + r, w := rune(0), 0 + for i := 0; i < len(s); i += w { + // Cannot use 'for range s' because we need to preserve the width + // of the runes in the input. If we see a decoding error, the input + // width will not be utf8.Runelen(r) and we will overrun the buffer. + r, w = utf8.DecodeRuneInString(s[i:]) if int(r) < len(replacementTable) { if repl := replacementTable[r]; len(repl) != 0 { b.WriteString(s[written:i]) b.WriteString(repl) - // Valid as long as replacementTable doesn't - // include anything above 0x7f. - written = i + utf8.RuneLen(r) + written = i + w } } else if badRunes { // No-op. // IE does not allow these ranges in unquoted attrs. } else if 0xfdd0 <= r && r <= 0xfdef || 0xfff0 <= r && r <= 0xffff { fmt.Fprintf(b, "%s&#x%x;", s[written:i], r) - written = i + utf8.RuneLen(r) + written = i + w } } if written == 0 { |
