@@ -1966,6 +1966,8 @@ static VALUE convert_encoding(VALUE source)
19661966struct parser_config_init_args {
19671967 JSON_ParserConfig * config ;
19681968 VALUE self ;
1969+ VALUE unknown_keywords ;
1970+ bool strict ;
19691971};
19701972
19711973static void parser_config_wb_write (VALUE self , VALUE * dest , VALUE val )
@@ -2019,27 +2021,43 @@ static int parser_config_init_i(VALUE key, VALUE val, VALUE data)
20192021 }
20202022 }
20212023 }
2024+ else if (args -> strict ) {
2025+ if (!args -> unknown_keywords ) {
2026+ args -> unknown_keywords = rb_obj_hide (rb_ary_new ());
2027+ }
2028+ rb_ary_push (args -> unknown_keywords , key );
2029+ }
20222030
20232031 return ST_CONTINUE ;
20242032}
20252033
2026- static void parser_config_init (JSON_ParserConfig * config , VALUE opts , VALUE self )
2034+ static void parser_config_init (JSON_ParserConfig * config , VALUE opts , VALUE self , bool strict )
20272035{
20282036 config -> max_nesting = 100 ;
20292037
20302038 struct parser_config_init_args args = {
20312039 .config = config ,
20322040 .self = self ,
2041+ .strict = strict ,
20332042 };
20342043
2035- if (! NIL_P (opts )) {
2036- Check_Type (opts , T_HASH );
2037- if (RHASH_SIZE (opts ) > 0 ) {
2038- // We assume in most cases few keys are set so it's faster to go over
2039- // the provided keys than to check all possible keys.
2040- rb_hash_foreach ( opts , parser_config_init_i , ( VALUE ) & args );
2041- }
2044+ if (NIL_P (opts )) return ;
2045+ Check_Type (opts , T_HASH );
2046+ if (RHASH_SIZE (opts ) == 0 ) return ;
2047+
2048+ // We assume in most cases few keys are set so it's faster to go over
2049+ // the provided keys than to check all possible keys.
2050+ rb_hash_foreach ( opts , parser_config_init_i , ( VALUE ) & args );
20422051
2052+ if (RB_UNLIKELY (args .unknown_keywords )) {
2053+ if (RARRAY_LEN (args .unknown_keywords ) == 1 ) {
2054+ rb_raise (rb_eArgError , "unknown keyword: %" PRIsVALUE , RARRAY_AREF (args .unknown_keywords , 0 ));
2055+ }
2056+ else {
2057+ VALUE keywords = rb_ary_join (args .unknown_keywords , rb_utf8_str_new_cstr (", " ));
2058+ rb_raise (rb_eArgError , "unknown keywords: %s" , RSTRING_PTR (keywords ));
2059+ RB_GC_GUARD (keywords );
2060+ }
20432061 }
20442062}
20452063
@@ -2057,7 +2075,7 @@ static VALUE cParserConfig_initialize(VALUE self, VALUE opts)
20572075 rb_check_frozen (self );
20582076 GET_PARSER_CONFIG ;
20592077
2060- parser_config_init (config , opts , self );
2078+ parser_config_init (config , opts , self , false );
20612079
20622080 return self ;
20632081}
@@ -2153,7 +2171,7 @@ static VALUE cParser_m_parse(VALUE klass, VALUE Vsource, VALUE opts)
21532171{
21542172 JSON_ParserConfig _config = {0 };
21552173 JSON_ParserConfig * config = & _config ;
2156- parser_config_init (config , opts , false);
2174+ parser_config_init (config , opts , Qfalse , false);
21572175
21582176 return cParser_parse (config , Vsource );
21592177}
@@ -2342,12 +2360,14 @@ static inline JSON_ResumableParser *cResumableParser_get(VALUE self)
23422360 */
23432361static VALUE cResumableParser_initialize (int argc , VALUE * argv , VALUE self )
23442362{
2345- rb_check_arity (argc , 0 , 1 );
23462363 rb_check_frozen (self );
2364+
2365+ VALUE opts = Qfalse ;
2366+ rb_scan_args_kw (RB_SCAN_ARGS_LAST_HASH_KEYWORDS , argc , argv , "0:" , & opts );
23472367 JSON_ResumableParser * parser = cResumableParser_get (self );
23482368
2349- VALUE opts = argc > 0 ? argv [0 ] : Qnil ;
2350- parser_config_init (& parser -> config , opts , self );
2369+ opts = argc > 0 ? argv [0 ] : Qnil ;
2370+ parser_config_init (& parser -> config , opts , self , true );
23512371
23522372 return self ;
23532373}
0 commit comments