@@ -38,6 +38,7 @@ static PHP_FUNCTION(json_last_error);
3838static PHP_FUNCTION (json_last_error_msg );
3939
4040PHP_JSON_API zend_class_entry * php_json_serializable_ce ;
41+ PHP_JSON_API zend_class_entry * php_json_exception_ce ;
4142
4243PHP_JSON_API ZEND_DECLARE_MODULE_GLOBALS (json )
4344
@@ -95,6 +96,9 @@ static PHP_MINIT_FUNCTION(json)
9596 INIT_CLASS_ENTRY (ce , "JsonSerializable" , json_serializable_interface );
9697 php_json_serializable_ce = zend_register_internal_interface (& ce );
9798
99+ INIT_CLASS_ENTRY (ce , "JsonException" , NULL );
100+ php_json_exception_ce = zend_register_internal_class_ex (& ce , zend_ce_exception );
101+
98102 /* options for json_encode */
99103 PHP_JSON_REGISTER_CONSTANT ("JSON_HEX_TAG" , PHP_JSON_HEX_TAG );
100104 PHP_JSON_REGISTER_CONSTANT ("JSON_HEX_AMP" , PHP_JSON_HEX_AMP );
@@ -116,6 +120,7 @@ static PHP_MINIT_FUNCTION(json)
116120 /* common options for json_decode and json_encode */
117121 PHP_JSON_REGISTER_CONSTANT ("JSON_INVALID_UTF8_IGNORE" , PHP_JSON_INVALID_UTF8_IGNORE );
118122 PHP_JSON_REGISTER_CONSTANT ("JSON_INVALID_UTF8_SUBSTITUTE" , PHP_JSON_INVALID_UTF8_SUBSTITUTE );
123+ PHP_JSON_REGISTER_CONSTANT ("JSON_THROW_ON_ERROR" , PHP_JSON_THROW_ON_ERROR );
119124
120125 /* json error constants */
121126 PHP_JSON_REGISTER_CONSTANT ("JSON_ERROR_NONE" , PHP_JSON_ERROR_NONE );
@@ -207,14 +212,50 @@ PHP_JSON_API int php_json_encode(smart_str *buf, zval *val, int options) /* {{{
207212}
208213/* }}} */
209214
215+ static const char * php_json_get_error_msg (php_json_error_code error_code ) /* {{{ */
216+ {
217+ switch (error_code ) {
218+ case PHP_JSON_ERROR_NONE :
219+ return "No error" ;
220+ case PHP_JSON_ERROR_DEPTH :
221+ return "Maximum stack depth exceeded" ;
222+ case PHP_JSON_ERROR_STATE_MISMATCH :
223+ return "State mismatch (invalid or malformed JSON)" ;
224+ case PHP_JSON_ERROR_CTRL_CHAR :
225+ return "Control character error, possibly incorrectly encoded" ;
226+ case PHP_JSON_ERROR_SYNTAX :
227+ return "Syntax error" ;
228+ case PHP_JSON_ERROR_UTF8 :
229+ return "Malformed UTF-8 characters, possibly incorrectly encoded" ;
230+ case PHP_JSON_ERROR_RECURSION :
231+ return "Recursion detected" ;
232+ case PHP_JSON_ERROR_INF_OR_NAN :
233+ return "Inf and NaN cannot be JSON encoded" ;
234+ case PHP_JSON_ERROR_UNSUPPORTED_TYPE :
235+ return "Type is not supported" ;
236+ case PHP_JSON_ERROR_INVALID_PROPERTY_NAME :
237+ return "The decoded property name is invalid" ;
238+ case PHP_JSON_ERROR_UTF16 :
239+ return "Single unpaired UTF-16 surrogate in unicode escape" ;
240+ default :
241+ return "Unknown error" ;
242+ }
243+ }
244+ /* }}} */
245+
210246PHP_JSON_API int php_json_decode_ex (zval * return_value , char * str , size_t str_len , zend_long options , zend_long depth ) /* {{{ */
211247{
212248 php_json_parser parser ;
213249
214250 php_json_parser_init (& parser , return_value , str , str_len , (int )options , (int )depth );
215251
216252 if (php_json_yyparse (& parser )) {
217- JSON_G (error_code ) = php_json_parser_error_code (& parser );
253+ php_json_error_code error_code = php_json_parser_error_code (& parser );
254+ if (!(options & PHP_JSON_THROW_ON_ERROR )) {
255+ JSON_G (error_code ) = error_code ;
256+ } else {
257+ zend_throw_exception (php_json_exception_ce , php_json_get_error_msg (error_code ), error_code );
258+ }
218259 RETVAL_NULL ();
219260 return FAILURE ;
220261 }
@@ -243,11 +284,19 @@ static PHP_FUNCTION(json_encode)
243284 php_json_encode_init (& encoder );
244285 encoder .max_depth = (int )depth ;
245286 php_json_encode_zval (& buf , parameter , (int )options , & encoder );
246- JSON_G (error_code ) = encoder .error_code ;
247287
248- if (encoder .error_code != PHP_JSON_ERROR_NONE && !(options & PHP_JSON_PARTIAL_OUTPUT_ON_ERROR )) {
249- smart_str_free (& buf );
250- RETURN_FALSE ;
288+ if (!(options & PHP_JSON_THROW_ON_ERROR ) || (options & PHP_JSON_PARTIAL_OUTPUT_ON_ERROR )) {
289+ JSON_G (error_code ) = encoder .error_code ;
290+ if (encoder .error_code != PHP_JSON_ERROR_NONE && !(options & PHP_JSON_PARTIAL_OUTPUT_ON_ERROR )) {
291+ smart_str_free (& buf );
292+ RETURN_FALSE ;
293+ }
294+ } else {
295+ if (encoder .error_code != PHP_JSON_ERROR_NONE ) {
296+ smart_str_free (& buf );
297+ zend_throw_exception (php_json_exception_ce , php_json_get_error_msg (encoder .error_code ), encoder .error_code );
298+ RETURN_FALSE ;
299+ }
251300 }
252301
253302 smart_str_0 (& buf ); /* copy? */
@@ -277,10 +326,16 @@ static PHP_FUNCTION(json_decode)
277326 Z_PARAM_LONG (options )
278327 ZEND_PARSE_PARAMETERS_END ();
279328
280- JSON_G (error_code ) = PHP_JSON_ERROR_NONE ;
329+ if (!(options & PHP_JSON_THROW_ON_ERROR )) {
330+ JSON_G (error_code ) = PHP_JSON_ERROR_NONE ;
331+ }
281332
282333 if (!str_len ) {
283- JSON_G (error_code ) = PHP_JSON_ERROR_SYNTAX ;
334+ if (!(options & PHP_JSON_THROW_ON_ERROR )) {
335+ JSON_G (error_code ) = PHP_JSON_ERROR_SYNTAX ;
336+ } else {
337+ zend_throw_exception (php_json_exception_ce , php_json_get_error_msg (PHP_JSON_ERROR_SYNTAX ), PHP_JSON_ERROR_SYNTAX );
338+ }
284339 RETURN_NULL ();
285340 }
286341
@@ -327,33 +382,7 @@ static PHP_FUNCTION(json_last_error_msg)
327382 return ;
328383 }
329384
330- switch (JSON_G (error_code )) {
331- case PHP_JSON_ERROR_NONE :
332- RETURN_STRING ("No error" );
333- case PHP_JSON_ERROR_DEPTH :
334- RETURN_STRING ("Maximum stack depth exceeded" );
335- case PHP_JSON_ERROR_STATE_MISMATCH :
336- RETURN_STRING ("State mismatch (invalid or malformed JSON)" );
337- case PHP_JSON_ERROR_CTRL_CHAR :
338- RETURN_STRING ("Control character error, possibly incorrectly encoded" );
339- case PHP_JSON_ERROR_SYNTAX :
340- RETURN_STRING ("Syntax error" );
341- case PHP_JSON_ERROR_UTF8 :
342- RETURN_STRING ("Malformed UTF-8 characters, possibly incorrectly encoded" );
343- case PHP_JSON_ERROR_RECURSION :
344- RETURN_STRING ("Recursion detected" );
345- case PHP_JSON_ERROR_INF_OR_NAN :
346- RETURN_STRING ("Inf and NaN cannot be JSON encoded" );
347- case PHP_JSON_ERROR_UNSUPPORTED_TYPE :
348- RETURN_STRING ("Type is not supported" );
349- case PHP_JSON_ERROR_INVALID_PROPERTY_NAME :
350- RETURN_STRING ("The decoded property name is invalid" );
351- case PHP_JSON_ERROR_UTF16 :
352- RETURN_STRING ("Single unpaired UTF-16 surrogate in unicode escape" );
353- default :
354- RETURN_STRING ("Unknown error" );
355- }
356-
385+ RETURN_STRING (php_json_get_error_msg (JSON_G (error_code )));
357386}
358387/* }}} */
359388
0 commit comments