Skip to content

Treat a null bundle definition as absent instead of panicking#412

Open
arpitjain099 wants to merge 1 commit into
cnabio:mainfrom
arpitjain099:chore/guard-nil-definition
Open

Treat a null bundle definition as absent instead of panicking#412
arpitjain099 wants to merge 1 commit into
cnabio:mainfrom
arpitjain099:chore/guard-nil-definition

Conversation

@arpitjain099

Copy link
Copy Markdown

Hi, thanks for maintaining cnab-go.

A bundle.json is allowed to carry a JSON null in its definitions map, for example:

"definitions": { "foo": null }

Since Bundle.Definitions is a map[string]*Schema, that null gets stored as a nil pointer under the key. The common value, ok := m[key] idiom then returns ok == true with a nil *Schema, and the following dereference panics. The four places that look a definition up and then read a field off it are affected:

  • Parameter.Validate (bundle/parameters.go) reading schema.Default
  • Output.Validate (bundle/outputs.go) reading schema.Default
  • ValuesOrDefaults (bundle/bundle.go) using s for coercion
  • IsOutputSensitive (bundle/outputs.go) reading def.WriteOnly

So any caller that runs Bundle.Validate, ValuesOrDefaults, or IsOutputSensitive on a bundle that a user or another tool produced with a null definition crashes with a nil pointer dereference rather than getting an error back.

The fix guards the nil pointer at each site (if !ok || schema == nil, and ok && def != nil for the sensitivity check) so a null definition is handled the same way as a missing one. That reuses the existing not-found error path, so behavior for well-formed bundles is unchanged.

I added a regression test (TestBundle_NilDefinition) that builds a bundle with a null definition referenced by both a parameter and an output, and asserts Validate, ValuesOrDefaults, and IsOutputSensitive all return an error instead of panicking. It panics before the change and passes after. go test ./bundle/... is green.

Happy to adjust the approach if you would rather reject a null definition earlier during unmarshalling instead.

Bundle.Definitions is a map[string]*Schema, so a bundle.json with a JSON
null definition ("definitions": {"foo": null}) stores a nil pointer under
that key. The usual value, ok := m[key] lookup then returns ok == true with a
nil *Schema, and dereferencing it panicked in Parameter.Validate,
Output.Validate, ValuesOrDefaults, and IsOutputSensitive.

Guard the nil pointer at each of those sites so a null definition is handled
the same as a missing one, reusing the existing not-found error path. Adds a
regression test that builds a bundle with a null definition referenced by a
parameter and an output.

Signed-off-by: Arpit Jain <arpitjain099@gmail.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant