@@ -1471,9 +1471,22 @@ static VALUE convert_encoding(VALUE source)
14711471 return rb_funcall (source , i_encode , 1 , Encoding_UTF_8 );
14721472}
14731473
1474+ struct parser_config_init_args {
1475+ JSON_ParserConfig * config ;
1476+ VALUE self ;
1477+ };
1478+
1479+ static void parser_config_wb_write (VALUE self , VALUE * dest , VALUE val )
1480+ {
1481+ * dest = val ;
1482+ if (self ) RB_OBJ_WRITTEN (self , Qundef , val );
1483+ }
1484+
14741485static int parser_config_init_i (VALUE key , VALUE val , VALUE data )
14751486{
1476- JSON_ParserConfig * config = (JSON_ParserConfig * )data ;
1487+ struct parser_config_init_args * args = (struct parser_config_init_args * )data ;
1488+ JSON_ParserConfig * config = args -> config ;
1489+ VALUE self = args -> self ;
14771490
14781491 if (key == sym_max_nesting ) { config -> max_nesting = RTEST (val ) ? FIX2INT (val ) : 0 ; }
14791492 else if (key == sym_allow_nan ) { config -> allow_nan = RTEST (val ); }
@@ -1482,15 +1495,15 @@ static int parser_config_init_i(VALUE key, VALUE val, VALUE data)
14821495 else if (key == sym_allow_invalid_escape ) { config -> allow_invalid_escape = RTEST (val ); }
14831496 else if (key == sym_symbolize_names ) { config -> symbolize_names = RTEST (val ); }
14841497 else if (key == sym_freeze ) { config -> freeze = RTEST (val ); }
1485- else if (key == sym_on_load ) { config -> on_load_proc = RTEST (val ) ? val : Qfalse ; }
1498+ else if (key == sym_on_load ) { parser_config_wb_write ( self , & config -> on_load_proc , RTEST (val ) ? val : Qfalse ) ; }
14861499 else if (key == sym_allow_duplicate_key ) { config -> on_duplicate_key = RTEST (val ) ? JSON_IGNORE : JSON_RAISE ; }
14871500 else if (key == sym_decimal_class ) {
14881501 if (RTEST (val )) {
14891502 if (rb_respond_to (val , i_try_convert )) {
1490- config -> decimal_class = val ;
1503+ parser_config_wb_write ( self , & config -> decimal_class , val ) ;
14911504 config -> decimal_method_id = i_try_convert ;
14921505 } else if (rb_respond_to (val , i_new )) {
1493- config -> decimal_class = val ;
1506+ parser_config_wb_write ( self , & config -> decimal_class , val ) ;
14941507 config -> decimal_method_id = i_new ;
14951508 } else if (RB_TYPE_P (val , T_CLASS )) {
14961509 VALUE name = rb_class_name (val );
@@ -1499,15 +1512,15 @@ static int parser_config_init_i(VALUE key, VALUE val, VALUE data)
14991512 if (last_colon ) {
15001513 const char * mod_path_end = last_colon - 1 ;
15011514 VALUE mod_path = rb_str_substr (name , 0 , mod_path_end - name_cstr );
1502- config -> decimal_class = rb_path_to_class (mod_path );
1515+ parser_config_wb_write ( self , & config -> decimal_class , rb_path_to_class (mod_path ) );
15031516
15041517 const char * method_name_beg = last_colon + 1 ;
15051518 long before_len = method_name_beg - name_cstr ;
15061519 long len = RSTRING_LEN (name ) - before_len ;
15071520 VALUE method_name = rb_str_substr (name , before_len , len );
15081521 config -> decimal_method_id = SYM2ID (rb_str_intern (method_name ));
15091522 } else {
1510- config -> decimal_class = rb_mKernel ;
1523+ parser_config_wb_write ( self , & config -> decimal_class , rb_mKernel ) ;
15111524 config -> decimal_method_id = SYM2ID (rb_str_intern (name ));
15121525 }
15131526 }
@@ -1517,16 +1530,21 @@ static int parser_config_init_i(VALUE key, VALUE val, VALUE data)
15171530 return ST_CONTINUE ;
15181531}
15191532
1520- static void parser_config_init (JSON_ParserConfig * config , VALUE opts )
1533+ static void parser_config_init (JSON_ParserConfig * config , VALUE opts , VALUE self )
15211534{
15221535 config -> max_nesting = 100 ;
15231536
1537+ struct parser_config_init_args args = {
1538+ .config = config ,
1539+ .self = self ,
1540+ };
1541+
15241542 if (!NIL_P (opts )) {
15251543 Check_Type (opts , T_HASH );
15261544 if (RHASH_SIZE (opts ) > 0 ) {
15271545 // We assume in most cases few keys are set so it's faster to go over
15281546 // the provided keys than to check all possible keys.
1529- rb_hash_foreach (opts , parser_config_init_i , (VALUE )config );
1547+ rb_hash_foreach (opts , parser_config_init_i , (VALUE )& args );
15301548 }
15311549
15321550 }
@@ -1560,9 +1578,7 @@ static VALUE cParserConfig_initialize(VALUE self, VALUE opts)
15601578 rb_check_frozen (self );
15611579 GET_PARSER_CONFIG ;
15621580
1563- parser_config_init (config , opts );
1564-
1565- RB_OBJ_WRITTEN (self , Qundef , config -> decimal_class );
1581+ parser_config_init (config , opts , self );
15661582
15671583 return self ;
15681584}
@@ -1624,7 +1640,7 @@ static VALUE cParser_m_parse(VALUE klass, VALUE Vsource, VALUE opts)
16241640
16251641 JSON_ParserConfig _config = {0 };
16261642 JSON_ParserConfig * config = & _config ;
1627- parser_config_init (config , opts );
1643+ parser_config_init (config , opts , false );
16281644
16291645 return cParser_parse (config , Vsource );
16301646}
0 commit comments