@@ -38,6 +38,7 @@ static PHP_FUNCTION(json_last_error);
38
38
static PHP_FUNCTION (json_last_error_msg );
39
39
40
40
PHP_JSON_API zend_class_entry * php_json_serializable_ce ;
41
+ PHP_JSON_API zend_class_entry * php_json_exception_ce ;
41
42
42
43
PHP_JSON_API ZEND_DECLARE_MODULE_GLOBALS (json )
43
44
@@ -95,6 +96,9 @@ static PHP_MINIT_FUNCTION(json)
95
96
INIT_CLASS_ENTRY (ce , "JsonSerializable" , json_serializable_interface );
96
97
php_json_serializable_ce = zend_register_internal_interface (& ce );
97
98
99
+ INIT_CLASS_ENTRY (ce , "JsonException" , NULL );
100
+ php_json_exception_ce = zend_register_internal_class_ex (& ce , zend_ce_exception );
101
+
98
102
/* options for json_encode */
99
103
PHP_JSON_REGISTER_CONSTANT ("JSON_HEX_TAG" , PHP_JSON_HEX_TAG );
100
104
PHP_JSON_REGISTER_CONSTANT ("JSON_HEX_AMP" , PHP_JSON_HEX_AMP );
@@ -116,6 +120,7 @@ static PHP_MINIT_FUNCTION(json)
116
120
/* common options for json_decode and json_encode */
117
121
PHP_JSON_REGISTER_CONSTANT ("JSON_INVALID_UTF8_IGNORE" , PHP_JSON_INVALID_UTF8_IGNORE );
118
122
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 );
119
124
120
125
/* json error constants */
121
126
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) /* {{{
207
212
}
208
213
/* }}} */
209
214
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
+
210
246
PHP_JSON_API int php_json_decode_ex (zval * return_value , char * str , size_t str_len , zend_long options , zend_long depth ) /* {{{ */
211
247
{
212
248
php_json_parser parser ;
213
249
214
250
php_json_parser_init (& parser , return_value , str , str_len , (int )options , (int )depth );
215
251
216
252
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
+ }
218
259
RETVAL_NULL ();
219
260
return FAILURE ;
220
261
}
@@ -243,11 +284,19 @@ static PHP_FUNCTION(json_encode)
243
284
php_json_encode_init (& encoder );
244
285
encoder .max_depth = (int )depth ;
245
286
php_json_encode_zval (& buf , parameter , (int )options , & encoder );
246
- JSON_G (error_code ) = encoder .error_code ;
247
287
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
+ }
251
300
}
252
301
253
302
smart_str_0 (& buf ); /* copy? */
@@ -277,10 +326,16 @@ static PHP_FUNCTION(json_decode)
277
326
Z_PARAM_LONG (options )
278
327
ZEND_PARSE_PARAMETERS_END ();
279
328
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
+ }
281
332
282
333
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
+ }
284
339
RETURN_NULL ();
285
340
}
286
341
@@ -327,33 +382,7 @@ static PHP_FUNCTION(json_last_error_msg)
327
382
return ;
328
383
}
329
384
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 )));
357
386
}
358
387
/* }}} */
359
388
0 commit comments