vendor: update github.com/valyala/quicktemplate from v1.5.0 to v1.5.1

This should fix incorrect encoding for json strings with char codes below 0x20

Updates https://github.com/VictoriaMetrics/VictoriaMetrics/issues/613
This commit is contained in:
Aliaksandr Valialkin 2020-07-10 12:56:03 +03:00
parent ca74b80f10
commit e5b9f47623
5 changed files with 72 additions and 90 deletions

2
go.mod
View file

@ -18,7 +18,7 @@ require (
github.com/valyala/fastrand v1.0.0
github.com/valyala/gozstd v1.7.0
github.com/valyala/histogram v1.0.1
github.com/valyala/quicktemplate v1.5.0
github.com/valyala/quicktemplate v1.5.1
go.opencensus.io v0.22.4 // indirect
golang.org/x/net v0.0.0-20200707034311-ab3426394381 // indirect
golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d

4
go.sum
View file

@ -171,8 +171,8 @@ github.com/valyala/gozstd v1.7.0 h1:Ljh5c9zboqLhwTI33al32R72iCZfn0mCbVGcFWbGwRQ=
github.com/valyala/gozstd v1.7.0/go.mod h1:y5Ew47GLlP37EkTB+B4s7r6A5rdaeB7ftbl9zoYiIPQ=
github.com/valyala/histogram v1.0.1 h1:FzA7n2Tz/wKRMejgu3PV1vw3htAklTjjuoI6z3d4KDg=
github.com/valyala/histogram v1.0.1/go.mod h1:lQy0xA4wUz2+IUnf97SivorsJIp8FxsnRd6x25q7Mto=
github.com/valyala/quicktemplate v1.5.0 h1:2CUbkvZbxZ9m51wp5a2vzrbnv38Iocp0bMJomSmHyg0=
github.com/valyala/quicktemplate v1.5.0/go.mod h1:v7yYWpBEiutDyNfVaph6oC/yKwejzVyTX/2cwwHxyok=
github.com/valyala/quicktemplate v1.5.1 h1:JtrOtlRMP+pySF9dkPBfVfhZ3YHTitAJpMLNqT9ZjFk=
github.com/valyala/quicktemplate v1.5.1/go.mod h1:v7yYWpBEiutDyNfVaph6oC/yKwejzVyTX/2cwwHxyok=
github.com/valyala/tcplisten v0.0.0-20161114210144-ceec8f93295a/go.mod h1:v3UYOV9WzVtRmSR+PDvWpU/qWl4Wa5LApYYX4ZtKbio=
github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=

View file

@ -1,93 +1,65 @@
package quicktemplate
import (
"io"
"fmt"
"strings"
)
func writeJSONString(w io.Writer, s string) {
if len(s) > 24 &&
strings.IndexByte(s, '"') < 0 &&
strings.IndexByte(s, '\\') < 0 &&
strings.IndexByte(s, '\n') < 0 &&
strings.IndexByte(s, '\r') < 0 &&
strings.IndexByte(s, '\t') < 0 &&
strings.IndexByte(s, '\f') < 0 &&
strings.IndexByte(s, '\b') < 0 &&
strings.IndexByte(s, '<') < 0 &&
strings.IndexByte(s, '\'') < 0 &&
strings.IndexByte(s, 0) < 0 {
// fast path - nothing to escape
w.Write(unsafeStrToBytes(s))
return
func hasSpecialChars(s string) bool {
if strings.IndexByte(s, '"') >= 0 || strings.IndexByte(s, '\\') >= 0 || strings.IndexByte(s, '<') >= 0 || strings.IndexByte(s, '\'') >= 0 {
return true
}
// slow path
write := w.Write
b := unsafeStrToBytes(s)
j := 0
n := len(b)
if n > 0 {
// Hint the compiler to remove bounds checks in the loop below.
_ = b[n-1]
}
for i := 0; i < n; i++ {
switch b[i] {
case '"':
write(b[j:i])
write(strBackslashQuote)
j = i + 1
case '\\':
write(b[j:i])
write(strBackslashBackslash)
j = i + 1
case '\n':
write(b[j:i])
write(strBackslashN)
j = i + 1
case '\r':
write(b[j:i])
write(strBackslashR)
j = i + 1
case '\t':
write(b[j:i])
write(strBackslashT)
j = i + 1
case '\f':
write(b[j:i])
write(strBackslashF)
j = i + 1
case '\b':
write(b[j:i])
write(strBackslashB)
j = i + 1
case '<':
write(b[j:i])
write(strBackslashLT)
j = i + 1
case '\'':
write(b[j:i])
write(strBackslashQ)
j = i + 1
case 0:
write(b[j:i])
write(strBackslashZero)
j = i + 1
for i := 0; i < len(s); i++ {
if s[i] < 0x20 {
return true
}
}
write(b[j:])
return false
}
var (
strBackslashQuote = []byte(`\"`)
strBackslashBackslash = []byte(`\\`)
strBackslashN = []byte(`\n`)
strBackslashR = []byte(`\r`)
strBackslashT = []byte(`\t`)
strBackslashF = []byte(`\u000c`)
strBackslashB = []byte(`\u0008`)
strBackslashLT = []byte(`\u003c`)
strBackslashQ = []byte(`\u0027`)
strBackslashZero = []byte(`\u0000`)
)
func appendJSONString(dst []byte, s string, addQuotes bool) []byte {
if !hasSpecialChars(s) {
// Fast path - nothing to escape.
if !addQuotes {
return append(dst, s...)
}
dst = append(dst, '"')
dst = append(dst, s...)
dst = append(dst, '"')
return dst
}
// Slow path - there are chars to escape.
if addQuotes {
dst = append(dst, '"')
}
bb := AcquireByteBuffer()
var tmp []byte
tmp, bb.B = bb.B, dst
_, err := jsonReplacer.WriteString(bb, s)
if err != nil {
panic(fmt.Errorf("BUG: unexpected error returned from jsonReplacer.WriteString: %s", err))
}
dst, bb.B = bb.B, tmp
ReleaseByteBuffer(bb)
if addQuotes {
dst = append(dst, '"')
}
return dst
}
var jsonReplacer = strings.NewReplacer(func() []string {
a := []string{
"\n", `\n`,
"\r", `\r`,
"\t", `\t`,
"\"", `\"`,
"\\", `\\`,
"<", `\u003c`,
"'", `\u0027`,
}
for i := 0; i < 0x20; i++ {
a = append(a, string([]byte{byte(i)}), fmt.Sprintf(`\u%04x`, i))
}
return a
}()...)

View file

@ -151,9 +151,13 @@ func (w *QWriter) FPrec(f float64, prec int) {
// Q writes quoted json-safe s to w.
func (w *QWriter) Q(s string) {
w.Write(strQuote)
writeJSONString(w, s)
w.Write(strQuote)
bb, ok := w.w.(*ByteBuffer)
if ok {
bb.B = appendJSONString(bb.B, s, true)
} else {
w.b = appendJSONString(w.b[:0], s, true)
w.Write(w.b)
}
}
var strQuote = []byte(`"`)
@ -167,7 +171,13 @@ func (w *QWriter) QZ(z []byte) {
//
// Unlike Q it doesn't qoute resulting s.
func (w *QWriter) J(s string) {
writeJSONString(w, s)
bb, ok := w.w.(*ByteBuffer)
if ok {
bb.B = appendJSONString(bb.B, s, false)
} else {
w.b = appendJSONString(w.b[:0], s, false)
w.Write(w.b)
}
}
// JZ writes json-safe z to w.

2
vendor/modules.txt vendored
View file

@ -108,7 +108,7 @@ github.com/valyala/fastrand
github.com/valyala/gozstd
# github.com/valyala/histogram v1.0.1
github.com/valyala/histogram
# github.com/valyala/quicktemplate v1.5.0
# github.com/valyala/quicktemplate v1.5.1
github.com/valyala/quicktemplate
# go.opencensus.io v0.22.4
go.opencensus.io