diff options
Diffstat (limited to 'lua_cjson.c')
| -rw-r--r-- | lua_cjson.c | 32 |
1 files changed, 25 insertions, 7 deletions
diff --git a/lua_cjson.c b/lua_cjson.c index 4642b51..8518a86 100644 --- a/lua_cjson.c +++ b/lua_cjson.c | |||
| @@ -162,6 +162,12 @@ typedef struct { | |||
| 162 | json_token_type_t ch2token[256]; | 162 | json_token_type_t ch2token[256]; |
| 163 | char escape2char[256]; /* Decoding */ | 163 | char escape2char[256]; /* Decoding */ |
| 164 | 164 | ||
| 165 | /* Per-config encoding escape table. Initialised from the global | ||
| 166 | * char2escape template, then customised per instance (e.g. by | ||
| 167 | * encode_escape_forward_slash) so that one cjson instance's settings | ||
| 168 | * never leak into another. */ | ||
| 169 | const char *char2escape[256]; | ||
| 170 | |||
| 165 | /* encode_buf is only allocated and used when | 171 | /* encode_buf is only allocated and used when |
| 166 | * encode_keep_buffer is set */ | 172 | * encode_keep_buffer is set */ |
| 167 | strbuf_t encode_buf; | 173 | strbuf_t encode_buf; |
| @@ -204,7 +210,10 @@ typedef struct { | |||
| 204 | size_t string_len; | 210 | size_t string_len; |
| 205 | } json_token_t; | 211 | } json_token_t; |
| 206 | 212 | ||
| 207 | static const char *char2escape[256] = { | 213 | /* Read-only template used to initialise each config's char2escape table. |
| 214 | * Per-instance customisation happens on json_config_t.char2escape, never | ||
| 215 | * here. */ | ||
| 216 | static const char *char2escape_template[256] = { | ||
| 208 | "\\u0000", "\\u0001", "\\u0002", "\\u0003", | 217 | "\\u0000", "\\u0001", "\\u0002", "\\u0003", |
| 209 | "\\u0004", "\\u0005", "\\u0006", "\\u0007", | 218 | "\\u0004", "\\u0005", "\\u0006", "\\u0007", |
| 210 | "\\b", "\\t", "\\n", "\\u000b", | 219 | "\\b", "\\t", "\\n", "\\u000b", |
| @@ -490,9 +499,9 @@ static int json_cfg_encode_escape_forward_slash(lua_State *l) | |||
| 490 | 499 | ||
| 491 | ret = json_enum_option(l, 1, &cfg->encode_escape_forward_slash, NULL, 1); | 500 | ret = json_enum_option(l, 1, &cfg->encode_escape_forward_slash, NULL, 1); |
| 492 | if (cfg->encode_escape_forward_slash) { | 501 | if (cfg->encode_escape_forward_slash) { |
| 493 | char2escape['/'] = "\\/"; | 502 | cfg->char2escape['/'] = "\\/"; |
| 494 | } else { | 503 | } else { |
| 495 | char2escape['/'] = NULL; | 504 | cfg->char2escape['/'] = NULL; |
| 496 | } | 505 | } |
| 497 | return ret; | 506 | return ret; |
| 498 | } | 507 | } |
| @@ -547,6 +556,14 @@ static void json_create_config(lua_State *l) | |||
| 547 | cfg->encode_skip_unsupported_value_types = DEFAULT_ENCODE_SKIP_UNSUPPORTED_VALUE_TYPES; | 556 | cfg->encode_skip_unsupported_value_types = DEFAULT_ENCODE_SKIP_UNSUPPORTED_VALUE_TYPES; |
| 548 | cfg->encode_indent = DEFAULT_ENCODE_INDENT; | 557 | cfg->encode_indent = DEFAULT_ENCODE_INDENT; |
| 549 | 558 | ||
| 559 | /* Seed this instance's escape table from the shared template, then | ||
| 560 | * apply the per-instance forward-slash setting. Mutating cfg->char2escape | ||
| 561 | * (instead of a global) keeps each cjson instance independent. */ | ||
| 562 | memcpy(cfg->char2escape, char2escape_template, sizeof(cfg->char2escape)); | ||
| 563 | if (!cfg->encode_escape_forward_slash) { | ||
| 564 | cfg->char2escape['/'] = NULL; | ||
| 565 | } | ||
| 566 | |||
| 550 | #if DEFAULT_ENCODE_KEEP_BUFFER > 0 | 567 | #if DEFAULT_ENCODE_KEEP_BUFFER > 0 |
| 551 | strbuf_init(&cfg->encode_buf, 0); | 568 | strbuf_init(&cfg->encode_buf, 0); |
| 552 | #endif | 569 | #endif |
| @@ -614,7 +631,8 @@ static void json_encode_exception(lua_State *l, json_config_t *cfg, strbuf_t *js | |||
| 614 | * - String (Lua stack index) | 631 | * - String (Lua stack index) |
| 615 | * | 632 | * |
| 616 | * Returns nothing. Doesn't remove string from Lua stack */ | 633 | * Returns nothing. Doesn't remove string from Lua stack */ |
| 617 | static void json_append_string(lua_State *l, strbuf_t *json, int lindex) | 634 | static void json_append_string(lua_State *l, json_config_t *cfg, |
| 635 | strbuf_t *json, int lindex) | ||
| 618 | { | 636 | { |
| 619 | const char *escstr; | 637 | const char *escstr; |
| 620 | const char *str; | 638 | const char *str; |
| @@ -633,7 +651,7 @@ static void json_append_string(lua_State *l, strbuf_t *json, int lindex) | |||
| 633 | 651 | ||
| 634 | strbuf_append_char_unsafe(json, '\"'); | 652 | strbuf_append_char_unsafe(json, '\"'); |
| 635 | for (i = 0; i < len; i++) { | 653 | for (i = 0; i < len; i++) { |
| 636 | escstr = char2escape[(unsigned char)str[i]]; | 654 | escstr = cfg->char2escape[(unsigned char)str[i]]; |
| 637 | if (escstr) | 655 | if (escstr) |
| 638 | strbuf_append_string(json, escstr); | 656 | strbuf_append_string(json, escstr); |
| 639 | else | 657 | else |
| @@ -848,7 +866,7 @@ static void json_append_object(lua_State *l, json_config_t *cfg, | |||
| 848 | json_append_number(l, cfg, json, -2); | 866 | json_append_number(l, cfg, json, -2); |
| 849 | strbuf_append_mem(json, "\":", 2); | 867 | strbuf_append_mem(json, "\":", 2); |
| 850 | } else if (keytype == LUA_TSTRING) { | 868 | } else if (keytype == LUA_TSTRING) { |
| 851 | json_append_string(l, json, -2); | 869 | json_append_string(l, cfg, json, -2); |
| 852 | strbuf_append_char(json, ':'); | 870 | strbuf_append_char(json, ':'); |
| 853 | } else { | 871 | } else { |
| 854 | json_encode_exception(l, cfg, json, -2, | 872 | json_encode_exception(l, cfg, json, -2, |
| @@ -889,7 +907,7 @@ static int json_append_data(lua_State *l, json_config_t *cfg, | |||
| 889 | 907 | ||
| 890 | switch (lua_type(l, -1)) { | 908 | switch (lua_type(l, -1)) { |
| 891 | case LUA_TSTRING: | 909 | case LUA_TSTRING: |
| 892 | json_append_string(l, json, -1); | 910 | json_append_string(l, cfg, json, -1); |
| 893 | break; | 911 | break; |
| 894 | case LUA_TNUMBER: | 912 | case LUA_TNUMBER: |
| 895 | json_append_number(l, cfg, json, -1); | 913 | json_append_number(l, cfg, json, -1); |
