Variable Escaping Proposal #10
Replies: 6 comments 25 replies
-
If the use case valid one, or a typo?
I guess you mean without the dot like below |
Beta Was this translation helpful? Give feedback.
-
Hi If becoming "standard" I think it makes sense to stick to the spirit and value of jsonlogic, ie staying an ast, if the ast needs other parsers it defeats the purpose of the spec and breaks interoperability and portability (graphql is one good example it doesnt work and stays a single vendor thing). So my 2cts would be no escaping but a preparsed tree in plain json. Not sure backward compat is a huge concern, I'd rather say the portability and multivendor agreement has more value and vendors can still enable backward compat in the impl (=not needed at spec level)....also means the json needs a version at root level for future upgrades (like jsonschema for ex). |
Beta Was this translation helpful? Give feedback.
-
I think adding semantics to paths to the As an alternative, I've experimented with altering the implementation of the See the patch here: https://github.com/ehn-dcc-development/eu-dcc-business-rules/blob/main/jsonlogic/javascript/patch/patched-logic.js This is a “benign” (non-breaking) change, because the extra I only experimented with the |
Beta Was this translation helpful? Give feedback.
-
RFC6901 Retrofit ProposalWhat if we retrofit RFC6901 onto the
This retrofit would work with pretty much most existing logic, enable folks to use RFC6901, and resolve the inaccessible keys. Flaws with the RetrofitBecause of the implicit Backwards Compatibility ConcernsThis retrofit would require folks to escape paths for I think this upgrade would be manageable. Proposed Test Suite[
"Test Specification for Handling esoteric path traversal",
{
"description": "Fetches a value from an empty key",
"rule": { "var": "/" },
"data": { "" : 1 },
"result": 1
},
{
"description": "Fetches a value from a nested empty key",
"rule": { "var": "//" },
"data": { "" : { "": 2 } },
"result": 2
},
{
"description": "Fetches a value from a doubly nested empty key",
"rule": { "var": "///" },
"data": { "" : { "": { "": 3 } } },
"result": 3
},
{
"description": "Fetches a value from a key that is purely a dot",
"rule": { "var": "~2" },
"data": { "." : 20 },
"result": 20
},
{
"description": "Fetches a value from a key with a dot in it",
"rule": { "var": "~2key" },
"data": { ".key" : 4 },
"result": 4
},
{
"description":"Fetches a value from a key with a dot in it (2)",
"rule": { "var": "hello~2world" },
"data": { "hello.world" : 5 },
"result": 5
},
{
"description": "Fetches a value from a key inside an empty key with a dot in it",
"rule": { "var": "//~2key" },
"data": { "": { ".key" : 6 } },
"result": 6
},
{
"description": "Going a few levels deep",
"rule": { "var": "///~2key/" },
"data": { "": { "": { ".key": { "": 7 }} }},
"result": 7
},
{
"description": "Escape / as well, which is useful for the scope proposal",
"rule": { "var": "~1" },
"data": { "/" : 8 },
"result": 8
},
{
"description": "Dot then empty key",
"rule": { "var": "~2." },
"data": { "." : { "" : 10 } },
"result": 10
},
{
"description": "Empty key then dot",
"rule": { "var": "//~2" },
"data": { "" : { "." : 11 } },
"result": 11
},
{
"description": "Can use backslack in name, too",
"rule": { "var": "\\.Hello" },
"data": { "\\" : { "Hello" : 12 } },
"result": 12
},
{
"description": "Can escape tilde",
"rule": { "var": "~0" },
"data": { "~" : 13 },
"result": 13
},
{
"description": "Fetches a value from an empty key, equivalence",
"rule": { "var": "." },
"data": { "" : 1 },
"result": 1
},
{
"description": "Fetches a value from a nested empty key, equivalence",
"rule": { "var": ".." },
"data": { "" : { "": 2 } },
"result": 2
},
{
"description": "Fetches a value from a doubly nested empty key, equivalence",
"rule": { "var": "..." },
"data": { "" : { "": { "": 3 } } },
"result": 3
},
{
"description": "Old format still works",
"rule": { "var": "hello.world" },
"data": { "hello": { "world": 5 } },
"result": 5
},
{
"description": "New format works too",
"rule": { "var": "hello/world" },
"data": { "hello": { "world": 5 } },
"result": 5
}
] |
Beta Was this translation helpful? Give feedback.
-
If you're going to use something that's not RFC6901, then don't mention RFC6901. Just make your own thing. Referencing a specification should only be done when using that specification as-is. Don't reference a spec only to change it. |
Beta Was this translation helpful? Give feedback.
-
I believe I'll be closing this proposal and introducing a new one, based on misc discussions we've had in different threads. |
Beta Was this translation helpful? Give feedback.
-
Background
In JSON Logic, there are a handful of keys that are inaccessible from JSON Logic.
Examples include:
{ "": 7 }
{ "hello.world": 7 }
,{ ".": 8 }
{ ".": { "": 9 } }
I'd like to discuss backwards compatible solutions that would allow us to access these
Why not RFC6901
I'd ideally like to retain backwards compatibility with JSON Logic, and also address scopes in a separate proposal.
My concern with RFC6901 is that it adjusts how we traverse properties and it invalidates all existing implementations of JSON Logic.
If this was more greenfield, I'd think RFC6901 would be a solid choice.
Suggestion
What if we take notes from
dot-prop notation
, which essentially allows for escaping certain characters in the path with\
.Escaped Characters would be
\
,.
, and potentially@
(useful for scope proposal).Alongside this proposal, I would like to suggest a second operator,
val
, which is a simpler, more explicit way to reference values.val
would be more AST friendly, and not involve a parsed path.Using RFC6901 Paths to explain pathing,
{ val: 'hello' }
would reference/hello
,{ "val": ["hello", "world"] }
would reference/hello/world
.{ val: '' }
would reference/
{ val: null }
would reference the entire context.Proposed Test Suite
var
retrofitval
operatorAnticipated Questions
I think for this initiative to be successful, we must try to maintain backwards compatibility with current mainline JSON Logic.
If we break backwards compatibility, I fear this will fragment the ecosystem and keep people from updating.
If we retrofit
var
with dot-prop, it's likely not a necessity, but having an AST friendly way to reference variables would be quite nice and simple to implement.I also don't believe it would add much project maintenance overhead, as folks could set up
var
to parse the path, and call the code set up forval
.Because
val
functions distinctly fromvar
, I believe it has a right to exist, and by introducing a new operator, we have a path to deprecate the old operator and listvar
andval
support in compatibility tables.Truthfully, I don't think we'll get away from
var
, butval
will make it easier for folks to build grammars that compile down to JSON Logic, and execute it across different environments.Beta Was this translation helpful? Give feedback.
All reactions