json
Advanced tools
+5
-0
@@ -5,2 +5,7 @@ # Changes | ||
| ### 2026-05-28 (2.19.6) | ||
| * Cleanly handle overly large `depth` generator argument. | ||
| * Add missing write barrier in `ParserConfig`. | ||
| ### 2026-05-04 (2.19.5) | ||
@@ -7,0 +12,0 @@ |
@@ -134,2 +134,11 @@ #ifndef _FBUFFER_H_ | ||
| static inline size_t fbuffer_size_mul_or_raise(size_t a, size_t b) | ||
| { | ||
| size_t result = a * b; | ||
| if (RB_UNLIKELY(a != 0 && (result / a) != b)) { | ||
| rb_raise(rb_eArgError, "Buffer overflow, the resulting document is too large to be generated"); | ||
| } | ||
| return result; | ||
| } | ||
| static inline void fbuffer_append_reserved(FBuffer *fb, const char *newstr, size_t len) | ||
@@ -179,3 +188,3 @@ { | ||
| fbuffer_inc_capa(fb, repeat * len); | ||
| fbuffer_inc_capa(fb, fbuffer_size_mul_or_raise(repeat, len)); | ||
| while (repeat) { | ||
@@ -182,0 +191,0 @@ #if JSON_DEBUG |
@@ -1474,5 +1474,18 @@ #include "../json.h" | ||
| struct parser_config_init_args { | ||
| JSON_ParserConfig *config; | ||
| VALUE self; | ||
| }; | ||
| static void parser_config_wb_write(VALUE self, VALUE *dest, VALUE val) | ||
| { | ||
| *dest = val; | ||
| if (self) RB_OBJ_WRITTEN(self, Qundef, val); | ||
| } | ||
| static int parser_config_init_i(VALUE key, VALUE val, VALUE data) | ||
| { | ||
| JSON_ParserConfig *config = (JSON_ParserConfig *)data; | ||
| struct parser_config_init_args *args = (struct parser_config_init_args *)data; | ||
| JSON_ParserConfig *config = args->config; | ||
| VALUE self = args->self; | ||
@@ -1486,3 +1499,3 @@ if (key == sym_max_nesting) { config->max_nesting = RTEST(val) ? FIX2INT(val) : 0; } | ||
| else if (key == sym_freeze) { config->freeze = RTEST(val); } | ||
| else if (key == sym_on_load) { config->on_load_proc = RTEST(val) ? val : Qfalse; } | ||
| else if (key == sym_on_load) { parser_config_wb_write(self, &config->on_load_proc, RTEST(val) ? val : Qfalse); } | ||
| else if (key == sym_allow_duplicate_key) { config->on_duplicate_key = RTEST(val) ? JSON_IGNORE : JSON_RAISE; } | ||
@@ -1492,6 +1505,6 @@ else if (key == sym_decimal_class) { | ||
| if (rb_respond_to(val, i_try_convert)) { | ||
| config->decimal_class = val; | ||
| parser_config_wb_write(self, &config->decimal_class, val); | ||
| config->decimal_method_id = i_try_convert; | ||
| } else if (rb_respond_to(val, i_new)) { | ||
| config->decimal_class = val; | ||
| parser_config_wb_write(self, &config->decimal_class, val); | ||
| config->decimal_method_id = i_new; | ||
@@ -1505,3 +1518,3 @@ } else if (RB_TYPE_P(val, T_CLASS)) { | ||
| VALUE mod_path = rb_str_substr(name, 0, mod_path_end - name_cstr); | ||
| config->decimal_class = rb_path_to_class(mod_path); | ||
| parser_config_wb_write(self, &config->decimal_class, rb_path_to_class(mod_path)); | ||
@@ -1514,3 +1527,3 @@ const char *method_name_beg = last_colon + 1; | ||
| } else { | ||
| config->decimal_class = rb_mKernel; | ||
| parser_config_wb_write(self, &config->decimal_class, rb_mKernel); | ||
| config->decimal_method_id = SYM2ID(rb_str_intern(name)); | ||
@@ -1525,6 +1538,11 @@ } | ||
| static void parser_config_init(JSON_ParserConfig *config, VALUE opts) | ||
| static void parser_config_init(JSON_ParserConfig *config, VALUE opts, VALUE self) | ||
| { | ||
| config->max_nesting = 100; | ||
| struct parser_config_init_args args = { | ||
| .config = config, | ||
| .self = self, | ||
| }; | ||
| if (!NIL_P(opts)) { | ||
@@ -1535,3 +1553,3 @@ Check_Type(opts, T_HASH); | ||
| // the provided keys than to check all possible keys. | ||
| rb_hash_foreach(opts, parser_config_init_i, (VALUE)config); | ||
| rb_hash_foreach(opts, parser_config_init_i, (VALUE)&args); | ||
| } | ||
@@ -1570,6 +1588,4 @@ | ||
| parser_config_init(config, opts); | ||
| parser_config_init(config, opts, self); | ||
| RB_OBJ_WRITTEN(self, Qundef, config->decimal_class); | ||
| return self; | ||
@@ -1635,3 +1651,3 @@ } | ||
| JSON_ParserConfig *config = &_config; | ||
| parser_config_init(config, opts); | ||
| parser_config_init(config, opts, false); | ||
@@ -1638,0 +1654,0 @@ return cParser_parse(config, Vsource); |
| # frozen_string_literal: true | ||
| module JSON | ||
| VERSION = '2.19.5' | ||
| VERSION = '2.19.6' | ||
| end |