fix(json): preserve empty arrays across decode + re-encode#207
Open
AlinsRan wants to merge 1 commit into
Open
Conversation
The shared private cjson instance in utils.lua decoded JSON without the array
metatable, so an empty array (`[]`) lost its array-ness and was re-encoded as
an object (`{}`). Sessions that carry an empty array (e.g. an OIDC userinfo
claim) thus had it silently turn into `{}` after a save/load round-trip.
Enable decode_array_with_array_mt(true) on the instance at creation so decoded
arrays keep the array metatable and round-trip correctly. Added a regression
test in spec/01-utils_spec.lua.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
The private
cjsoninstance inlib/resty/session/utils.lua(shared byencode_json/decode_json) decodes JSON without the array metatable. As a result an empty JSON array ([]) loses its array-ness on decode and is re-encoded as an object ({}).Any session payload that carries an empty array therefore has it silently mutated from
[]to{}after a save → load → save round-trip. This surfaced downstream in APISIX'sopenid-connectplugin: an empty array claim in the OIDCuserinfo(e.g. emptygroups/roles) comes back as{}, breaking backends that expect an array (apache/apisix#13440). It is a regression since the private cjson instance was introduced.Fix
Enable
decode_array_with_array_mt(true)on the instance when it is created, so decoded arrays keep the array metatable and round-trip correctly.encode_jsonanddecode_jsonshare the same lazily-created instance, so the option is set at whichever creation site runs first.Behavior verified:
Non-empty arrays already round-tripped correctly (cjson infers an array from the elements); only empty arrays were affected, and objects are unchanged.
Test
Added a regression test in
spec/01-utils_spec.luathat decodes{"items":[]}and asserts it re-encodes back to{"items":[]}(fails before the change, passes after).