fix(json): ensure empty array is the same after decode then encode (#6383)

This commit is contained in:
罗泽轩 2022-02-24 15:37:35 +08:00 committed by GitHub
parent 0527e45733
commit d5d1c8a490
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 81 additions and 23 deletions

View File

@ -14,7 +14,8 @@
-- See the License for the specific language governing permissions and
-- limitations under the License.
--
local json_encode = require("cjson.safe").encode
local cjson = require("cjson.safe")
local json_encode = cjson.encode
local clear_tab = require("table.clear")
local ngx = ngx
local tostring = tostring
@ -23,10 +24,11 @@ local pairs = pairs
local cached_tab = {}
cjson.decode_array_with_array_mt(true)
local _M = {
version = 0.1,
array_mt = require("cjson.safe").array_mt,
decode = require("cjson.safe").decode,
array_mt = cjson.array_mt,
decode = cjson.decode,
-- This method produces the same encoded string when the input is not changed.
-- Different calls with cjson.encode will produce different string because
-- it doesn't maintain the object key order.

View File

@ -20,6 +20,11 @@
"code": 40001,
"desc": "Give you a object reason"
}
},
"elisa": {
"reason": {
"info": []
}
}
}
}

2
t/admin/services.t vendored
View File

@ -1068,7 +1068,7 @@ GET /t
local t = require("lib.test_admin").test
local code, body = t('/apisix/admin/services/1',
ngx.HTTP_PUT,
{},
'{}',
[[{
"node": {
"value": {"id":"1"}

47
t/core/json.t vendored
View File

@ -20,6 +20,18 @@ repeat_each(2);
no_long_string();
no_root_location();
add_block_preprocessor(sub {
my ($block) = @_;
if (!$block->request) {
$block->set_value("request", "GET /t");
}
if ((!defined $block->error_log) && (!defined $block->no_error_log)) {
$block->set_value("no_error_log", "[error]");
}
});
run_tests;
__DATA__
@ -37,13 +49,9 @@ __DATA__
ngx.say("data: ", data.test)
}
}
--- request
GET /t
--- response_body
encode: {"test":"test"}
data: test
--- no_error_log
[error]
@ -61,8 +69,6 @@ data: test
ngx.log(ngx.ERR, "data2 val: ", data2)
}
}
--- request
GET /t
--- response_body
delay encode: true
data1 type: table
@ -82,12 +88,8 @@ data2 val: {"test":"test2"}
ngx.say("encode: ", data)
}
}
--- request
GET /t
--- response_body_like eval
qr/\{("test":"test","fun":"function: 0x[0-9a-f]+"|"fun":"function: 0x[0-9a-f]+","test":"test")}/
--- no_error_log
[error]
@ -103,12 +105,8 @@ qr/\{("test":"test","fun":"function: 0x[0-9a-f]+"|"fun":"function: 0x[0-9a-f]+",
ngx.say("encode: ", json_data)
}
}
--- request
GET /t
--- response_body_like eval
qr/encode: \{"test":"cdata\<char \*\[1\]>: 0x[0-9a-f]+"\}/
--- no_error_log
[error]
@ -126,9 +124,22 @@ qr/encode: \{"test":"cdata\<char \*\[1\]>: 0x[0-9a-f]+"\}/
ngx.say("encode: ", json_data)
}
}
--- request
GET /t
--- response_body eval
qr/\{"b":\{"a":\{"b":"table: 0x[\w]+"\}\}\}/
--- no_error_log
[error]
=== TEST 6: decode/encode empty array
--- config
location /t {
content_by_lua_block {
local core = require("apisix.core")
local data = core.json.decode('{"arr":[]}')
ngx.say(core.json.encode(data))
local data = core.json.decode('{"obj":{}}')
ngx.say(core.json.encode(data))
}
}
--- response_body
{"arr":[]}
{"obj":{}}

View File

@ -168,6 +168,7 @@ function _M.test(uri, method, body, pattern, headers)
end
if type(body) == "table" then
-- {} will be encoded as '[]' whether decode_array_with_array_mt or not
body = json.encode(body)
end

View File

@ -33,7 +33,7 @@ __DATA__
local t = require("lib.test_admin").test
local code, body = t('/apisix/admin/services/1',
ngx.HTTP_PUT,
{},
'{}',
[[{
"node": {
"value": {"id":"1"}

39
t/plugin/opa2.t vendored
View File

@ -185,3 +185,42 @@ apikey: test-key
--- error_code: 403
--- response_body_unlike eval
qr/\"service\"/ and qr/\"consumer\"/
=== TEST 7: setup route
--- config
location /t {
content_by_lua_block {
local t = require("lib.test_admin").test
local code, body = t('/apisix/admin/routes/1',
ngx.HTTP_PUT,
[[{
"plugins": {
"opa": {
"host": "http://127.0.0.1:8181",
"policy": "example"
}
},
"upstream_id": "u1",
"uri": "/hello"
}]]
)
if code >= 300 then
ngx.status = code
end
ngx.say(body)
}
}
--- response_body
passed
=== TEST 8: hit route (with JSON empty array)
--- request
GET /hello?user=elisa
--- error_code: 403
--- response_body chomp
{"info":[]}