aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorlijunlong <lijunlong@openresty.com>2023-02-22 11:28:15 +0800
committerGitHub <noreply@github.com>2023-02-22 11:28:15 +0800
commitde93a78d3002ee72bb1c7e3a629d67e19623a4ae (patch)
treefddd9ba083aae1c3f58868e313aa0540885951b8
parent1dff61d9bf390372124c13443e0131a96383f5bc (diff)
downloadlua-cjson-de93a78d3002ee72bb1c7e3a629d67e19623a4ae.tar.gz
lua-cjson-de93a78d3002ee72bb1c7e3a629d67e19623a4ae.tar.bz2
lua-cjson-de93a78d3002ee72bb1c7e3a629d67e19623a4ae.zip
feature: Add option to skip invalid value types.
Co-authored-by: Jesper Lundgren <jesperlundgren@exosite.com>
-rw-r--r--.travis.yml4
-rw-r--r--lua-cjson-2.1.0.11-1.rockspec (renamed from lua-cjson-2.1.0.10-1.rockspec)0
-rw-r--r--lua_cjson.c59
-rw-r--r--strbuf.h6
-rw-r--r--tests/agentzh.t26
5 files changed, 79 insertions, 16 deletions
diff --git a/.travis.yml b/.travis.yml
index b07f3dc..91f73ff 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -46,8 +46,8 @@ install:
46 - cd .. 46 - cd ..
47 47
48script: 48script:
49 - cppcheck -i ./luajit2 -i --force --error-exitcode=1 --enable=warning . > build.log 2>&1 || (cat build.log && exit 1) 49 - cppcheck -i ./luajit2 --force --error-exitcode=1 --enable=warning . > build.log 2>&1 || (cat build.log && exit 1)
50 - sh runtests.sh 50 - bash runtests.sh
51 - make 51 - make
52 - prove -Itests tests 52 - prove -Itests tests
53 - TEST_LUA_USE_VALGRIND=1 prove -Itests tests > build.log 2>&1; export e=$? 53 - TEST_LUA_USE_VALGRIND=1 prove -Itests tests > build.log 2>&1; export e=$?
diff --git a/lua-cjson-2.1.0.10-1.rockspec b/lua-cjson-2.1.0.11-1.rockspec
index 9ed4272..9ed4272 100644
--- a/lua-cjson-2.1.0.10-1.rockspec
+++ b/lua-cjson-2.1.0.11-1.rockspec
diff --git a/lua_cjson.c b/lua_cjson.c
index 94b0b46..42672de 100644
--- a/lua_cjson.c
+++ b/lua_cjson.c
@@ -82,6 +82,7 @@
82#define DEFAULT_ENCODE_EMPTY_TABLE_AS_OBJECT 1 82#define DEFAULT_ENCODE_EMPTY_TABLE_AS_OBJECT 1
83#define DEFAULT_DECODE_ARRAY_WITH_ARRAY_MT 0 83#define DEFAULT_DECODE_ARRAY_WITH_ARRAY_MT 0
84#define DEFAULT_ENCODE_ESCAPE_FORWARD_SLASH 1 84#define DEFAULT_ENCODE_ESCAPE_FORWARD_SLASH 1
85#define DEFAULT_ENCODE_SKIP_UNSUPPORTED_VALUE_TYPES 0
85 86
86#ifdef DISABLE_INVALID_NUMBERS 87#ifdef DISABLE_INVALID_NUMBERS
87#undef DEFAULT_DECODE_INVALID_NUMBERS 88#undef DEFAULT_DECODE_INVALID_NUMBERS
@@ -165,6 +166,7 @@ typedef struct {
165 int decode_invalid_numbers; 166 int decode_invalid_numbers;
166 int decode_max_depth; 167 int decode_max_depth;
167 int decode_array_with_array_mt; 168 int decode_array_with_array_mt;
169 int encode_skip_unsupported_value_types;
168} json_config_t; 170} json_config_t;
169 171
170typedef struct { 172typedef struct {
@@ -356,6 +358,16 @@ static int json_cfg_decode_array_with_array_mt(lua_State *l)
356 return 1; 358 return 1;
357} 359}
358 360
361/* Configure how to treat invalid types */
362static int json_cfg_encode_skip_unsupported_value_types(lua_State *l)
363{
364 json_config_t *cfg = json_arg_init(l, 1);
365
366 json_enum_option(l, 1, &cfg->encode_skip_unsupported_value_types, NULL, 1);
367
368 return 1;
369}
370
359/* Configures JSON encoding buffer persistence */ 371/* Configures JSON encoding buffer persistence */
360static int json_cfg_encode_keep_buffer(lua_State *l) 372static int json_cfg_encode_keep_buffer(lua_State *l)
361{ 373{
@@ -463,6 +475,7 @@ static void json_create_config(lua_State *l)
463 cfg->encode_empty_table_as_object = DEFAULT_ENCODE_EMPTY_TABLE_AS_OBJECT; 475 cfg->encode_empty_table_as_object = DEFAULT_ENCODE_EMPTY_TABLE_AS_OBJECT;
464 cfg->decode_array_with_array_mt = DEFAULT_DECODE_ARRAY_WITH_ARRAY_MT; 476 cfg->decode_array_with_array_mt = DEFAULT_DECODE_ARRAY_WITH_ARRAY_MT;
465 cfg->encode_escape_forward_slash = DEFAULT_ENCODE_ESCAPE_FORWARD_SLASH; 477 cfg->encode_escape_forward_slash = DEFAULT_ENCODE_ESCAPE_FORWARD_SLASH;
478 cfg->encode_skip_unsupported_value_types = DEFAULT_ENCODE_SKIP_UNSUPPORTED_VALUE_TYPES;
466 479
467#if DEFAULT_ENCODE_KEEP_BUFFER > 0 480#if DEFAULT_ENCODE_KEEP_BUFFER > 0
468 strbuf_init(&cfg->encode_buf, 0); 481 strbuf_init(&cfg->encode_buf, 0);
@@ -627,7 +640,7 @@ static void json_check_encode_depth(lua_State *l, json_config_t *cfg,
627 current_depth); 640 current_depth);
628} 641}
629 642
630static void json_append_data(lua_State *l, json_config_t *cfg, 643static int json_append_data(lua_State *l, json_config_t *cfg,
631 int current_depth, strbuf_t *json); 644 int current_depth, strbuf_t *json);
632 645
633/* json_append_array args: 646/* json_append_array args:
@@ -637,19 +650,24 @@ static void json_append_data(lua_State *l, json_config_t *cfg,
637static void json_append_array(lua_State *l, json_config_t *cfg, int current_depth, 650static void json_append_array(lua_State *l, json_config_t *cfg, int current_depth,
638 strbuf_t *json, int array_length) 651 strbuf_t *json, int array_length)
639{ 652{
640 int comma, i; 653 int comma, i, json_pos, err;
641 654
642 strbuf_append_char(json, '['); 655 strbuf_append_char(json, '[');
643 656
644 comma = 0; 657 comma = 0;
645 for (i = 1; i <= array_length; i++) { 658 for (i = 1; i <= array_length; i++) {
646 if (comma) 659 json_pos = strbuf_length(json);
660 if (comma++ > 0)
647 strbuf_append_char(json, ','); 661 strbuf_append_char(json, ',');
648 else
649 comma = 1;
650 662
651 lua_rawgeti(l, -1, i); 663 lua_rawgeti(l, -1, i);
652 json_append_data(l, cfg, current_depth, json); 664 err = json_append_data(l, cfg, current_depth, json);
665 if (err) {
666 strbuf_set_length(json, json_pos);
667 if (comma == 1) {
668 comma = 0;
669 }
670 }
653 lua_pop(l, 1); 671 lua_pop(l, 1);
654 } 672 }
655 673
@@ -697,7 +715,7 @@ static void json_append_number(lua_State *l, json_config_t *cfg,
697static void json_append_object(lua_State *l, json_config_t *cfg, 715static void json_append_object(lua_State *l, json_config_t *cfg,
698 int current_depth, strbuf_t *json) 716 int current_depth, strbuf_t *json)
699{ 717{
700 int comma, keytype; 718 int comma, keytype, json_pos, err;
701 719
702 /* Object */ 720 /* Object */
703 strbuf_append_char(json, '{'); 721 strbuf_append_char(json, '{');
@@ -706,10 +724,9 @@ static void json_append_object(lua_State *l, json_config_t *cfg,
706 /* table, startkey */ 724 /* table, startkey */
707 comma = 0; 725 comma = 0;
708 while (lua_next(l, -2) != 0) { 726 while (lua_next(l, -2) != 0) {
709 if (comma) 727 json_pos = strbuf_length(json);
728 if (comma++ > 0)
710 strbuf_append_char(json, ','); 729 strbuf_append_char(json, ',');
711 else
712 comma = 1;
713 730
714 /* table, key, value */ 731 /* table, key, value */
715 keytype = lua_type(l, -2); 732 keytype = lua_type(l, -2);
@@ -727,7 +744,14 @@ static void json_append_object(lua_State *l, json_config_t *cfg,
727 } 744 }
728 745
729 /* table, key, value */ 746 /* table, key, value */
730 json_append_data(l, cfg, current_depth, json); 747 err = json_append_data(l, cfg, current_depth, json);
748 if (err) {
749 strbuf_set_length(json, json_pos);
750 if (comma == 1) {
751 comma = 0;
752 }
753 }
754
731 lua_pop(l, 1); 755 lua_pop(l, 1);
732 /* table, key */ 756 /* table, key */
733 } 757 }
@@ -735,8 +759,8 @@ static void json_append_object(lua_State *l, json_config_t *cfg,
735 strbuf_append_char(json, '}'); 759 strbuf_append_char(json, '}');
736} 760}
737 761
738/* Serialise Lua data into JSON string. */ 762/* Serialise Lua data into JSON string. Return 1 if error an error happened, else 0 */
739static void json_append_data(lua_State *l, json_config_t *cfg, 763static int json_append_data(lua_State *l, json_config_t *cfg,
740 int current_depth, strbuf_t *json) 764 int current_depth, strbuf_t *json)
741{ 765{
742 int len; 766 int len;
@@ -807,9 +831,15 @@ static void json_append_data(lua_State *l, json_config_t *cfg,
807 default: 831 default:
808 /* Remaining types (LUA_TFUNCTION, LUA_TUSERDATA, LUA_TTHREAD, 832 /* Remaining types (LUA_TFUNCTION, LUA_TUSERDATA, LUA_TTHREAD,
809 * and LUA_TLIGHTUSERDATA) cannot be serialised */ 833 * and LUA_TLIGHTUSERDATA) cannot be serialised */
810 json_encode_exception(l, cfg, json, -1, "type not supported"); 834 if (cfg->encode_skip_unsupported_value_types) {
835 return 1;
836 } else {
837 json_encode_exception(l, cfg, json, -1, "type not supported");
838 }
839
811 /* never returns */ 840 /* never returns */
812 } 841 }
842 return 0;
813} 843}
814 844
815static int json_encode(lua_State *l) 845static int json_encode(lua_State *l)
@@ -1479,6 +1509,7 @@ static int lua_cjson_new(lua_State *l)
1479 { "encode_invalid_numbers", json_cfg_encode_invalid_numbers }, 1509 { "encode_invalid_numbers", json_cfg_encode_invalid_numbers },
1480 { "decode_invalid_numbers", json_cfg_decode_invalid_numbers }, 1510 { "decode_invalid_numbers", json_cfg_decode_invalid_numbers },
1481 { "encode_escape_forward_slash", json_cfg_encode_escape_forward_slash }, 1511 { "encode_escape_forward_slash", json_cfg_encode_escape_forward_slash },
1512 { "encode_skip_unsupported_value_types", json_cfg_encode_skip_unsupported_value_types },
1482 { "new", lua_cjson_new }, 1513 { "new", lua_cjson_new },
1483 { NULL, NULL } 1514 { NULL, NULL }
1484 }; 1515 };
diff --git a/strbuf.h b/strbuf.h
index 5df0b7b..a98ee22 100644
--- a/strbuf.h
+++ b/strbuf.h
@@ -70,6 +70,7 @@ static char *strbuf_string(strbuf_t *s, int *len);
70static void strbuf_ensure_empty_length(strbuf_t *s, int len); 70static void strbuf_ensure_empty_length(strbuf_t *s, int len);
71static char *strbuf_empty_ptr(strbuf_t *s); 71static char *strbuf_empty_ptr(strbuf_t *s);
72static void strbuf_extend_length(strbuf_t *s, int len); 72static void strbuf_extend_length(strbuf_t *s, int len);
73static void strbuf_set_length(strbuf_t *s, int len);
73 74
74/* Update */ 75/* Update */
75extern void strbuf_append_fmt(strbuf_t *s, int len, const char *fmt, ...); 76extern void strbuf_append_fmt(strbuf_t *s, int len, const char *fmt, ...);
@@ -108,6 +109,11 @@ static inline char *strbuf_empty_ptr(strbuf_t *s)
108 return s->buf + s->length; 109 return s->buf + s->length;
109} 110}
110 111
112static inline void strbuf_set_length(strbuf_t *s, int len)
113{
114 s->length = len;
115}
116
111static inline void strbuf_extend_length(strbuf_t *s, int len) 117static inline void strbuf_extend_length(strbuf_t *s, int len)
112{ 118{
113 s->length += len; 119 s->length += len;
diff --git a/tests/agentzh.t b/tests/agentzh.t
index 2e7c8ce..552630a 100644
--- a/tests/agentzh.t
+++ b/tests/agentzh.t
@@ -306,3 +306,29 @@ print(b)
306{"test":"http:\/\/google.com\/google"} 306{"test":"http:\/\/google.com\/google"}
307{"test":"http://google.com/google"} 307{"test":"http://google.com/google"}
308{"test":"http:\/\/google.com\/google"} 308{"test":"http:\/\/google.com\/google"}
309
310
311
312=== TEST 22: disable error on invalid type
313--- lua
314local cjson = require "cjson"
315local f = function (x) return 2*x end
316local res, err = pcall(cjson.encode, f)
317print(err)
318local t = {f = f, valid = "valid"}
319local res, err = pcall(cjson.encode, t)
320print(err)
321local arr = {"one", "two", f, "three"}
322local res, err = pcall(cjson.encode, arr)
323print(err)
324cjson.encode_skip_unsupported_value_types(true)
325print(cjson.encode(f))
326print(cjson.encode(t))
327print(cjson.encode(arr))
328--- out
329Cannot serialise function: type not supported
330Cannot serialise function: type not supported
331Cannot serialise function: type not supported
332
333{"valid":"valid"}
334["one","two","three"]