root/ext/json/json.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. PHP_MINIT_FUNCTION
  2. PHP_GINIT_FUNCTION
  3. ZEND_TSRMLS_CACHE_DEFINE
  4. php_json_encode
  5. php_json_decode_ex
  6. PHP_FUNCTION
  7. PHP_FUNCTION
  8. PHP_FUNCTION
  9. PHP_FUNCTION

   1 /*
   2   +----------------------------------------------------------------------+
   3   | PHP Version 7                                                        |
   4   +----------------------------------------------------------------------+
   5   | Copyright (c) 1997-2016 The PHP Group                                |
   6   +----------------------------------------------------------------------+
   7   | This source file is subject to version 3.01 of the PHP license,      |
   8   | that is bundled with this package in the file LICENSE, and is        |
   9   | available through the world-wide-web at the following url:           |
  10   | http://www.php.net/license/3_01.txt                                  |
  11   | If you did not receive a copy of the PHP license and are unable to   |
  12   | obtain it through the world-wide-web, please send a note to          |
  13   | license@php.net so we can mail you a copy immediately.               |
  14   +----------------------------------------------------------------------+
  15   | Author: Omar Kilani <omar@php.net>                                   |
  16   |         Jakub Zelenka <bukka@php.net>                                |
  17   +----------------------------------------------------------------------+
  18 */
  19 
  20 /* $Id$ */
  21 
  22 #ifdef HAVE_CONFIG_H
  23 #include "config.h"
  24 #endif
  25 
  26 #include "php.h"
  27 #include "php_ini.h"
  28 #include "ext/standard/info.h"
  29 #include "ext/standard/html.h"
  30 #include "zend_smart_str.h"
  31 #include "php_json.h"
  32 #include "php_json_encoder.h"
  33 #include "php_json_parser.h"
  34 #include <zend_exceptions.h>
  35 
  36 #include <float.h>
  37 #if defined(DBL_MANT_DIG) && defined(DBL_MIN_EXP)
  38 #define NUM_BUF_SIZE (3 + DBL_MANT_DIG - DBL_MIN_EXP)
  39 #else
  40 #define NUM_BUF_SIZE 1080
  41 #endif
  42 
  43 
  44 static PHP_MINFO_FUNCTION(json);
  45 static PHP_FUNCTION(json_encode);
  46 static PHP_FUNCTION(json_decode);
  47 static PHP_FUNCTION(json_last_error);
  48 static PHP_FUNCTION(json_last_error_msg);
  49 
  50 PHP_JSON_API zend_class_entry *php_json_serializable_ce;
  51 
  52 PHP_JSON_API ZEND_DECLARE_MODULE_GLOBALS(json)
  53 
  54 /* {{{ arginfo */
  55 ZEND_BEGIN_ARG_INFO_EX(arginfo_json_encode, 0, 0, 1)
  56         ZEND_ARG_INFO(0, value)
  57         ZEND_ARG_INFO(0, options)
  58         ZEND_ARG_INFO(0, depth)
  59 ZEND_END_ARG_INFO()
  60 
  61 ZEND_BEGIN_ARG_INFO_EX(arginfo_json_decode, 0, 0, 1)
  62         ZEND_ARG_INFO(0, json)
  63         ZEND_ARG_INFO(0, assoc)
  64         ZEND_ARG_INFO(0, depth)
  65         ZEND_ARG_INFO(0, options)
  66 ZEND_END_ARG_INFO()
  67 
  68 ZEND_BEGIN_ARG_INFO(arginfo_json_last_error, 0)
  69 ZEND_END_ARG_INFO()
  70 
  71 ZEND_BEGIN_ARG_INFO(arginfo_json_last_error_msg, 0)
  72 ZEND_END_ARG_INFO()
  73 /* }}} */
  74 
  75 /* {{{ json_functions[] */
  76 static const zend_function_entry json_functions[] = {
  77         PHP_FE(json_encode, arginfo_json_encode)
  78         PHP_FE(json_decode, arginfo_json_decode)
  79         PHP_FE(json_last_error, arginfo_json_last_error)
  80         PHP_FE(json_last_error_msg, arginfo_json_last_error_msg)
  81         PHP_FE_END
  82 };
  83 /* }}} */
  84 
  85 /* {{{ JsonSerializable methods */
  86 ZEND_BEGIN_ARG_INFO(json_serialize_arginfo, 0)
  87         /* No arguments */
  88 ZEND_END_ARG_INFO();
  89 
  90 static const zend_function_entry json_serializable_interface[] = {
  91         PHP_ABSTRACT_ME(JsonSerializable, jsonSerialize, json_serialize_arginfo)
  92         PHP_FE_END
  93 };
  94 /* }}} */
  95 
  96 /* Register constant for options and errors */
  97 #define PHP_JSON_REGISTER_CONSTANT(_name, _value) \
  98         REGISTER_LONG_CONSTANT(_name,  _value, CONST_CS | CONST_PERSISTENT);
  99 
 100 /* {{{ MINIT */
 101 static PHP_MINIT_FUNCTION(json)
 102 {
 103         zend_class_entry ce;
 104 
 105         INIT_CLASS_ENTRY(ce, "JsonSerializable", json_serializable_interface);
 106         php_json_serializable_ce = zend_register_internal_interface(&ce);
 107 
 108         /* options for json_encode */
 109         PHP_JSON_REGISTER_CONSTANT("JSON_HEX_TAG",  PHP_JSON_HEX_TAG);
 110         PHP_JSON_REGISTER_CONSTANT("JSON_HEX_AMP",  PHP_JSON_HEX_AMP);
 111         PHP_JSON_REGISTER_CONSTANT("JSON_HEX_APOS", PHP_JSON_HEX_APOS);
 112         PHP_JSON_REGISTER_CONSTANT("JSON_HEX_QUOT", PHP_JSON_HEX_QUOT);
 113         PHP_JSON_REGISTER_CONSTANT("JSON_FORCE_OBJECT", PHP_JSON_FORCE_OBJECT);
 114         PHP_JSON_REGISTER_CONSTANT("JSON_NUMERIC_CHECK", PHP_JSON_NUMERIC_CHECK);
 115         PHP_JSON_REGISTER_CONSTANT("JSON_UNESCAPED_SLASHES", PHP_JSON_UNESCAPED_SLASHES);
 116         PHP_JSON_REGISTER_CONSTANT("JSON_PRETTY_PRINT", PHP_JSON_PRETTY_PRINT);
 117         PHP_JSON_REGISTER_CONSTANT("JSON_UNESCAPED_UNICODE", PHP_JSON_UNESCAPED_UNICODE);
 118         PHP_JSON_REGISTER_CONSTANT("JSON_PARTIAL_OUTPUT_ON_ERROR", PHP_JSON_PARTIAL_OUTPUT_ON_ERROR);
 119         PHP_JSON_REGISTER_CONSTANT("JSON_PRESERVE_ZERO_FRACTION", PHP_JSON_PRESERVE_ZERO_FRACTION);
 120 
 121         /* options for json_decode */
 122         PHP_JSON_REGISTER_CONSTANT("JSON_OBJECT_AS_ARRAY", PHP_JSON_OBJECT_AS_ARRAY);
 123         PHP_JSON_REGISTER_CONSTANT("JSON_BIGINT_AS_STRING", PHP_JSON_BIGINT_AS_STRING);
 124 
 125         /* json error constants */
 126         PHP_JSON_REGISTER_CONSTANT("JSON_ERROR_NONE", PHP_JSON_ERROR_NONE);
 127         PHP_JSON_REGISTER_CONSTANT("JSON_ERROR_DEPTH", PHP_JSON_ERROR_DEPTH);
 128         PHP_JSON_REGISTER_CONSTANT("JSON_ERROR_STATE_MISMATCH", PHP_JSON_ERROR_STATE_MISMATCH);
 129         PHP_JSON_REGISTER_CONSTANT("JSON_ERROR_CTRL_CHAR", PHP_JSON_ERROR_CTRL_CHAR);
 130         PHP_JSON_REGISTER_CONSTANT("JSON_ERROR_SYNTAX", PHP_JSON_ERROR_SYNTAX);
 131         PHP_JSON_REGISTER_CONSTANT("JSON_ERROR_UTF8", PHP_JSON_ERROR_UTF8);
 132         PHP_JSON_REGISTER_CONSTANT("JSON_ERROR_RECURSION", PHP_JSON_ERROR_RECURSION);
 133         PHP_JSON_REGISTER_CONSTANT("JSON_ERROR_INF_OR_NAN", PHP_JSON_ERROR_INF_OR_NAN);
 134         PHP_JSON_REGISTER_CONSTANT("JSON_ERROR_UNSUPPORTED_TYPE", PHP_JSON_ERROR_UNSUPPORTED_TYPE);
 135         PHP_JSON_REGISTER_CONSTANT("JSON_ERROR_INVALID_PROPERTY_NAME", PHP_JSON_ERROR_INVALID_PROPERTY_NAME);
 136         PHP_JSON_REGISTER_CONSTANT("JSON_ERROR_UTF16", PHP_JSON_ERROR_UTF16);
 137 
 138         return SUCCESS;
 139 }
 140 /* }}} */
 141 
 142 /* {{{ PHP_GINIT_FUNCTION
 143 */
 144 static PHP_GINIT_FUNCTION(json)
 145 {
 146 #if defined(COMPILE_DL_JSON) && defined(ZTS)
 147         ZEND_TSRMLS_CACHE_UPDATE();
 148 #endif
 149         json_globals->encoder_depth = 0;
 150         json_globals->error_code = 0;
 151         json_globals->encode_max_depth = 0;
 152 }
 153 /* }}} */
 154 
 155 
 156 /* {{{ json_module_entry
 157  */
 158 zend_module_entry json_module_entry = {
 159         STANDARD_MODULE_HEADER,
 160         "json",
 161         json_functions,
 162         PHP_MINIT(json),
 163         NULL,
 164         NULL,
 165         NULL,
 166         PHP_MINFO(json),
 167         PHP_JSON_VERSION,
 168         PHP_MODULE_GLOBALS(json),
 169         PHP_GINIT(json),
 170         NULL,
 171         NULL,
 172         STANDARD_MODULE_PROPERTIES_EX
 173 };
 174 /* }}} */
 175 
 176 #ifdef COMPILE_DL_JSON
 177 #ifdef ZTS
 178 ZEND_TSRMLS_CACHE_DEFINE()
 179 #endif
 180 ZEND_GET_MODULE(json)
 181 #endif
 182 
 183 /* {{{ PHP_MINFO_FUNCTION
 184  */
 185 static PHP_MINFO_FUNCTION(json)
 186 {
 187         php_info_print_table_start();
 188         php_info_print_table_row(2, "json support", "enabled");
 189         php_info_print_table_row(2, "json version", PHP_JSON_VERSION);
 190         php_info_print_table_end();
 191 }
 192 /* }}} */
 193 
 194 PHP_JSON_API void php_json_encode(smart_str *buf, zval *val, int options) /* {{{ */
 195 {
 196         php_json_encode_zval(buf, val, options);
 197 }
 198 /* }}} */
 199 
 200 PHP_JSON_API void php_json_decode_ex(zval *return_value, char *str, size_t str_len, zend_long options, zend_long depth) /* {{{ */
 201 {
 202         php_json_parser parser;
 203 
 204         php_json_parser_init(&parser, return_value, str, str_len, (int)options, (int)depth);
 205 
 206         if (php_json_yyparse(&parser)) {
 207                 JSON_G(error_code) = php_json_parser_error_code(&parser);
 208                 RETURN_NULL();
 209         }
 210 }
 211 /* }}} */
 212 
 213 /* {{{ proto string json_encode(mixed data [, int options[, int depth]])
 214    Returns the JSON representation of a value */
 215 static PHP_FUNCTION(json_encode)
 216 {
 217         zval *parameter;
 218         smart_str buf = {0};
 219         zend_long options = 0;
 220         zend_long depth = PHP_JSON_PARSER_DEFAULT_DEPTH;
 221 
 222         if (zend_parse_parameters(ZEND_NUM_ARGS(), "z|ll", &parameter, &options, &depth) == FAILURE) {
 223                 return;
 224         }
 225 
 226         JSON_G(error_code) = PHP_JSON_ERROR_NONE;
 227 
 228         JSON_G(encode_max_depth) = (int)depth;
 229 
 230         php_json_encode(&buf, parameter, (int)options);
 231 
 232         if (JSON_G(error_code) != PHP_JSON_ERROR_NONE && !(options & PHP_JSON_PARTIAL_OUTPUT_ON_ERROR)) {
 233                 smart_str_free(&buf);
 234                 ZVAL_FALSE(return_value);
 235         } else {
 236                 smart_str_0(&buf); /* copy? */
 237                 ZVAL_NEW_STR(return_value, buf.s);
 238         }
 239 }
 240 /* }}} */
 241 
 242 /* {{{ proto mixed json_decode(string json [, bool assoc [, long depth]])
 243    Decodes the JSON representation into a PHP value */
 244 static PHP_FUNCTION(json_decode)
 245 {
 246         char *str;
 247         size_t str_len;
 248         zend_bool assoc = 0; /* return JS objects as PHP objects by default */
 249         zend_long depth = PHP_JSON_PARSER_DEFAULT_DEPTH;
 250         zend_long options = 0;
 251 
 252         if (zend_parse_parameters(ZEND_NUM_ARGS(), "s|bll", &str, &str_len, &assoc, &depth, &options) == FAILURE) {
 253                 return;
 254         }
 255 
 256         JSON_G(error_code) = 0;
 257 
 258         if (!str_len) {
 259                 JSON_G(error_code) = PHP_JSON_ERROR_SYNTAX;
 260                 RETURN_NULL();
 261         }
 262 
 263         /* For BC reasons, the bool $assoc overrides the long $options bit for PHP_JSON_OBJECT_AS_ARRAY */
 264         if (assoc) {
 265                 options |=  PHP_JSON_OBJECT_AS_ARRAY;
 266         } else {
 267                 options &= ~PHP_JSON_OBJECT_AS_ARRAY;
 268         }
 269 
 270         php_json_decode_ex(return_value, str, str_len, options, depth);
 271 }
 272 /* }}} */
 273 
 274 /* {{{ proto int json_last_error()
 275    Returns the error code of the last json_encode() or json_decode() call. */
 276 static PHP_FUNCTION(json_last_error)
 277 {
 278         if (zend_parse_parameters_none() == FAILURE) {
 279                 return;
 280         }
 281 
 282         RETURN_LONG(JSON_G(error_code));
 283 }
 284 /* }}} */
 285 
 286 /* {{{ proto string json_last_error_msg()
 287    Returns the error string of the last json_encode() or json_decode() call. */
 288 static PHP_FUNCTION(json_last_error_msg)
 289 {
 290         if (zend_parse_parameters_none() == FAILURE) {
 291                 return;
 292         }
 293 
 294         switch(JSON_G(error_code)) {
 295                 case PHP_JSON_ERROR_NONE:
 296                         RETURN_STRING("No error");
 297                 case PHP_JSON_ERROR_DEPTH:
 298                         RETURN_STRING("Maximum stack depth exceeded");
 299                 case PHP_JSON_ERROR_STATE_MISMATCH:
 300                         RETURN_STRING("State mismatch (invalid or malformed JSON)");
 301                 case PHP_JSON_ERROR_CTRL_CHAR:
 302                         RETURN_STRING("Control character error, possibly incorrectly encoded");
 303                 case PHP_JSON_ERROR_SYNTAX:
 304                         RETURN_STRING("Syntax error");
 305                 case PHP_JSON_ERROR_UTF8:
 306                         RETURN_STRING("Malformed UTF-8 characters, possibly incorrectly encoded");
 307                 case PHP_JSON_ERROR_RECURSION:
 308                         RETURN_STRING("Recursion detected");
 309                 case PHP_JSON_ERROR_INF_OR_NAN:
 310                         RETURN_STRING("Inf and NaN cannot be JSON encoded");
 311                 case PHP_JSON_ERROR_UNSUPPORTED_TYPE:
 312                         RETURN_STRING("Type is not supported");
 313                 case PHP_JSON_ERROR_INVALID_PROPERTY_NAME:
 314                         RETURN_STRING("The decoded property name is invalid");
 315                 case PHP_JSON_ERROR_UTF16:
 316                         RETURN_STRING("Single unpaired UTF-16 surrogate in unicode escape");
 317                 default:
 318                         RETURN_STRING("Unknown error");
 319         }
 320 
 321 }
 322 /* }}} */
 323 
 324 /*
 325  * Local variables:
 326  * tab-width: 4
 327  * c-basic-offset: 4
 328  * End:
 329  * vim600: noet sw=4 ts=4 fdm=marker
 330  * vim<600: noet sw=4 ts=4
 331  */

/* [<][>][^][v][top][bottom][index][help] */