@@ -71,6 +71,28 @@ static void generate_json_float(FBuffer *buffer, struct generate_json_data *data
71
71
72
72
static int usascii_encindex , utf8_encindex , binary_encindex ;
73
73
74
+ #ifdef RBIMPL_ATTR_NORETURN
75
+ RBIMPL_ATTR_NORETURN ()
76
+ #endif
77
+ static void raise_generator_error_str (VALUE invalid_object , VALUE str )
78
+ {
79
+ VALUE exc = rb_exc_new_str (eGeneratorError , str );
80
+ rb_ivar_set (exc , rb_intern ("@invalid_object" ), invalid_object );
81
+ rb_exc_raise (exc );
82
+ }
83
+
84
+ #ifdef RBIMPL_ATTR_NORETURN
85
+ RBIMPL_ATTR_NORETURN ()
86
+ #endif
87
+ static void raise_generator_error (VALUE invalid_object , const char * fmt , ...)
88
+ {
89
+ va_list args ;
90
+ va_start (args , fmt );
91
+ VALUE str = rb_vsprintf (fmt , args );
92
+ va_end (args );
93
+ raise_generator_error_str (invalid_object , str );
94
+ }
95
+
74
96
/* Converts in_string to a JSON string (without the wrapping '"'
75
97
* characters) in FBuffer out_buffer.
76
98
*
@@ -867,6 +889,17 @@ static inline int enc_utf8_compatible_p(int enc_idx)
867
889
return 0 ;
868
890
}
869
891
892
+ static VALUE encode_json_string_try (VALUE str )
893
+ {
894
+ return rb_funcall (str , i_encode , 1 , Encoding_UTF_8 );
895
+ }
896
+
897
+ static VALUE encode_json_string_rescue (VALUE str , VALUE exception )
898
+ {
899
+ raise_generator_error_str (str , rb_funcall (exception , rb_intern ("message" ), 0 ));
900
+ return Qundef ;
901
+ }
902
+
870
903
static inline VALUE ensure_valid_encoding (VALUE str )
871
904
{
872
905
int encindex = RB_ENCODING_GET (str );
@@ -886,7 +919,7 @@ static inline VALUE ensure_valid_encoding(VALUE str)
886
919
}
887
920
}
888
921
889
- str = rb_funcall ( str , i_encode , 1 , Encoding_UTF_8 );
922
+ str = rb_rescue ( encode_json_string_try , str , encode_json_string_rescue , str );
890
923
}
891
924
return str ;
892
925
}
@@ -909,7 +942,7 @@ static void generate_json_string(FBuffer *buffer, struct generate_json_data *dat
909
942
}
910
943
break ;
911
944
default :
912
- rb_raise ( rb_path2class ( "JSON::GeneratorError" ) , "source sequence is illegal/malformed utf-8" );
945
+ raise_generator_error ( obj , "source sequence is illegal/malformed utf-8" );
913
946
break ;
914
947
}
915
948
fbuffer_append_char (buffer , '"' );
@@ -957,10 +990,8 @@ static void generate_json_float(FBuffer *buffer, struct generate_json_data *data
957
990
char allow_nan = state -> allow_nan ;
958
991
VALUE tmp = rb_funcall (obj , i_to_s , 0 );
959
992
if (!allow_nan ) {
960
- if (isinf (value )) {
961
- rb_raise (eGeneratorError , "%" PRIsVALUE " not allowed in JSON" , tmp );
962
- } else if (isnan (value )) {
963
- rb_raise (eGeneratorError , "%" PRIsVALUE " not allowed in JSON" , tmp );
993
+ if (isinf (value ) || isnan (value )) {
994
+ raise_generator_error (obj , "%" PRIsVALUE " not allowed in JSON" , tmp );
964
995
}
965
996
}
966
997
fbuffer_append_str (buffer , tmp );
@@ -1008,7 +1039,7 @@ static void generate_json(FBuffer *buffer, struct generate_json_data *data, JSON
1008
1039
default :
1009
1040
general :
1010
1041
if (state -> strict ) {
1011
- rb_raise ( eGeneratorError , "%" PRIsVALUE " not allowed in JSON" , CLASS_OF (obj ));
1042
+ raise_generator_error ( obj , "%" PRIsVALUE " not allowed in JSON" , CLASS_OF (obj ));
1012
1043
} else if (rb_respond_to (obj , i_to_json )) {
1013
1044
tmp = rb_funcall (obj , i_to_json , 1 , vstate_get (data ));
1014
1045
Check_Type (tmp , T_STRING );
@@ -1036,10 +1067,6 @@ static VALUE generate_json_rescue(VALUE d, VALUE exc)
1036
1067
struct generate_json_data * data = (struct generate_json_data * )d ;
1037
1068
fbuffer_free (data -> buffer );
1038
1069
1039
- if (RBASIC_CLASS (exc ) == rb_path2class ("Encoding::UndefinedConversionError" )) {
1040
- exc = rb_exc_new_str (eGeneratorError , rb_funcall (exc , rb_intern ("message" ), 0 ));
1041
- }
1042
-
1043
1070
rb_exc_raise (exc );
1044
1071
1045
1072
return Qundef ;
@@ -1537,10 +1564,11 @@ void Init_generator(void)
1537
1564
VALUE mExt = rb_define_module_under (mJSON , "Ext" );
1538
1565
VALUE mGenerator = rb_define_module_under (mExt , "Generator" );
1539
1566
1567
+ rb_global_variable (& eGeneratorError );
1540
1568
eGeneratorError = rb_path2class ("JSON::GeneratorError" );
1569
+
1570
+ rb_global_variable (& eNestingError );
1541
1571
eNestingError = rb_path2class ("JSON::NestingError" );
1542
- rb_gc_register_mark_object (eGeneratorError );
1543
- rb_gc_register_mark_object (eNestingError );
1544
1572
1545
1573
cState = rb_define_class_under (mGenerator , "State" , rb_cObject );
1546
1574
rb_define_alloc_func (cState , cState_s_allocate );
0 commit comments