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",
deps = [
"//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",
],
)

View File

@ -22,13 +22,11 @@ import (
"encoding/json"
"fmt"
"io"
"io/ioutil"
"strings"
"unicode"
jsonutil "k8s.io/apimachinery/pkg/util/json"
"k8s.io/klog/v2"
"sigs.k8s.io/yaml"
)
@ -215,16 +213,15 @@ type YAMLOrJSONDecoder struct {
bufferSize int
decoder decoder
rawData []byte
}
type JSONSyntaxError struct {
Line int
Err error
Offset int64
Err error
}
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 {
@ -250,35 +247,18 @@ func NewYAMLOrJSONDecoder(r io.Reader, bufferSize int) *YAMLOrJSONDecoder {
// provide object, or returns an error.
func (d *YAMLOrJSONDecoder) Decode(into interface{}) error {
if d.decoder == nil {
buffer, origData, isJSON := GuessJSONStream(d.r, d.bufferSize)
buffer, _, isJSON := GuessJSONStream(d.r, d.bufferSize)
if isJSON {
d.decoder = json.NewDecoder(buffer)
d.rawData = origData
} else {
d.decoder = NewYAMLToJSONDecoder(buffer)
}
}
err := d.decoder.Decode(into)
if jsonDecoder, ok := d.decoder.(*json.Decoder); 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{
Line: line,
Err: fmt.Errorf(syntax.Error()),
}
if syntax, ok := err.(*json.SyntaxError); ok {
return JSONSyntaxError{
Offset: syntax.Offset,
Err: syntax,
}
}
return err

View File

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