From 93670d7d6da6623d404405f813eff5be34645abb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Mart=C3=AD?= Date: Wed, 14 Aug 2024 09:43:30 +0100 Subject: [PATCH] cmd/cue: do not panic on empty jsonl inputs MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit buildPlan.instances always returned an iterator with at least one instance, and in the case of an empty jsonl file, this would result in iterating over a single nil instance. This would cause the following logic, like exporting, to panic. An empty jsonl input means zero files, and is allowed by the spec. Moreover, zero bytes is not valid input, unlike YAML or TOML, which produce null and {} respectively. For these reasons, treat empty jsonl inputs as a stream of zero values. Signed-off-by: Daniel Martí Change-Id: Ie0a62bb59d347011de5aa47f5ee6d175824451a3 Reviewed-on: https://review.gerrithub.io/c/cue-lang/cue/+/1199451 Unity-Result: CUE porcuepine Reviewed-by: Matthew Sackman TryBot-Result: CUEcueckoo --- cmd/cue/cmd/common.go | 8 +++++++- cmd/cue/cmd/testdata/script/encoding_empty.txtar | 14 ++++++++------ 2 files changed, 15 insertions(+), 7 deletions(-) diff --git a/cmd/cue/cmd/common.go b/cmd/cue/cmd/common.go index 5e494e7f721..b09682a34c0 100644 --- a/cmd/cue/cmd/common.go +++ b/cmd/cue/cmd/common.go @@ -142,12 +142,18 @@ func (b *buildPlan) instances() iterator { e: err, i: -1, } - default: + case b.instance != nil: i = &instanceIterator{ a: []*instance{b.instance}, i: -1, } b.instance = nil + default: + // No instances; return an iterator with zero values. + // This can happen when the input is an empty jsonl file, for example. + // Zero iteration may not make much sense in some scenarios like export, + // but an empty jsonl file is valid, so doing nothing seems reasonable. + i = &instanceIterator{} } if len(b.expressions) > 0 { return &expressionIter{ diff --git a/cmd/cue/cmd/testdata/script/encoding_empty.txtar b/cmd/cue/cmd/testdata/script/encoding_empty.txtar index 734e50e9927..fa8d200c759 100644 --- a/cmd/cue/cmd/testdata/script/encoding_empty.txtar +++ b/cmd/cue/cmd/testdata/script/encoding_empty.txtar @@ -1,6 +1,7 @@ # Test that the various encodings cope with empty files correctly. - -# TODO(mvdan): fix the panics below; see https://cuelang.org/issue/1790 and https://cuelang.org/issue/2714. +# Note that empty files or inputs have different meanings per encoding. +# For example, in CUE and TOML they mean an empty struct or object, +# in JSON they are invalid, and in JSONL they are a stream of zero values. # TODO(mvdan): cover more encodings: jsonschema, openapi, textproto, proto. @@ -12,8 +13,8 @@ exec cue export cue: empty cmp stdout as-cue.stdout ! exec cue export json: empty stderr 'unexpected end of JSON input' -! exec cue export jsonl: empty -stderr '^panic: ' +exec cue export jsonl: empty +cmp stdout as-jsonl.stdout exec cue export yaml: empty cmp stdout as-yaml.stdout exec cue export toml: empty @@ -25,8 +26,8 @@ exec cue export cue: newlines cmp stdout as-cue.stdout ! exec cue export json: newlines stderr 'unexpected end of JSON input' -! exec cue export jsonl: newlines -stderr '^panic: ' +exec cue export jsonl: newlines +cmp stdout as-jsonl.stdout exec cue export yaml: newlines cmp stdout as-yaml.stdout exec cue export toml: newlines @@ -48,6 +49,7 @@ cmp stdout as-toml.stdout -- as-cue.stdout -- {} +-- as-jsonl.stdout -- -- as-yaml.stdout -- null -- as-toml.stdout --