mapbox / mapbox-gl-style-spec

76 stars 38 forks source link

Don't rely on splitting on periods; explicitly disallow arbitrary keys in transitions #559

Closed lbud closed 7 years ago

lbud commented 7 years ago

Alternative to #558.

While it's doubtful anyone is making up arbitrary keys in transitions in a style, I'd still rather not make the spec any less strict — object validation now relies on a boolean option to error on arbitrary keys (so any other properties that go through vanilla object validation can have arbitrary keys).

@jfirebaugh @lucaswoj

lbud commented 7 years ago

@lucaswoj @jfirebaugh

To make sure I fully understood this, I broke down the validation pipeline here (and caught a few bugs with the light validation I had written here :pray:):

Here's what happens when we validate a style:


  • Should allowArbitrary be true by default? I would like to make new style spec primitives as strict as possible. Strictness should be the default.

To clarify, it's disallowArbitrary in this PR but your point stands. We could switch this to allowArbitrary (false by default) and allow it only in the root object and root layers.

  • Are you sure that transition objects are the only ones that have been enforcing "strictness"? What about light objects? What about layout / paint objects within layers? What about function objects?

See above. (light object has its own validator, which I just fixed some bugs in and added tests to make sure we don't tolerate arbitrary keys. (Note that the root-level transition hasn't been prohibiting arbitrary keys — should it?) As shown in https://github.com/mapbox/mapbox-gl-style-spec/pull/562, layout and paint objects as well as function keys have been enforcing strictness via the splitting-on-periods mechanism. (I merged that PR then rebased here to ensure this enforces strictness in the same way.)

  • We already have a means of interacting with arbitrary keys in objects: the * wildcard object element validator. What would it mean to specify a * wildcard object element validator and make allowArbitrary false? Could the two concepts be combined? For example, we could allow arbitrary keys iff a * wildcard object element validator is specified.

The wildcard object element validator is more for when "type": "*", rather than for interacting with wildcard keys themselves. I'm not sure we should conflate these?

  • Is allowArbitrary a specific enough name for this setting that someone who stumbles across it in the codebase without context would know what it means? "Allow arbitrary what?"

I'm happy to change to disallowArbitraryKeys (or, if we go with the change mentioned above, allowArbitraryKeys).


In my opinion then the outstanding questions are

lbud commented 7 years ago
  • should we rename this from disallowArbitrary to allowArbitrary? (`.concat('keys'))
  • should we toggle this to strict by default, and instead be explicit in all the places where we do allow arbitrary keys, so that future object validation will be strict by default?

Just did in https://github.com/mapbox/mapbox-gl-style-spec/pull/559/commits/428bf80f1941ed3ebe76367db64f849c8a0f4075 https://github.com/mapbox/mapbox-gl-style-spec/pull/559/commits/f902b4a9a45aa679f068544f6834749e4db6d4f7

lucaswoj commented 7 years ago

Thank you for being so thorough on this 🙇


should we add strictness (disallowArbitrary) to the $root-level global transition?

A stated goal of this PR is to not increase strictness. We should not add strictness to the $root-level global transition.

The wildcard object element validator is more for when "type": "*", rather than for interacting with wildcard keys themselves. I'm not sure we should conflate these?

What would it mean to specify a * wildcard object element validator and when allowArbitrary false? Or is that combination impossible for a reason I'm missing? (It's been a while since I wrote this code.)

It is desirable that it be impossible to pass contradictary arguments to this method. It is desirable that objects which allow arbitrary keys must go against the grain to omit validation for arbitrary keys.