Uses offset instead of line number in JSONSyntaxError

This commit is contained in:
Alexander Yastrebov 2021-01-13 00:46:23 +01:00
parent 4a595bd373
commit 4b422f9e4c
3 changed files with 11 additions and 31 deletions

View File

@ -19,7 +19,6 @@ go_library(
importpath = "k8s.io/apimachinery/pkg/util/yaml", importpath = "k8s.io/apimachinery/pkg/util/yaml",
deps = [ deps = [
"//staging/src/k8s.io/apimachinery/pkg/util/json:go_default_library", "//staging/src/k8s.io/apimachinery/pkg/util/json:go_default_library",
"//vendor/k8s.io/klog/v2:go_default_library",
"//vendor/sigs.k8s.io/yaml:go_default_library", "//vendor/sigs.k8s.io/yaml:go_default_library",
], ],
) )

View File

@ -22,13 +22,11 @@ import (
"encoding/json" "encoding/json"
"fmt" "fmt"
"io" "io"
"io/ioutil"
"strings" "strings"
"unicode" "unicode"
jsonutil "k8s.io/apimachinery/pkg/util/json" jsonutil "k8s.io/apimachinery/pkg/util/json"
"k8s.io/klog/v2"
"sigs.k8s.io/yaml" "sigs.k8s.io/yaml"
) )
@ -215,16 +213,15 @@ type YAMLOrJSONDecoder struct {
bufferSize int bufferSize int
decoder decoder decoder decoder
rawData []byte
} }
type JSONSyntaxError struct { type JSONSyntaxError struct {
Line int Offset int64
Err error Err error
} }
func (e JSONSyntaxError) Error() string { func (e JSONSyntaxError) Error() string {
return fmt.Sprintf("json: line %d: %s", e.Line, e.Err.Error()) return fmt.Sprintf("json: offset %d: %s", e.Offset, e.Err.Error())
} }
type YAMLSyntaxError struct { type YAMLSyntaxError struct {
@ -250,35 +247,18 @@ func NewYAMLOrJSONDecoder(r io.Reader, bufferSize int) *YAMLOrJSONDecoder {
// provide object, or returns an error. // provide object, or returns an error.
func (d *YAMLOrJSONDecoder) Decode(into interface{}) error { func (d *YAMLOrJSONDecoder) Decode(into interface{}) error {
if d.decoder == nil { if d.decoder == nil {
buffer, origData, isJSON := GuessJSONStream(d.r, d.bufferSize) buffer, _, isJSON := GuessJSONStream(d.r, d.bufferSize)
if isJSON { if isJSON {
d.decoder = json.NewDecoder(buffer) d.decoder = json.NewDecoder(buffer)
d.rawData = origData
} else { } else {
d.decoder = NewYAMLToJSONDecoder(buffer) d.decoder = NewYAMLToJSONDecoder(buffer)
} }
} }
err := d.decoder.Decode(into) err := d.decoder.Decode(into)
if jsonDecoder, ok := d.decoder.(*json.Decoder); ok {
if syntax, ok := err.(*json.SyntaxError); ok { if syntax, ok := err.(*json.SyntaxError); ok {
data, readErr := ioutil.ReadAll(jsonDecoder.Buffered())
if readErr != nil {
klog.V(4).Infof("reading stream failed: %v", readErr)
}
js := string(data)
// if contents from io.Reader are not complete,
// use the original raw data to prevent panic
if int64(len(js)) <= syntax.Offset {
js = string(d.rawData)
}
start := strings.LastIndex(js[:syntax.Offset], "\n") + 1
line := strings.Count(js[:start], "\n")
return JSONSyntaxError{ return JSONSyntaxError{
Line: line, Offset: syntax.Offset,
Err: fmt.Errorf(syntax.Error()), Err: syntax,
}
} }
} }
return err return err

View File

@ -242,8 +242,9 @@ func TestDecodeBrokenJSON(t *testing.T) {
if err == nil { if err == nil {
t.Fatal("expected error with json: prefix, got no error") t.Fatal("expected error with json: prefix, got no error")
} }
if !strings.HasPrefix(err.Error(), "json: line 3:") { const msg = `json: offset 28: invalid character '"' after object key:value pair`
t.Fatalf("expected %q to have 'json: line 3:' prefix", err.Error()) if msg != err.Error() {
t.Fatalf("expected %q, got %q", msg, err.Error())
} }
} }