diff --git a/lib/resty/session/utils.lua b/lib/resty/session/utils.lua index b5b88749..c7e293bf 100644 --- a/lib/resty/session/utils.lua +++ b/lib/resty/session/utils.lua @@ -246,6 +246,10 @@ local encode_json, decode_json do encode_json = function(value) if not cjson then cjson = require("cjson.safe").new() + -- decode arrays with the array metatable so an empty array round-trips + -- as `[]` instead of being re-encoded as `{}` (encode and decode share + -- this instance, so the option is set wherever it is created first). + cjson.decode_array_with_array_mt(true) end encode_json = cjson.encode return encode_json(value) @@ -263,6 +267,10 @@ local encode_json, decode_json do decode_json = function(value) if not cjson then cjson = require("cjson.safe").new() + -- decode arrays with the array metatable so an empty array round-trips + -- as `[]` instead of being re-encoded as `{}` (encode and decode share + -- this instance, so the option is set wherever it is created first). + cjson.decode_array_with_array_mt(true) end decode_json = cjson.decode return decode_json(value) diff --git a/spec/01-utils_spec.lua b/spec/01-utils_spec.lua index 95cb53c7..465b51ba 100644 --- a/spec/01-utils_spec.lua +++ b/spec/01-utils_spec.lua @@ -52,6 +52,16 @@ describe("Testing utils", function() assert.same(decoded, input) end) + + it("preserves empty arrays across decode then re-encode", function() + -- An empty JSON array must survive a decode + re-encode round-trip as + -- `[]`, not turn into `{}`. Without decode_array_with_array_mt the decoded + -- empty array loses its array metatable and is re-encoded as an object. + local decoded = utils.decode_json('{"items":[]}') + local reencoded = utils.encode_json(decoded) + + assert.equals('{"items":[]}', reencoded) + end) end) describe("encode/decode base64url", function()