diff --git a/infra/conf/json/reader.go b/infra/conf/json/reader.go index ca6c4cb93..d0d3cf6f3 100644 --- a/infra/conf/json/reader.go +++ b/infra/conf/json/reader.go @@ -27,18 +27,29 @@ const ( type Reader struct { io.Reader - state State - br *buf.BufferedReader + state State + pending []byte + br *buf.BufferedReader } -// Read implements io.Reader.Read(). Buffer must be at least 3 bytes. +// Read implements io.Reader.Read(). func (v *Reader) Read(b []byte) (int, error) { if v.br == nil { v.br = &buf.BufferedReader{Reader: buf.NewReader(v.Reader)} } p := b[:0] - for len(p) < len(b)-2 { + for len(p) < len(b) { + if len(v.pending) > 0 { + max := len(b) - len(p) + if max > len(v.pending) { + max = len(v.pending) + } + p = append(p, v.pending[:max]...) + v.pending = v.pending[max:] + continue + } + x, err := v.br.ReadByte() if err != nil { if len(p) == 0 { @@ -57,6 +68,7 @@ func (v *Reader) Read(b []byte) (int, error) { p = append(p, x) case '\\': v.state = StateEscape + p = append(p, x) case '#': v.state = StateComment case '/': @@ -65,7 +77,7 @@ func (v *Reader) Read(b []byte) (int, error) { p = append(p, x) } case StateEscape: - p = append(p, '\\', x) + p = append(p, x) v.state = StateContent case StateDoubleQuote: switch x { @@ -74,11 +86,12 @@ func (v *Reader) Read(b []byte) (int, error) { p = append(p, x) case '\\': v.state = StateDoubleQuoteEscape + p = append(p, x) default: p = append(p, x) } case StateDoubleQuoteEscape: - p = append(p, '\\', x) + p = append(p, x) v.state = StateDoubleQuote case StateSingleQuote: switch x { @@ -87,16 +100,17 @@ func (v *Reader) Read(b []byte) (int, error) { p = append(p, x) case '\\': v.state = StateSingleQuoteEscape + p = append(p, x) default: p = append(p, x) } case StateSingleQuoteEscape: - p = append(p, '\\', x) + p = append(p, x) v.state = StateSingleQuote case StateComment: if x == '\n' { v.state = StateContent - p = append(p, '\n') + p = append(p, x) } case StateSlash: switch x { @@ -105,14 +119,16 @@ func (v *Reader) Read(b []byte) (int, error) { case '*': v.state = StateMultilineComment default: - p = append(p, '/', x) + v.state = StateContent + v.pending = append(v.pending, x) + p = append(p, '/') } case StateMultilineComment: switch x { case '*': v.state = StateMultilineCommentStar case '\n': - p = append(p, '\n') + p = append(p, x) } case StateMultilineCommentStar: switch x { @@ -121,7 +137,7 @@ func (v *Reader) Read(b []byte) (int, error) { case '*': // Stay case '\n': - p = append(p, '\n') + p = append(p, x) default: v.state = StateMultilineComment } diff --git a/infra/conf/json/reader_test.go b/infra/conf/json/reader_test.go index 5bc7d1158..c66992e61 100644 --- a/infra/conf/json/reader_test.go +++ b/infra/conf/json/reader_test.go @@ -62,7 +62,7 @@ func TestReader1(t *testing.T) { output string } - bufLen := 8 + bufLen := 1 data := []dataStruct{ {"loooooooooooooooooooooooooooooooooooooooog", "loooooooooooooooooooooooooooooooooooooooog"}, @@ -70,6 +70,7 @@ func TestReader1(t *testing.T) { {`{"t": "\/test"}`, `{"t": "\/test"}`}, {`"\// fake comment"`, `"\// fake comment"`}, {`"\/\/\/\/\/"`, `"\/\/\/\/\/"`}, + {`/test/test`, `/test/test`}, } for _, testCase := range data {