Skip to content

Commit e8e6f04

Browse files
committed
internal/encoding: decode json files as a single JSON value
We were currently decoding json files just like we did jsonl and ndjson, meaning that we were allowing any of them to contain many newline-delimited JSON values, even if the filetype was JSON, which should mean exactly one JSON value. This bug was hiding in plain sight in tests like vet_altdata.txtar and vet_trailing.txtar, which both loaded jsonl files as json. For example, the latter had the following test passing where both json and jsonl files contained many values: ! exec cue vet schema.cue data-trailing-mismatch.json stderr 'foo: conflicting values "789" and int' ! exec cue vet schema.cue data-trailing-mismatch.jsonl stderr 'foo: conflicting values "789" and int' This is incorrect; the json decoder should reject anything after the top-level JSON value has been decoded, even after a newline. It now does reject multiple JSON values, as expected: ! exec cue vet schema.cue data-trailing-mismatch.json stderr 'invalid JSON.*after top-level value' ! exec cue vet schema.cue data-trailing-mismatch.jsonl stderr 'foo: conflicting values "789" and int' Fix up these tests to adjust their expectations. We also fix the JSON panics in the encoding_empty.txtar test, as the panic only exists with the JSONL decoder but not in the simpler JSON decoder which does not use an iterator anymore. Updates #2714. Signed-off-by: Daniel Martí <[email protected]> Change-Id: I7cca8f1b149640c9232b177135a0a0af06388711 Reviewed-on: https://review.gerrithub.io/c/cue-lang/cue/+/1198874 Unity-Result: CUE porcuepine <[email protected]> TryBot-Result: CUEcueckoo <[email protected]> Reviewed-by: Roger Peppe <[email protected]>
1 parent 0dccbf3 commit e8e6f04

File tree

4 files changed

+26
-12
lines changed

4 files changed

+26
-12
lines changed

cmd/cue/cmd/testdata/script/encoding_empty.txtar

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
exec cue export cue: empty
1212
cmp stdout as-cue.stdout
1313
! exec cue export json: empty
14-
stderr '^panic: '
14+
stderr 'unexpected end of JSON input'
1515
! exec cue export jsonl: empty
1616
stderr '^panic: '
1717
! exec cue export yaml: empty
@@ -24,7 +24,7 @@ cmp stdout as-toml.stdout
2424
exec cue export cue: newlines
2525
cmp stdout as-cue.stdout
2626
! exec cue export json: newlines
27-
stderr '^panic: '
27+
stderr 'unexpected end of JSON input'
2828
! exec cue export jsonl: newlines
2929
stderr '^panic: '
3030
! exec cue export yaml: newlines

cmd/cue/cmd/testdata/script/vet_altdata.txtar

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,13 @@
1-
exec cue vet schema.cue json: foo.data
1+
exec cue vet schema.cue jsonl: foo.data
22
! stderr .
33

4-
exec cue export schema.cue json: foo.data
4+
exec cue export schema.cue jsonl: foo.data
55
cmp stdout export-stdout
66

7+
# Multiple JSON values should be rejected if we're not using jsonl.
8+
! exec cue vet schema.cue json: foo.data
9+
stderr 'invalid JSON.*after top-level value'
10+
711
-- schema.cue --
812
[string]: string
913

cmd/cue/cmd/testdata/script/vet_trailing.txtar

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -3,23 +3,23 @@
33

44
# First, sanity check that other commands spot the trailing invalid syntax.
55
! exec cue eval data-trailing-garbage.json
6-
stderr 'invalid JSON'
6+
stderr 'invalid JSON.*after top-level value'
77
! exec cue def data-trailing-garbage.json
8-
stderr 'invalid JSON'
8+
stderr 'invalid JSON.*after top-level value'
99
! exec cue export data-trailing-garbage.json
10-
stderr 'invalid JSON'
10+
stderr 'invalid JSON.*after top-level value'
1111
! exec cue eval data-trailing-garbage.jsonl
12-
stderr 'invalid JSON'
12+
stderr 'invalid JSON.*looking for beginning of value'
1313

1414
# Then, check that vet does too.
1515
! exec cue vet schema.cue data-trailing-garbage.json
16-
stderr 'invalid JSON'
16+
stderr 'invalid JSON.*after top-level value'
1717
! exec cue vet schema.cue data-trailing-garbage.jsonl
18-
stderr 'invalid JSON'
18+
stderr 'invalid JSON.*looking for beginning of value'
1919

2020
# Check that even the last value is validated as well.
2121
! exec cue vet schema.cue data-trailing-mismatch.json
22-
stderr 'foo: conflicting values "789" and int'
22+
stderr 'invalid JSON.*after top-level value'
2323
! exec cue vet schema.cue data-trailing-mismatch.jsonl
2424
stderr 'foo: conflicting values "789" and int'
2525

internal/encoding/encoding.go

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -240,7 +240,17 @@ func NewDecoder(ctx *cue.Context, f *build.File, cfg *Config) *Decoder {
240240
if i.err == nil {
241241
i.doInterpret()
242242
}
243-
case build.JSON, build.JSONL:
243+
case build.JSON:
244+
b, err := io.ReadAll(r)
245+
if err != nil {
246+
i.err = err
247+
break
248+
}
249+
i.expr, i.err = json.Extract(path, b)
250+
if i.err == nil {
251+
i.doInterpret()
252+
}
253+
case build.JSONL:
244254
i.next = json.NewDecoder(nil, path, r).Extract
245255
i.Next()
246256
case build.YAML:

0 commit comments

Comments
 (0)