php-internal-docs 8.4.8
Unofficial docs for php/php-src
Loading...
Searching...
No Matches
json.c
Go to the documentation of this file.
1/*
2 +----------------------------------------------------------------------+
3 | Copyright (c) The PHP Group |
4 +----------------------------------------------------------------------+
5 | This source file is subject to version 3.01 of the PHP license, |
6 | that is bundled with this package in the file LICENSE, and is |
7 | available through the world-wide-web at the following url: |
8 | https://www.php.net/license/3_01.txt |
9 | If you did not receive a copy of the PHP license and are unable to |
10 | obtain it through the world-wide-web, please send a note to |
11 | license@php.net so we can mail you a copy immediately. |
12 +----------------------------------------------------------------------+
13 | Author: Omar Kilani <omar@php.net> |
14 | Jakub Zelenka <bukka@php.net> |
15 +----------------------------------------------------------------------+
16*/
17
18#ifdef HAVE_CONFIG_H
19#include <config.h>
20#endif
21
22#include "php.h"
23#include "ext/standard/info.h"
24#include "zend_smart_str.h"
25#include "php_json.h"
26#include "php_json_encoder.h"
27#include "php_json_parser.h"
28#include "json_arginfo.h"
29#include <zend_exceptions.h>
30
31static PHP_MINFO_FUNCTION(json);
32
35
37
38static int php_json_implement_json_serializable(zend_class_entry *interface, zend_class_entry *class_type)
39{
40 class_type->ce_flags |= ZEND_ACC_USE_GUARDS;
41 return SUCCESS;
42}
43
44/* {{{ MINIT */
45static PHP_MINIT_FUNCTION(json)
46{
47 php_json_serializable_ce = register_class_JsonSerializable();
48 php_json_serializable_ce->interface_gets_implemented = php_json_implement_json_serializable;
49
50 php_json_exception_ce = register_class_JsonException(zend_ce_exception);
51
52 register_json_symbols(module_number);
53
54 return SUCCESS;
55}
56/* }}} */
57
58/* {{{ PHP_GINIT_FUNCTION */
59static PHP_GINIT_FUNCTION(json)
60{
61#if defined(COMPILE_DL_JSON) && defined(ZTS)
63#endif
64 json_globals->encoder_depth = 0;
65 json_globals->error_code = 0;
66 json_globals->encode_max_depth = PHP_JSON_PARSER_DEFAULT_DEPTH;
67}
68/* }}} */
69
70static PHP_RINIT_FUNCTION(json)
71{
72 JSON_G(error_code) = 0;
73 return SUCCESS;
74}
75
76/* {{{ json_module_entry */
79 "json",
80 ext_functions,
81 PHP_MINIT(json),
82 NULL,
83 PHP_RINIT(json),
84 NULL,
85 PHP_MINFO(json),
88 PHP_GINIT(json),
89 NULL,
90 NULL,
92};
93/* }}} */
94
95#ifdef COMPILE_DL_JSON
96#ifdef ZTS
98#endif
100#endif
101
102/* {{{ PHP_MINFO_FUNCTION */
103static PHP_MINFO_FUNCTION(json)
104{
106 php_info_print_table_row(2, "json support", "enabled");
108}
109/* }}} */
110
112{
113 smart_str buf = {0};
114 php_json_encoder encoder;
115
116 php_json_encode_init(&encoder);
117
118 if (php_json_escape_string(&buf, s, len, options, &encoder) == FAILURE) {
119 smart_str_free(&buf);
120 return NULL;
121 }
122
123 return smart_str_extract(&buf);
124}
125
127{
128 php_json_encoder encoder;
129 zend_result return_code;
130
131 php_json_encode_init(&encoder);
132 encoder.max_depth = depth;
133
134 return_code = php_json_encode_zval(buf, val, options, &encoder);
135 JSON_G(error_code) = encoder.error_code;
136
137 return return_code;
138}
139/* }}} */
140
145/* }}} */
146
147static const char *php_json_get_error_msg(php_json_error_code error_code) /* {{{ */
148{
149 switch(error_code) {
151 return "No error";
153 return "Maximum stack depth exceeded";
155 return "State mismatch (invalid or malformed JSON)";
157 return "Control character error, possibly incorrectly encoded";
159 return "Syntax error";
161 return "Malformed UTF-8 characters, possibly incorrectly encoded";
163 return "Recursion detected";
165 return "Inf and NaN cannot be JSON encoded";
167 return "Type is not supported";
169 return "The decoded property name is invalid";
171 return "Single unpaired UTF-16 surrogate in unicode escape";
173 return "Non-backed enums have no default serialization";
174 default:
175 return "Unknown error";
176 }
177}
178/* }}} */
179
180PHP_JSON_API zend_result php_json_decode_ex(zval *return_value, const char *str, size_t str_len, zend_long options, zend_long depth) /* {{{ */
181{
182 php_json_parser parser;
183
184 php_json_parser_init(&parser, return_value, str, str_len, (int)options, (int)depth);
185
186 if (php_json_yyparse(&parser)) {
190 } else {
192 }
193 RETVAL_NULL();
194 return FAILURE;
195 }
196
197 return SUCCESS;
198}
199/* }}} */
200
201/* {{{ */
202PHP_JSON_API bool php_json_validate_ex(const char *str, size_t str_len, zend_long options, zend_long depth)
203{
204 php_json_parser parser;
205 zval tmp;
206 const php_json_parser_methods* parser_validate_methods = php_json_get_validate_methods();
207 php_json_parser_init_ex(&parser, &tmp, str, str_len, (int)options, (int)depth, parser_validate_methods);
208
209 if (php_json_yyparse(&parser)) {
212 return false;
213 }
214
215 return true;
216}
217/* }}} */
218
219/* {{{ Returns the JSON representation of a value */
221{
222 zval *parameter;
223 php_json_encoder encoder;
224 smart_str buf = {0};
225 zend_long options = 0;
227
229 Z_PARAM_ZVAL(parameter)
232 Z_PARAM_LONG(depth)
234
235 php_json_encode_init(&encoder);
236 encoder.max_depth = (int)depth;
237 php_json_encode_zval(&buf, parameter, (int)options, &encoder);
238
240 JSON_G(error_code) = encoder.error_code;
242 smart_str_free(&buf);
244 }
245 } else {
246 if (encoder.error_code != PHP_JSON_ERROR_NONE) {
247 smart_str_free(&buf);
248 zend_throw_exception(php_json_exception_ce, php_json_get_error_msg(encoder.error_code), encoder.error_code);
250 }
251 }
252
253 RETURN_STR(smart_str_extract(&buf));
254}
255/* }}} */
256
257/* {{{ Decodes the JSON representation into a PHP value */
259{
260 char *str;
261 size_t str_len;
262 bool assoc = 0; /* return JS objects as PHP objects by default */
263 bool assoc_null = 1;
265 zend_long options = 0;
266
268 Z_PARAM_STRING(str, str_len)
270 Z_PARAM_BOOL_OR_NULL(assoc, assoc_null)
271 Z_PARAM_LONG(depth)
274
277 }
278
279 if (!str_len) {
282 } else {
284 }
285 RETURN_NULL();
286 }
287
288 if (depth <= 0) {
289 zend_argument_value_error(3, "must be greater than 0");
291 }
292
293 if (depth > INT_MAX) {
294 zend_argument_value_error(3, "must be less than %d", INT_MAX);
296 }
297
298 /* For BC reasons, the bool $assoc overrides the long $options bit for PHP_JSON_OBJECT_AS_ARRAY */
299 if (!assoc_null) {
300 if (assoc) {
302 } else {
304 }
305 }
306
307 php_json_decode_ex(return_value, str, str_len, options, depth);
308}
309/* }}} */
310
311/* {{{ Validates if a string contains a valid json */
313{
314 char *str;
315 size_t str_len;
317 zend_long options = 0;
318
320 Z_PARAM_STRING(str, str_len)
322 Z_PARAM_LONG(depth)
325
326
327 if ((options != 0) && (options != PHP_JSON_INVALID_UTF8_IGNORE)) {
328 zend_argument_value_error(3, "must be a valid flag (allowed flags: JSON_INVALID_UTF8_IGNORE)");
330 }
331
332 if (!str_len) {
335 }
336
338
339 if (depth <= 0) {
340 zend_argument_value_error(2, "must be greater than 0");
342 }
343
344 if (depth > INT_MAX) {
345 zend_argument_value_error(2, "must be less than %d", INT_MAX);
347 }
348
349 RETURN_BOOL(php_json_validate_ex(str, str_len, options, depth));
350}
351/* }}} */
352
353/* {{{ Returns the error code of the last json_encode() or json_decode() call. */
360/* }}} */
361
362/* {{{ Returns the error string of the last json_encode() or json_decode() call. */
369/* }}} */
size_t len
Definition apprentice.c:174
char s[4]
Definition cdf.c:77
zval * val
Definition ffi.c:4262
zend_ffi_ctype_name_buf buf
Definition ffi.c:4685
#define NULL
Definition gdcache.h:45
#define SUCCESS
Definition hash_sha3.c:261
PHP_JSON_API zend_result php_json_encode_ex(smart_str *buf, zval *val, int options, zend_long depth)
Definition json.c:126
PHP_JSON_API zend_result php_json_encode(smart_str *buf, zval *val, int options)
Definition json.c:141
PHP_JSON_API zend_class_entry * php_json_exception_ce
Definition json.c:34
PHP_JSON_API bool php_json_validate_ex(const char *str, size_t str_len, zend_long options, zend_long depth)
Definition json.c:202
PHP_JSON_API zend_string * php_json_encode_string(const char *s, size_t len, int options)
Definition json.c:111
zend_module_entry json_module_entry
Definition json.c:77
PHP_JSON_API zend_class_entry * php_json_serializable_ce
Definition json.c:33
PHP_JSON_API zend_result php_json_decode_ex(zval *return_value, const char *str, size_t str_len, zend_long options, zend_long depth)
Definition json.c:180
json_last_error()
json_validate(string $json, int $depth=512, int $flags=0)
json_encode(mixed $value, int $flags=0, int $depth=512)
json_decode(string $json, ?bool $associative=null, int $depth=512, int $flags=0)
json_last_error_msg()
zend_result php_json_encode_zval(smart_str *buf, zval *val, int options, php_json_encoder *encoder)
zend_result php_json_escape_string(smart_str *buf, const char *s, size_t len, int options, php_json_encoder *encoder)
php_info_print_table_start()
Definition info.c:1064
php_info_print_table_row(2, "PDO Driver for Firebird", "enabled")
php_info_print_table_end()
Definition info.c:1074
#define PHP_GINIT
Definition php.h:397
#define PHP_FUNCTION
Definition php.h:364
#define PHP_MINFO
Definition php.h:396
#define PHP_MINIT_FUNCTION
Definition php.h:400
#define PHP_RINIT
Definition php.h:394
#define PHP_MINFO_FUNCTION
Definition php.h:404
#define PHP_GINIT_FUNCTION
Definition php.h:405
#define INT_MAX
Definition php.h:237
#define PHP_RINIT_FUNCTION
Definition php.h:402
#define PHP_MINIT
Definition php.h:392
#define PHP_MODULE_GLOBALS
Definition php.h:408
#define PHP_JSON_PARTIAL_OUTPUT_ON_ERROR
Definition php_json.h:71
#define PHP_JSON_INVALID_UTF8_IGNORE
Definition php_json.h:76
php_json_error_code
Definition php_json.h:42
@ PHP_JSON_ERROR_UNSUPPORTED_TYPE
Definition php_json.h:51
@ PHP_JSON_ERROR_INVALID_PROPERTY_NAME
Definition php_json.h:52
@ PHP_JSON_ERROR_DEPTH
Definition php_json.h:44
@ PHP_JSON_ERROR_NONE
Definition php_json.h:43
@ PHP_JSON_ERROR_UTF16
Definition php_json.h:53
@ PHP_JSON_ERROR_UTF8
Definition php_json.h:48
@ PHP_JSON_ERROR_INF_OR_NAN
Definition php_json.h:50
@ PHP_JSON_ERROR_NON_BACKED_ENUM
Definition php_json.h:54
@ PHP_JSON_ERROR_RECURSION
Definition php_json.h:49
@ PHP_JSON_ERROR_SYNTAX
Definition php_json.h:47
@ PHP_JSON_ERROR_STATE_MISMATCH
Definition php_json.h:45
@ PHP_JSON_ERROR_CTRL_CHAR
Definition php_json.h:46
int encode_max_depth
Definition php_json.h:91
#define PHP_JSON_THROW_ON_ERROR
Definition php_json.h:80
#define PHP_JSON_OBJECT_AS_ARRAY
Definition php_json.h:58
#define PHP_JSON_PARSER_DEFAULT_DEPTH
Definition php_json.h:87
#define PHP_JSON_API
Definition php_json.h:32
PHP_JSON_API size_t int options
Definition php_json.h:102
#define PHP_JSON_VERSION
Definition php_json.h:24
#define JSON_G(v)
php_json_error_code error_code
Definition php_json.h:92
struct _php_json_encoder php_json_encoder
struct _php_json_parser php_json_parser
PHP_JSON_API void php_json_parser_init_ex(php_json_parser *parser, zval *return_value, const char *str, size_t str_len, int options, int max_depth, const php_json_parser_methods *methods)
PHP_JSON_API void php_json_parser_init(php_json_parser *parser, zval *return_value, const char *str, size_t str_len, int options, int max_depth)
const php_json_parser_methods * php_json_get_validate_methods(void)
int php_json_yyparse(php_json_parser *parser)
PHP_JSON_API php_json_error_code php_json_parser_error_code(const php_json_parser *parser)
struct _php_json_parser_methods php_json_parser_methods
php_json_error_code error_code
uint32_t ce_flags
Definition zend.h:156
#define ZEND_TSRMLS_CACHE_UPDATE()
Definition zend.h:69
#define ZEND_TSRMLS_CACHE_DEFINE()
Definition zend.h:68
ZEND_API ZEND_COLD void zend_argument_value_error(uint32_t arg_num, const char *format,...)
Definition zend_API.c:433
#define RETURN_STRING(s)
Definition zend_API.h:1043
#define ZEND_PARSE_PARAMETERS_END()
Definition zend_API.h:1641
#define RETURN_FALSE
Definition zend_API.h:1058
#define ZEND_PARSE_PARAMETERS_NONE()
Definition zend_API.h:1623
#define RETURN_NULL()
Definition zend_API.h:1036
#define ZEND_DECLARE_MODULE_GLOBALS(module_name)
Definition zend_API.h:268
#define Z_PARAM_OPTIONAL
Definition zend_API.h:1667
#define ZEND_GET_MODULE(name)
Definition zend_API.h:241
#define Z_PARAM_STRING(dest, dest_len)
Definition zend_API.h:2071
#define ZEND_PARSE_PARAMETERS_START(min_num_args, max_num_args)
Definition zend_API.h:1620
#define Z_PARAM_BOOL_OR_NULL(dest, is_null)
Definition zend_API.h:1729
#define Z_PARAM_LONG(dest)
Definition zend_API.h:1896
#define RETURN_LONG(l)
Definition zend_API.h:1037
#define RETVAL_NULL()
Definition zend_API.h:1010
#define RETURN_BOOL(b)
Definition zend_API.h:1035
#define RETURN_THROWS()
Definition zend_API.h:1060
#define RETURN_STR(s)
Definition zend_API.h:1039
#define Z_PARAM_ZVAL(dest)
Definition zend_API.h:2100
struct _zval_struct zval
#define ZEND_ACC_USE_GUARDS
ZEND_API zend_class_entry * zend_ce_exception
ZEND_API ZEND_COLD zend_object * zend_throw_exception(zend_class_entry *exception_ce, const char *message, zend_long code)
int32_t zend_long
Definition zend_long.h:42
struct _zend_string zend_string
#define STANDARD_MODULE_HEADER
struct _zend_module_entry zend_module_entry
#define STANDARD_MODULE_PROPERTIES_EX
struct _zend_class_entry zend_class_entry
@ FAILURE
Definition zend_types.h:61
ZEND_RESULT_CODE zend_result
Definition zend_types.h:64
zval * return_value