Skip to content

Conversation

@mtrmac
Copy link
Collaborator

@mtrmac mtrmac commented Mar 13, 2017

Instead of relying on json.Unmarshal into a map[string]interface{}, and dealing with field presence and correct types manually, build a helper based on paranoidUnmarshalJSONObjects which verifies field presence automatically, relies on json.Unmarshal for enforcing types of unstructured values, and newly rejects JSON objects with duplicate members.

Besides the primary benefit, rejecting ambiguous signatures, this allows us to get rid of the infrastructure for safely manually parsing map[string]interface{}. The new paranoidUnmarshalJSONObjectExactFields can also be used to simplify policy.json parsing a bit.

Also includes one unrelated test bug fix.

See the individual commits for more details.

mtrmac added 4 commits March 13, 2017 17:15
This is a combination of json.Unmarshal + validateExactMapKeys
except using the paranoidUnmarshalJSONObject parser (refusing duplicate
and unknown fields),
+ unmarshaling into typed values instead of a map[string]interface{},
i.e. making int64Field/mapField/stringField unnecessary.

This does not add any user yet.

Signed-off-by: Miloslav Trmač <[email protected]>
i.e. validateExactMapKeys, int64Field, mapField, stringField.

untrustedSignature.strictUnmarshalJSON no longer uses them.  The test
scenarios are covered by tests of untrustedSignature.strictUnmarshalJSON
already (except for testing the full range of int64 timestamps).

Signed-off-by: Miloslav Trmač <[email protected]>
A test was referring to the old "specific" name for the "transports"
member.

Signed-off-by: Miloslav Trmač <[email protected]>
// (including duplicated keys, unrecognized keys, and non-matching types). Each of the fields in exactFields
// must be present exactly once, and none other fields are accepted.
func paranoidUnmarshalJSONObjectExactFields(data []byte, exactFields map[string]interface{}) error {
seenKeys := map[string]struct{}{}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It might be more idiomatic, but a map[string]bool is better suited here and allows to do

If seenkeys[i]...

W/o playing around with !ok below

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I somewhat prefer the struct{} to make the type closer to the true type (set of string), see also earlier conversation in #223 , and perhaps earlier.

I don’t feel all that strongly about this, but if you can live with it, I’ll merge as is.

@runcom
Copy link
Member

runcom commented Mar 13, 2017

LGTM just a minor nit

Approved with PullApprove

In most of the cases, the original code did not explicitly require that
a (string) field is present, but empty strings were later rejected
(because the "type" field was required to be equal to a constant, or
because parsing a docker/reference would fail).  Either way, there were
already tests verifying that missing fields are rejected; now the code
is just a bit more explicit about it.

Signed-off-by: Miloslav Trmač <[email protected]>
@mtrmac mtrmac force-pushed the paranoid-signature-json branch from 9353672 to 3994e56 Compare March 14, 2017 14:24
@mtrmac
Copy link
Collaborator Author

mtrmac commented Mar 14, 2017

👍

Approved with PullApprove

@mtrmac mtrmac merged commit 3149c1a into containers:master Mar 14, 2017
@mtrmac mtrmac deleted the paranoid-signature-json branch March 14, 2017 15:05
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.

2 participants