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

Generated by: LCOV version 1.10

Generated at Sat, 08 Dec 2018 23:47:39 +0000 (3 days ago)

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