PHP  
 PHP: Test and Code Coverage Analysis
downloads | QA | documentation | faq | getting help | mailing lists | reporting bugs | php.net sites | links | my php.net 
 

LCOV - code coverage report
Current view: top level - ext/json - json.c (source / functions) Hit Total Coverage
Test: PHP Code Coverage Lines: 123 135 91.1 %
Date: 2020-09-22 Functions: 8 10 80.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /*
       2             :   +----------------------------------------------------------------------+
       3             :   | PHP Version 7                                                        |
       4             :   +----------------------------------------------------------------------+
       5             :   | Copyright (c) 1997-2018 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             : #ifdef HAVE_CONFIG_H
      21             : #include "config.h"
      22             : #endif
      23             : 
      24             : #include "php.h"
      25             : #include "php_ini.h"
      26             : #include "ext/standard/info.h"
      27             : #include "ext/standard/html.h"
      28             : #include "zend_smart_str.h"
      29             : #include "php_json.h"
      30             : #include "php_json_encoder.h"
      31             : #include "php_json_parser.h"
      32             : #include <zend_exceptions.h>
      33             : 
      34             : static PHP_MINFO_FUNCTION(json);
      35             : static PHP_FUNCTION(json_encode);
      36             : static PHP_FUNCTION(json_decode);
      37             : static PHP_FUNCTION(json_last_error);
      38             : static PHP_FUNCTION(json_last_error_msg);
      39             : 
      40             : PHP_JSON_API zend_class_entry *php_json_serializable_ce;
      41             : 
      42             : PHP_JSON_API ZEND_DECLARE_MODULE_GLOBALS(json)
      43             : 
      44             : /* {{{ arginfo */
      45             : ZEND_BEGIN_ARG_INFO_EX(arginfo_json_encode, 0, 0, 1)
      46             :         ZEND_ARG_INFO(0, value)
      47             :         ZEND_ARG_INFO(0, options)
      48             :         ZEND_ARG_INFO(0, depth)
      49             : ZEND_END_ARG_INFO()
      50             : 
      51             : ZEND_BEGIN_ARG_INFO_EX(arginfo_json_decode, 0, 0, 1)
      52             :         ZEND_ARG_INFO(0, json)
      53             :         ZEND_ARG_INFO(0, assoc)
      54             :         ZEND_ARG_INFO(0, depth)
      55             :         ZEND_ARG_INFO(0, options)
      56             : ZEND_END_ARG_INFO()
      57             : 
      58             : ZEND_BEGIN_ARG_INFO(arginfo_json_last_error, 0)
      59             : ZEND_END_ARG_INFO()
      60             : 
      61             : ZEND_BEGIN_ARG_INFO(arginfo_json_last_error_msg, 0)
      62             : ZEND_END_ARG_INFO()
      63             : /* }}} */
      64             : 
      65             : /* {{{ json_functions[] */
      66             : static const zend_function_entry json_functions[] = {
      67             :         PHP_FE(json_encode, arginfo_json_encode)
      68             :         PHP_FE(json_decode, arginfo_json_decode)
      69             :         PHP_FE(json_last_error, arginfo_json_last_error)
      70             :         PHP_FE(json_last_error_msg, arginfo_json_last_error_msg)
      71             :         PHP_FE_END
      72             : };
      73             : /* }}} */
      74             : 
      75             : /* {{{ JsonSerializable methods */
      76             : ZEND_BEGIN_ARG_INFO(json_serialize_arginfo, 0)
      77             :         /* No arguments */
      78             : ZEND_END_ARG_INFO();
      79             : 
      80             : static const zend_function_entry json_serializable_interface[] = {
      81             :         PHP_ABSTRACT_ME(JsonSerializable, jsonSerialize, json_serialize_arginfo)
      82             :         PHP_FE_END
      83             : };
      84             : /* }}} */
      85             : 
      86             : /* Register constant for options and errors */
      87             : #define PHP_JSON_REGISTER_CONSTANT(_name, _value) \
      88             :         REGISTER_LONG_CONSTANT(_name,  _value, CONST_CS | CONST_PERSISTENT);
      89             : 
      90             : /* {{{ MINIT */
      91       25284 : static PHP_MINIT_FUNCTION(json)
      92             : {
      93             :         zend_class_entry ce;
      94             : 
      95       25284 :         INIT_CLASS_ENTRY(ce, "JsonSerializable", json_serializable_interface);
      96       25284 :         php_json_serializable_ce = zend_register_internal_interface(&ce);
      97             : 
      98             :         /* options for json_encode */
      99       25284 :         PHP_JSON_REGISTER_CONSTANT("JSON_HEX_TAG",  PHP_JSON_HEX_TAG);
     100       25284 :         PHP_JSON_REGISTER_CONSTANT("JSON_HEX_AMP",  PHP_JSON_HEX_AMP);
     101       25284 :         PHP_JSON_REGISTER_CONSTANT("JSON_HEX_APOS", PHP_JSON_HEX_APOS);
     102       25284 :         PHP_JSON_REGISTER_CONSTANT("JSON_HEX_QUOT", PHP_JSON_HEX_QUOT);
     103       25284 :         PHP_JSON_REGISTER_CONSTANT("JSON_FORCE_OBJECT", PHP_JSON_FORCE_OBJECT);
     104       25284 :         PHP_JSON_REGISTER_CONSTANT("JSON_NUMERIC_CHECK", PHP_JSON_NUMERIC_CHECK);
     105       25284 :         PHP_JSON_REGISTER_CONSTANT("JSON_UNESCAPED_SLASHES", PHP_JSON_UNESCAPED_SLASHES);
     106       25284 :         PHP_JSON_REGISTER_CONSTANT("JSON_PRETTY_PRINT", PHP_JSON_PRETTY_PRINT);
     107       25284 :         PHP_JSON_REGISTER_CONSTANT("JSON_UNESCAPED_UNICODE", PHP_JSON_UNESCAPED_UNICODE);
     108       25284 :         PHP_JSON_REGISTER_CONSTANT("JSON_PARTIAL_OUTPUT_ON_ERROR", PHP_JSON_PARTIAL_OUTPUT_ON_ERROR);
     109       25284 :         PHP_JSON_REGISTER_CONSTANT("JSON_PRESERVE_ZERO_FRACTION", PHP_JSON_PRESERVE_ZERO_FRACTION);
     110       25284 :         PHP_JSON_REGISTER_CONSTANT("JSON_UNESCAPED_LINE_TERMINATORS", PHP_JSON_UNESCAPED_LINE_TERMINATORS);
     111             : 
     112             :         /* options for json_decode */
     113       25284 :         PHP_JSON_REGISTER_CONSTANT("JSON_OBJECT_AS_ARRAY", PHP_JSON_OBJECT_AS_ARRAY);
     114       25284 :         PHP_JSON_REGISTER_CONSTANT("JSON_BIGINT_AS_STRING", PHP_JSON_BIGINT_AS_STRING);
     115             : 
     116             :         /* common options for json_decode and json_encode */
     117       25284 :         PHP_JSON_REGISTER_CONSTANT("JSON_INVALID_UTF8_IGNORE", PHP_JSON_INVALID_UTF8_IGNORE);
     118       25284 :         PHP_JSON_REGISTER_CONSTANT("JSON_INVALID_UTF8_SUBSTITUTE", PHP_JSON_INVALID_UTF8_SUBSTITUTE);
     119             : 
     120             :         /* json error constants */
     121       25284 :         PHP_JSON_REGISTER_CONSTANT("JSON_ERROR_NONE", PHP_JSON_ERROR_NONE);
     122       25284 :         PHP_JSON_REGISTER_CONSTANT("JSON_ERROR_DEPTH", PHP_JSON_ERROR_DEPTH);
     123       25284 :         PHP_JSON_REGISTER_CONSTANT("JSON_ERROR_STATE_MISMATCH", PHP_JSON_ERROR_STATE_MISMATCH);
     124       25284 :         PHP_JSON_REGISTER_CONSTANT("JSON_ERROR_CTRL_CHAR", PHP_JSON_ERROR_CTRL_CHAR);
     125       25284 :         PHP_JSON_REGISTER_CONSTANT("JSON_ERROR_SYNTAX", PHP_JSON_ERROR_SYNTAX);
     126       25284 :         PHP_JSON_REGISTER_CONSTANT("JSON_ERROR_UTF8", PHP_JSON_ERROR_UTF8);
     127       25284 :         PHP_JSON_REGISTER_CONSTANT("JSON_ERROR_RECURSION", PHP_JSON_ERROR_RECURSION);
     128       25284 :         PHP_JSON_REGISTER_CONSTANT("JSON_ERROR_INF_OR_NAN", PHP_JSON_ERROR_INF_OR_NAN);
     129       25284 :         PHP_JSON_REGISTER_CONSTANT("JSON_ERROR_UNSUPPORTED_TYPE", PHP_JSON_ERROR_UNSUPPORTED_TYPE);
     130       25284 :         PHP_JSON_REGISTER_CONSTANT("JSON_ERROR_INVALID_PROPERTY_NAME", PHP_JSON_ERROR_INVALID_PROPERTY_NAME);
     131       25284 :         PHP_JSON_REGISTER_CONSTANT("JSON_ERROR_UTF16", PHP_JSON_ERROR_UTF16);
     132             : 
     133       25284 :         return SUCCESS;
     134             : }
     135             : /* }}} */
     136             : 
     137             : /* {{{ PHP_GINIT_FUNCTION
     138             : */
     139       25284 : static PHP_GINIT_FUNCTION(json)
     140             : {
     141             : #if defined(COMPILE_DL_JSON) && defined(ZTS)
     142             :         ZEND_TSRMLS_CACHE_UPDATE();
     143             : #endif
     144       25284 :         json_globals->encoder_depth = 0;
     145       25284 :         json_globals->error_code = 0;
     146       25284 :         json_globals->encode_max_depth = PHP_JSON_PARSER_DEFAULT_DEPTH;
     147       25284 : }
     148             : /* }}} */
     149             : 
     150             : 
     151             : /* {{{ json_module_entry
     152             :  */
     153             : zend_module_entry json_module_entry = {
     154             :         STANDARD_MODULE_HEADER,
     155             :         "json",
     156             :         json_functions,
     157             :         PHP_MINIT(json),
     158             :         NULL,
     159             :         NULL,
     160             :         NULL,
     161             :         PHP_MINFO(json),
     162             :         PHP_JSON_VERSION,
     163             :         PHP_MODULE_GLOBALS(json),
     164             :         PHP_GINIT(json),
     165             :         NULL,
     166             :         NULL,
     167             :         STANDARD_MODULE_PROPERTIES_EX
     168             : };
     169             : /* }}} */
     170             : 
     171             : #ifdef COMPILE_DL_JSON
     172             : #ifdef ZTS
     173             : ZEND_TSRMLS_CACHE_DEFINE()
     174             : #endif
     175             : ZEND_GET_MODULE(json)
     176             : #endif
     177             : 
     178             : /* {{{ PHP_MINFO_FUNCTION
     179             :  */
     180         149 : static PHP_MINFO_FUNCTION(json)
     181             : {
     182         149 :         php_info_print_table_start();
     183         149 :         php_info_print_table_row(2, "json support", "enabled");
     184         149 :         php_info_print_table_row(2, "json version", PHP_JSON_VERSION);
     185         149 :         php_info_print_table_end();
     186         149 : }
     187             : /* }}} */
     188             : 
     189           0 : PHP_JSON_API int php_json_encode_ex(smart_str *buf, zval *val, int options, zend_long depth) /* {{{ */
     190             : {
     191             :         php_json_encoder encoder;
     192             :         int return_code;
     193             : 
     194           0 :         php_json_encode_init(&encoder);
     195           0 :         encoder.max_depth = depth;
     196             : 
     197           0 :         return_code = php_json_encode_zval(buf, val, options, &encoder);
     198           0 :         JSON_G(error_code) = encoder.error_code;
     199             : 
     200           0 :         return return_code;
     201             : }
     202             : /* }}} */
     203             : 
     204           0 : PHP_JSON_API int php_json_encode(smart_str *buf, zval *val, int options) /* {{{ */
     205             : {
     206           0 :         return php_json_encode_ex(buf, val, options, JSON_G(encode_max_depth));
     207             : }
     208             : /* }}} */
     209             : 
     210         230 : PHP_JSON_API int php_json_decode_ex(zval *return_value, char *str, size_t str_len, zend_long options, zend_long depth) /* {{{ */
     211             : {
     212             :         php_json_parser parser;
     213             : 
     214         230 :         php_json_parser_init(&parser, return_value, str, str_len, (int)options, (int)depth);
     215             : 
     216         230 :         if (php_json_yyparse(&parser)) {
     217          80 :                 JSON_G(error_code) = php_json_parser_error_code(&parser);
     218          80 :                 RETVAL_NULL();
     219          80 :                 return FAILURE;
     220             :         }
     221             : 
     222         150 :         return SUCCESS;
     223             : }
     224             : /* }}} */
     225             : 
     226             : /* {{{ proto string json_encode(mixed data [, int options[, int depth]])
     227             :    Returns the JSON representation of a value */
     228         465 : static PHP_FUNCTION(json_encode)
     229             : {
     230             :         zval *parameter;
     231             :         php_json_encoder encoder;
     232         465 :         smart_str buf = {0};
     233         465 :         zend_long options = 0;
     234         465 :         zend_long depth = PHP_JSON_PARSER_DEFAULT_DEPTH;
     235             : 
     236         465 :         ZEND_PARSE_PARAMETERS_START(1, 3)
     237         464 :                 Z_PARAM_ZVAL(parameter)
     238         464 :                 Z_PARAM_OPTIONAL
     239         535 :                 Z_PARAM_LONG(options)
     240          74 :                 Z_PARAM_LONG(depth)
     241         465 :         ZEND_PARSE_PARAMETERS_END();
     242             : 
     243         464 :         php_json_encode_init(&encoder);
     244         464 :         encoder.max_depth = (int)depth;
     245         464 :         php_json_encode_zval(&buf, parameter, (int)options, &encoder);
     246         464 :         JSON_G(error_code) = encoder.error_code;
     247             : 
     248         464 :         if (encoder.error_code != PHP_JSON_ERROR_NONE && !(options & PHP_JSON_PARTIAL_OUTPUT_ON_ERROR)) {
     249             :                 smart_str_free(&buf);
     250          21 :                 RETURN_FALSE;
     251             :         }
     252             : 
     253             :         smart_str_0(&buf); /* copy? */
     254         443 :         if (buf.s) {
     255         442 :                 RETURN_NEW_STR(buf.s);
     256             :         }
     257           1 :         RETURN_EMPTY_STRING();
     258             : }
     259             : /* }}} */
     260             : 
     261             : /* {{{ proto mixed json_decode(string json [, bool assoc [, long depth]])
     262             :    Decodes the JSON representation into a PHP value */
     263         247 : static PHP_FUNCTION(json_decode)
     264             : {
     265             :         char *str;
     266             :         size_t str_len;
     267         247 :         zend_bool assoc = 0; /* return JS objects as PHP objects by default */
     268         247 :         zend_bool assoc_null = 1;
     269         247 :         zend_long depth = PHP_JSON_PARSER_DEFAULT_DEPTH;
     270         247 :         zend_long options = 0;
     271             : 
     272         247 :         ZEND_PARSE_PARAMETERS_START(1, 4)
     273         488 :                 Z_PARAM_STRING(str, str_len)
     274         244 :                 Z_PARAM_OPTIONAL
     275         328 :                 Z_PARAM_BOOL_EX(assoc, assoc_null, 1, 0)
     276         101 :                 Z_PARAM_LONG(depth)
     277          32 :                 Z_PARAM_LONG(options)
     278         247 :         ZEND_PARSE_PARAMETERS_END();
     279             : 
     280         244 :         JSON_G(error_code) = PHP_JSON_ERROR_NONE;
     281             : 
     282         244 :         if (!str_len) {
     283          13 :                 JSON_G(error_code) = PHP_JSON_ERROR_SYNTAX;
     284          13 :                 RETURN_NULL();
     285             :         }
     286             : 
     287         231 :         if (depth <= 0) {
     288           0 :                 php_error_docref(NULL, E_WARNING, "Depth must be greater than zero");
     289           0 :                 RETURN_NULL();
     290             :         }
     291             : 
     292         231 :         if (depth > INT_MAX) {
     293           1 :                 php_error_docref(NULL, E_WARNING, "Depth must be lower than %d", INT_MAX);
     294           1 :                 RETURN_NULL();
     295             :         }
     296             : 
     297             :         /* For BC reasons, the bool $assoc overrides the long $options bit for PHP_JSON_OBJECT_AS_ARRAY */
     298         230 :         if (!assoc_null) {
     299          76 :                 if (assoc) {
     300          68 :                         options |=  PHP_JSON_OBJECT_AS_ARRAY;
     301             :                 } else {
     302           8 :                         options &= ~PHP_JSON_OBJECT_AS_ARRAY;
     303             :                 }
     304             :         }
     305             : 
     306         230 :         php_json_decode_ex(return_value, str, str_len, options, depth);
     307             : }
     308             : /* }}} */
     309             : 
     310             : /* {{{ proto int json_last_error()
     311             :    Returns the error code of the last json_encode() or json_decode() call. */
     312          83 : static PHP_FUNCTION(json_last_error)
     313             : {
     314          83 :         if (zend_parse_parameters_none() == FAILURE) {
     315           2 :                 return;
     316             :         }
     317             : 
     318          81 :         RETURN_LONG(JSON_G(error_code));
     319             : }
     320             : /* }}} */
     321             : 
     322             : /* {{{ proto string json_last_error_msg()
     323             :    Returns the error string of the last json_encode() or json_decode() call. */
     324          28 : static PHP_FUNCTION(json_last_error_msg)
     325             : {
     326          28 :         if (zend_parse_parameters_none() == FAILURE) {
     327           2 :                 return;
     328             :         }
     329             : 
     330          26 :         switch(JSON_G(error_code)) {
     331           2 :                 case PHP_JSON_ERROR_NONE:
     332           4 :                         RETURN_STRING("No error");
     333           1 :                 case PHP_JSON_ERROR_DEPTH:
     334           2 :                         RETURN_STRING("Maximum stack depth exceeded");
     335           1 :                 case PHP_JSON_ERROR_STATE_MISMATCH:
     336           2 :                         RETURN_STRING("State mismatch (invalid or malformed JSON)");
     337           1 :                 case PHP_JSON_ERROR_CTRL_CHAR:
     338           2 :                         RETURN_STRING("Control character error, possibly incorrectly encoded");
     339           1 :                 case PHP_JSON_ERROR_SYNTAX:
     340           2 :                         RETURN_STRING("Syntax error");
     341           8 :                 case PHP_JSON_ERROR_UTF8:
     342          16 :                         RETURN_STRING("Malformed UTF-8 characters, possibly incorrectly encoded");
     343           4 :                 case PHP_JSON_ERROR_RECURSION:
     344           8 :                         RETURN_STRING("Recursion detected");
     345           4 :                 case PHP_JSON_ERROR_INF_OR_NAN:
     346           8 :                         RETURN_STRING("Inf and NaN cannot be JSON encoded");
     347           2 :                 case PHP_JSON_ERROR_UNSUPPORTED_TYPE:
     348           4 :                         RETURN_STRING("Type is not supported");
     349           1 :                 case PHP_JSON_ERROR_INVALID_PROPERTY_NAME:
     350           2 :                         RETURN_STRING("The decoded property name is invalid");
     351           1 :                 case PHP_JSON_ERROR_UTF16:
     352           2 :                         RETURN_STRING("Single unpaired UTF-16 surrogate in unicode escape");
     353           0 :                 default:
     354           0 :                         RETURN_STRING("Unknown error");
     355             :         }
     356             : 
     357             : }
     358             : /* }}} */
     359             : 
     360             : /*
     361             :  * Local variables:
     362             :  * tab-width: 4
     363             :  * c-basic-offset: 4
     364             :  * End:
     365             :  * vim600: noet sw=4 ts=4 fdm=marker
     366             :  * vim<600: noet sw=4 ts=4
     367             :  */

Generated by: LCOV version 1.10

Generated at Tue, 22 Sep 2020 23:19:46 +0000 (10 hours ago)

Copyright © 2005-2020 The PHP Group
All rights reserved.