Found while fixing #761/#762 (PR #764). Everything here happens on main.
1. A refused argument can share a key with a valid call
When the valid call's result is cached, the refused form is answered from the cache through fetchQuery or a query hook, instead of failing. So an app with a bad argument can look like it works, until the cache is empty and the call throws.
Suggested fix: key a value only by the form the codec accepts at that position, and give refused values a key that can't match an accepted one. #757 and #764 already read argument types in the key builder, so this is local.
2. Some forms that send the same bytes still get separate keys
Extra calls, not wrong data:
- extra record fields
- a number vs numeric text for integers of 32 bits or less, and for floats
- a
Principal vs its text
- a typed array vs a plain array for non-blob vectors
- different values of
reserved
Acceptance
Found while fixing #761/#762 (PR #764). Everything here happens on
main.1. A refused argument can share a key with a valid call
undefinedwhere Candidnullis required gets the same query key asnull, in bothReactorandDisplayReactor. The codec refusesundefinedthere, so a direct call fails.bigintfor a displaynatgets the key of its decimal text (core: query keys map NaN/Infinity/-0 to one key, and give equal records in different field order different keys #515 writes bigints as decimal strings). TheDisplayReactorcodec refuses the bigint.When the valid call's result is cached, the refused form is answered from the cache through
fetchQueryor a query hook, instead of failing. So an app with a bad argument can look like it works, until the cache is empty and the call throws.Suggested fix: key a value only by the form the codec accepts at that position, and give refused values a key that can't match an accepted one. #757 and #764 already read argument types in the key builder, so this is local.
2. Some forms that send the same bytes still get separate keys
Extra calls, not wrong data:
Principalvs its textreservedAcceptance
main.