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: 244 261 93.5 %
Date: 2014-07-27 Functions: 11 11 100.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /*
       2             :   +----------------------------------------------------------------------+
       3             :   | PHP Version 5                                                        |
       4             :   +----------------------------------------------------------------------+
       5             :   | Copyright (c) 1997-2013 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             :   +----------------------------------------------------------------------+
      17             : */
      18             : 
      19             : /* $Id$ */
      20             : 
      21             : #ifdef HAVE_CONFIG_H
      22             : #include "config.h"
      23             : #endif
      24             : 
      25             : #include "php.h"
      26             : #include "php_ini.h"
      27             : #include "ext/standard/info.h"
      28             : #include "ext/standard/php_smart_str.h"
      29             : #include "utf8_to_utf16.h"
      30             : #include "JSON_parser.h"
      31             : #include "php_json.h"
      32             : 
      33             : static PHP_MINFO_FUNCTION(json);
      34             : static PHP_FUNCTION(json_encode);
      35             : static PHP_FUNCTION(json_decode);
      36             : static PHP_FUNCTION(json_last_error);
      37             : 
      38             : static const char digits[] = "0123456789abcdef";
      39             : 
      40             : ZEND_DECLARE_MODULE_GLOBALS(json)
      41             : 
      42             : /* {{{ arginfo */
      43             : ZEND_BEGIN_ARG_INFO_EX(arginfo_json_encode, 0, 0, 1)
      44             :         ZEND_ARG_INFO(0, value)
      45             :         ZEND_ARG_INFO(0, options)
      46             : ZEND_END_ARG_INFO()
      47             : 
      48             : ZEND_BEGIN_ARG_INFO_EX(arginfo_json_decode, 0, 0, 1)
      49             :         ZEND_ARG_INFO(0, json)
      50             :         ZEND_ARG_INFO(0, assoc)
      51             :         ZEND_ARG_INFO(0, depth)
      52             : ZEND_END_ARG_INFO()
      53             : 
      54             : ZEND_BEGIN_ARG_INFO(arginfo_json_last_error, 0)
      55             : ZEND_END_ARG_INFO()
      56             : /* }}} */
      57             : 
      58             : /* {{{ json_functions[] */
      59             : static const function_entry json_functions[] = {
      60             :         PHP_FE(json_encode, arginfo_json_encode)
      61             :         PHP_FE(json_decode, arginfo_json_decode)
      62             :         PHP_FE(json_last_error, arginfo_json_last_error)
      63             :         PHP_FE_END
      64             : };
      65             : /* }}} */
      66             : 
      67             : /* {{{ MINIT */
      68       19341 : static PHP_MINIT_FUNCTION(json)
      69             : {
      70       19341 :         REGISTER_LONG_CONSTANT("JSON_HEX_TAG",  PHP_JSON_HEX_TAG,  CONST_CS | CONST_PERSISTENT);
      71       19341 :         REGISTER_LONG_CONSTANT("JSON_HEX_AMP",  PHP_JSON_HEX_AMP,  CONST_CS | CONST_PERSISTENT);
      72       19341 :         REGISTER_LONG_CONSTANT("JSON_HEX_APOS", PHP_JSON_HEX_APOS, CONST_CS | CONST_PERSISTENT);
      73       19341 :         REGISTER_LONG_CONSTANT("JSON_HEX_QUOT", PHP_JSON_HEX_QUOT, CONST_CS | CONST_PERSISTENT);
      74       19341 :         REGISTER_LONG_CONSTANT("JSON_FORCE_OBJECT", PHP_JSON_FORCE_OBJECT, CONST_CS | CONST_PERSISTENT);
      75       19341 :         REGISTER_LONG_CONSTANT("JSON_NUMERIC_CHECK", PHP_JSON_NUMERIC_CHECK, CONST_CS | CONST_PERSISTENT);
      76             : 
      77       19341 :         REGISTER_LONG_CONSTANT("JSON_ERROR_NONE", PHP_JSON_ERROR_NONE, CONST_CS | CONST_PERSISTENT);
      78       19341 :         REGISTER_LONG_CONSTANT("JSON_ERROR_DEPTH", PHP_JSON_ERROR_DEPTH, CONST_CS | CONST_PERSISTENT);
      79       19341 :         REGISTER_LONG_CONSTANT("JSON_ERROR_STATE_MISMATCH", PHP_JSON_ERROR_STATE_MISMATCH, CONST_CS | CONST_PERSISTENT);
      80       19341 :         REGISTER_LONG_CONSTANT("JSON_ERROR_CTRL_CHAR", PHP_JSON_ERROR_CTRL_CHAR, CONST_CS | CONST_PERSISTENT);
      81       19341 :         REGISTER_LONG_CONSTANT("JSON_ERROR_SYNTAX", PHP_JSON_ERROR_SYNTAX, CONST_CS | CONST_PERSISTENT);
      82       19341 :         REGISTER_LONG_CONSTANT("JSON_ERROR_UTF8", PHP_JSON_ERROR_UTF8, CONST_CS | CONST_PERSISTENT);
      83             : 
      84       19341 :         return SUCCESS;
      85             : }
      86             : /* }}} */
      87             : 
      88             : /* {{{ PHP_GINIT_FUNCTION
      89             : */
      90       19341 : static PHP_GINIT_FUNCTION(json)
      91             : {
      92       19341 :         json_globals->error_code = 0;
      93       19341 : }
      94             : /* }}} */
      95             : 
      96             : 
      97             : /* {{{ json_module_entry
      98             :  */
      99             : zend_module_entry json_module_entry = {
     100             :         STANDARD_MODULE_HEADER,
     101             :         "json",
     102             :         json_functions,
     103             :         PHP_MINIT(json),
     104             :         NULL,
     105             :         NULL,
     106             :         NULL,
     107             :         PHP_MINFO(json),
     108             :         PHP_JSON_VERSION,
     109             :         PHP_MODULE_GLOBALS(json),
     110             :         PHP_GINIT(json),
     111             :         NULL,
     112             :         NULL,
     113             :         STANDARD_MODULE_PROPERTIES_EX
     114             : };
     115             : /* }}} */
     116             : 
     117             : #ifdef COMPILE_DL_JSON
     118             : ZEND_GET_MODULE(json)
     119             : #endif
     120             : 
     121             : /* {{{ PHP_MINFO_FUNCTION
     122             :  */
     123         148 : static PHP_MINFO_FUNCTION(json)
     124             : {
     125         148 :         php_info_print_table_start();
     126         148 :         php_info_print_table_row(2, "json support", "enabled");
     127         148 :         php_info_print_table_row(2, "json version", PHP_JSON_VERSION);
     128         148 :         php_info_print_table_end();
     129         148 : }
     130             : /* }}} */
     131             : 
     132             : static void json_escape_string(smart_str *buf, char *s, int len, int options TSRMLS_DC);
     133             : 
     134         103 : static int json_determine_array_type(zval **val TSRMLS_DC) /* {{{ */
     135             : {
     136             :         int i;
     137         103 :         HashTable *myht = HASH_OF(*val);
     138             : 
     139         103 :         i = myht ? zend_hash_num_elements(myht) : 0;
     140         103 :         if (i > 0) {
     141             :                 char *key;
     142             :                 ulong index, idx;
     143             :                 uint key_len;
     144             :                 HashPosition pos;
     145             : 
     146          88 :                 zend_hash_internal_pointer_reset_ex(myht, &pos);
     147          88 :                 idx = 0;
     148         214 :                 for (;; zend_hash_move_forward_ex(myht, &pos)) {
     149         302 :                         i = zend_hash_get_current_key_ex(myht, &key, &key_len, &index, 0, &pos);
     150         302 :                         if (i == HASH_KEY_NON_EXISTANT) {
     151          74 :                                 break;
     152             :                         }
     153             : 
     154         228 :                         if (i == HASH_KEY_IS_STRING) {
     155          11 :                                 return 1;
     156             :                         } else {
     157         217 :                                 if (index != idx) {
     158           3 :                                         return 1;
     159             :                                 }
     160             :                         }
     161         214 :                         idx++;
     162         214 :                 }
     163             :         }
     164             : 
     165          89 :         return PHP_JSON_OUTPUT_ARRAY;
     166             : }
     167             : /* }}} */
     168             : 
     169         129 : static void json_encode_array(smart_str *buf, zval **val, int options TSRMLS_DC) /* {{{ */
     170             : {
     171             :         int i, r;
     172             :         HashTable *myht;
     173             : 
     174         129 :         if (Z_TYPE_PP(val) == IS_ARRAY) {
     175         107 :                 myht = HASH_OF(*val);
     176         107 :                 r = (options & PHP_JSON_FORCE_OBJECT) ? PHP_JSON_OUTPUT_OBJECT : json_determine_array_type(val TSRMLS_CC);
     177             :         } else {
     178          22 :                 myht = Z_OBJPROP_PP(val);
     179          22 :                 r = PHP_JSON_OUTPUT_OBJECT;
     180             :         }
     181             : 
     182         129 :         if (myht && myht->nApplyCount > 1) {
     183           2 :                 php_error_docref(NULL TSRMLS_CC, E_WARNING, "recursion detected");
     184           2 :                 smart_str_appendl(buf, "null", 4);
     185           2 :                 return;
     186             :         }
     187             : 
     188         127 :         if (r == PHP_JSON_OUTPUT_ARRAY) {
     189          88 :                 smart_str_appendc(buf, '[');
     190             :         } else {
     191          39 :                 smart_str_appendc(buf, '{');
     192             :         }
     193             : 
     194         127 :         i = myht ? zend_hash_num_elements(myht) : 0;
     195             : 
     196         127 :         if (i > 0)
     197             :         {
     198             :                 char *key;
     199             :                 zval **data;
     200             :                 ulong index;
     201             :                 uint key_len;
     202             :                 HashPosition pos;
     203             :                 HashTable *tmp_ht;
     204         107 :                 int need_comma = 0;
     205             : 
     206         107 :                 zend_hash_internal_pointer_reset_ex(myht, &pos);
     207         402 :                 for (;; zend_hash_move_forward_ex(myht, &pos)) {
     208         509 :                         i = zend_hash_get_current_key_ex(myht, &key, &key_len, &index, 0, &pos);
     209         509 :                         if (i == HASH_KEY_NON_EXISTANT)
     210         107 :                                 break;
     211             : 
     212         402 :                         if (zend_hash_get_current_data_ex(myht, (void **) &data, &pos) == SUCCESS) {
     213         402 :                                 tmp_ht = HASH_OF(*data);
     214         402 :                                 if (tmp_ht) {
     215          92 :                                         tmp_ht->nApplyCount++;
     216             :                                 }
     217             : 
     218         402 :                                 if (r == PHP_JSON_OUTPUT_ARRAY) {
     219         212 :                                         if (need_comma) {
     220         139 :                                                 smart_str_appendc(buf, ',');
     221             :                                         } else {
     222          73 :                                                 need_comma = 1;
     223             :                                         }
     224             :  
     225         212 :                                         php_json_encode(buf, *data, options TSRMLS_CC);
     226         190 :                                 } else if (r == PHP_JSON_OUTPUT_OBJECT) {
     227         190 :                                         if (i == HASH_KEY_IS_STRING) {
     228         176 :                                                 if (key[0] == '\0' && Z_TYPE_PP(val) == IS_OBJECT) {
     229             :                                                         /* Skip protected and private members. */
     230           1 :                                                         if (tmp_ht) {
     231           1 :                                                                 tmp_ht->nApplyCount--;
     232             :                                                         }
     233           1 :                                                         continue;
     234             :                                                 }
     235             : 
     236         175 :                                                 if (need_comma) {
     237         148 :                                                         smart_str_appendc(buf, ',');
     238             :                                                 } else {
     239          27 :                                                         need_comma = 1;
     240             :                                                 }
     241             : 
     242         175 :                                                 json_escape_string(buf, key, key_len - 1, options & ~PHP_JSON_NUMERIC_CHECK TSRMLS_CC);
     243         175 :                                                 smart_str_appendc(buf, ':');
     244             : 
     245         175 :                                                 php_json_encode(buf, *data, options TSRMLS_CC);
     246             :                                         } else {
     247          14 :                                                 if (need_comma) {
     248           8 :                                                         smart_str_appendc(buf, ',');
     249             :                                                 } else {
     250           6 :                                                         need_comma = 1;
     251             :                                                 }
     252             : 
     253          14 :                                                 smart_str_appendc(buf, '"');
     254          14 :                                                 smart_str_append_long(buf, (long) index);
     255          14 :                                                 smart_str_appendc(buf, '"');
     256          14 :                                                 smart_str_appendc(buf, ':');
     257             : 
     258          14 :                                                 php_json_encode(buf, *data, options TSRMLS_CC);
     259             :                                         }
     260             :                                 }
     261             : 
     262         401 :                                 if (tmp_ht) {
     263          91 :                                         tmp_ht->nApplyCount--;
     264             :                                 }
     265             :                         }
     266         402 :                 }
     267             :         }
     268             : 
     269         127 :         if (r == PHP_JSON_OUTPUT_ARRAY) {
     270          88 :                 smart_str_appendc(buf, ']');
     271             :         } else {
     272          39 :                 smart_str_appendc(buf, '}');
     273             :         }
     274             : }
     275             : /* }}} */
     276             : 
     277             : #define REVERSE16(us) (((us & 0xf) << 12) | (((us >> 4) & 0xf) << 8) | (((us >> 8) & 0xf) << 4) | ((us >> 12) & 0xf))
     278             : 
     279         351 : static void json_escape_string(smart_str *buf, char *s, int len, int options TSRMLS_DC) /* {{{ */
     280             : {
     281         351 :         int pos = 0;
     282             :         unsigned short us;
     283             :         unsigned short *utf16;
     284             : 
     285         351 :         if (len == 0) {
     286          11 :                 smart_str_appendl(buf, "\"\"", 2);
     287          11 :                 return;
     288             :         }
     289             : 
     290         340 :         if (options & PHP_JSON_NUMERIC_CHECK) {
     291             :                 double d;
     292             :                 int type;
     293             :                 long p;
     294             : 
     295           1 :                 if ((type = is_numeric_string(s, len, &p, &d, 0)) != 0) {
     296           1 :                         if (type == IS_LONG) {
     297           1 :                                 smart_str_append_long(buf, p);
     298           0 :                         } else if (type == IS_DOUBLE) {
     299           0 :                                 if (!zend_isinf(d) && !zend_isnan(d)) {
     300             :                                         char *tmp;
     301           0 :                                         int l = spprintf(&tmp, 0, "%.*k", (int) EG(precision), d);
     302           0 :                                         smart_str_appendl(buf, tmp, l);
     303           0 :                                         efree(tmp);
     304             :                                 } else {
     305           0 :                                         php_error_docref(NULL TSRMLS_CC, E_WARNING, "double %.9g does not conform to the JSON spec, encoded as 0", d);
     306           0 :                                         smart_str_appendc(buf, '0');
     307             :                                 }
     308             :                         }
     309           1 :                         return;
     310             :                 }
     311             :                 
     312             :         }
     313             : 
     314         339 :         utf16 = (unsigned short *) safe_emalloc(len, sizeof(unsigned short), 0);
     315             : 
     316         339 :         len = utf8_to_utf16(utf16, s, len);
     317         339 :         if (len <= 0) {
     318           8 :                 if (utf16) {
     319           8 :                         efree(utf16);
     320             :                 }
     321           8 :                 if (len < 0) {
     322           8 :                         JSON_G(error_code) = PHP_JSON_ERROR_UTF8;
     323           8 :                         if (!PG(display_errors)) {
     324           0 :                                 php_error_docref(NULL TSRMLS_CC, E_WARNING, "Invalid UTF-8 sequence in argument");
     325             :                         }
     326           8 :                         smart_str_appendl(buf, "null", 4);
     327             :                 } else {
     328           0 :                         smart_str_appendl(buf, "\"\"", 2);
     329             :                 }
     330           8 :                 return;
     331             :         }
     332             : 
     333         331 :         smart_str_appendc(buf, '"');
     334             : 
     335        3620 :         while (pos < len)
     336             :         {
     337        2958 :                 us = utf16[pos++];
     338             : 
     339        2958 :                 switch (us)
     340             :                 {
     341             :                         case '"':
     342          44 :                                 if (options & PHP_JSON_HEX_QUOT) {
     343           4 :                                         smart_str_appendl(buf, "\\u0022", 6);
     344             :                                 } else {
     345          40 :                                         smart_str_appendl(buf, "\\\"", 2);
     346             :                                 }
     347          44 :                                 break;
     348             : 
     349             :                         case '\\':
     350           8 :                                 smart_str_appendl(buf, "\\\\", 2);
     351           8 :                                 break;
     352             : 
     353             :                         case '/':
     354          48 :                                 smart_str_appendl(buf, "\\/", 2);
     355          48 :                                 break;
     356             : 
     357             :                         case '\b':
     358           8 :                                 smart_str_appendl(buf, "\\b", 2);
     359           8 :                                 break;
     360             : 
     361             :                         case '\f':
     362           8 :                                 smart_str_appendl(buf, "\\f", 2);
     363           8 :                                 break;
     364             : 
     365             :                         case '\n':
     366           9 :                                 smart_str_appendl(buf, "\\n", 2);
     367           9 :                                 break;
     368             : 
     369             :                         case '\r':
     370           8 :                                 smart_str_appendl(buf, "\\r", 2);
     371           8 :                                 break;
     372             : 
     373             :                         case '\t':
     374          10 :                                 smart_str_appendl(buf, "\\t", 2);
     375          10 :                                 break;
     376             : 
     377             :                         case '<':
     378          18 :                                 if (options & PHP_JSON_HEX_TAG) {
     379           2 :                                         smart_str_appendl(buf, "\\u003C", 6);
     380             :                                 } else {
     381          16 :                                         smart_str_appendc(buf, '<');
     382             :                                 }
     383          18 :                                 break;
     384             : 
     385             :                         case '>':
     386          18 :                                 if (options & PHP_JSON_HEX_TAG) {
     387           2 :                                         smart_str_appendl(buf, "\\u003E", 6);
     388             :                                 } else {
     389          16 :                                         smart_str_appendc(buf, '>');
     390             :                                 }
     391          18 :                                 break;
     392             : 
     393             :                         case '&':
     394          32 :                                 if (options & PHP_JSON_HEX_AMP) {
     395           4 :                                         smart_str_appendl(buf, "\\u0026", 6);
     396             :                                 } else {
     397          28 :                                         smart_str_appendc(buf, '&');
     398             :                                 }
     399          32 :                                 break;
     400             : 
     401             :                         case '\'':
     402          20 :                                 if (options & PHP_JSON_HEX_APOS) {
     403           4 :                                         smart_str_appendl(buf, "\\u0027", 6);
     404             :                                 } else {
     405          16 :                                         smart_str_appendc(buf, '\'');
     406             :                                 }
     407          20 :                                 break;
     408             : 
     409             :                         default:
     410        5312 :                                 if (us >= ' ' && (us & 127) == us) {
     411        2585 :                                         smart_str_appendc(buf, (unsigned char) us);
     412             :                                 } else {
     413         142 :                                         smart_str_appendl(buf, "\\u", 2);
     414         142 :                                         us = REVERSE16(us);
     415             : 
     416         142 :                                         smart_str_appendc(buf, digits[us & ((1 << 4) - 1)]);
     417         142 :                                         us >>= 4;
     418         142 :                                         smart_str_appendc(buf, digits[us & ((1 << 4) - 1)]);
     419         142 :                                         us >>= 4;
     420         142 :                                         smart_str_appendc(buf, digits[us & ((1 << 4) - 1)]);
     421         142 :                                         us >>= 4;
     422         142 :                                         smart_str_appendc(buf, digits[us & ((1 << 4) - 1)]);
     423             :                                 }
     424             :                                 break;
     425             :                 }
     426             :         }
     427             : 
     428         331 :         smart_str_appendc(buf, '"');
     429         331 :         efree(utf16);
     430             : }
     431             : /* }}} */
     432             : 
     433         493 : PHP_JSON_API void php_json_encode(smart_str *buf, zval *val, int options TSRMLS_DC) /* {{{ */
     434             : {
     435         493 :         switch (Z_TYPE_P(val))
     436             :         {
     437             :                 case IS_NULL:
     438          14 :                         smart_str_appendl(buf, "null", 4);
     439          14 :                         break;
     440             : 
     441             :                 case IS_BOOL:
     442          22 :                         if (Z_BVAL_P(val)) {
     443          12 :                                 smart_str_appendl(buf, "true", 4);
     444             :                         } else {
     445          10 :                                 smart_str_appendl(buf, "false", 5);
     446             :                         }
     447          22 :                         break;
     448             : 
     449             :                 case IS_LONG:
     450         114 :                         smart_str_append_long(buf, Z_LVAL_P(val));
     451         114 :                         break;
     452             : 
     453             :                 case IS_DOUBLE:
     454             :                         {
     455          37 :                                 char *d = NULL;
     456             :                                 int len;
     457          37 :                                 double dbl = Z_DVAL_P(val);
     458             : 
     459          70 :                                 if (!zend_isinf(dbl) && !zend_isnan(dbl)) {
     460          33 :                                         len = spprintf(&d, 0, "%.*k", (int) EG(precision), dbl);
     461          33 :                                         smart_str_appendl(buf, d, len);
     462          33 :                                         efree(d);
     463             :                                 } else {
     464           4 :                                         php_error_docref(NULL TSRMLS_CC, E_WARNING, "double %.9g does not conform to the JSON spec, encoded as 0", dbl);
     465           4 :                                         smart_str_appendc(buf, '0');
     466             :                                 }
     467             :                         }
     468          37 :                         break;
     469             : 
     470             :                 case IS_STRING:
     471         176 :                         json_escape_string(buf, Z_STRVAL_P(val), Z_STRLEN_P(val), options TSRMLS_CC);
     472         176 :                         break;
     473             : 
     474             :                 case IS_ARRAY:
     475             :                 case IS_OBJECT:
     476         129 :                         json_encode_array(buf, &val, options TSRMLS_CC);
     477         129 :                         break;
     478             : 
     479             :                 default:
     480           1 :                         php_error_docref(NULL TSRMLS_CC, E_WARNING, "type is unsupported, encoded as null");
     481           1 :                         smart_str_appendl(buf, "null", 4);
     482             :                         break;
     483             :         }
     484             : 
     485         493 :         return;
     486             : }
     487             : /* }}} */
     488             : 
     489         143 : PHP_JSON_API void php_json_decode(zval *return_value, char *str, int str_len, zend_bool assoc, long depth TSRMLS_DC) /* {{{ */
     490             : {
     491             :         int utf16_len;
     492             :         zval *z;
     493             :         unsigned short *utf16;
     494             :         JSON_parser jp;
     495             : 
     496         143 :         utf16 = (unsigned short *) safe_emalloc((str_len+1), sizeof(unsigned short), 1);
     497             : 
     498         143 :         utf16_len = utf8_to_utf16(utf16, str, str_len);
     499         143 :         if (utf16_len <= 0) {
     500           0 :                 if (utf16) {
     501           0 :                         efree(utf16);
     502             :                 }
     503           0 :                 JSON_G(error_code) = PHP_JSON_ERROR_UTF8;
     504           0 :                 RETURN_NULL();
     505             :         }
     506             : 
     507         143 :         if (depth <= 0) {
     508           0 :                 php_error_docref(NULL TSRMLS_CC, E_WARNING, "Depth must be greater than zero");
     509           0 :                 efree(utf16);
     510           0 :                 RETURN_NULL();
     511             :         }
     512             : 
     513         143 :         ALLOC_INIT_ZVAL(z);
     514         143 :         jp = new_JSON_parser(depth);
     515         143 :         if (parse_JSON(jp, z, utf16, utf16_len, assoc TSRMLS_CC)) {
     516          58 :                 *return_value = *z;
     517             :         }
     518             :         else
     519             :         {
     520             :                 double d;
     521             :                 int type;
     522             :                 long p;
     523             : 
     524          85 :                 RETVAL_NULL();
     525          85 :                 if (str_len == 4) {
     526          10 :                         if (!strcasecmp(str, "null")) {
     527             :                                 /* We need to explicitly clear the error because its an actual NULL and not an error */
     528           2 :                                 jp->error_code = PHP_JSON_ERROR_NONE;
     529           2 :                                 RETVAL_NULL();
     530           8 :                         } else if (!strcasecmp(str, "true")) {
     531           2 :                                 RETVAL_BOOL(1);
     532             :                         }
     533          75 :                 } else if (str_len == 5 && !strcasecmp(str, "false")) {
     534           2 :                         RETVAL_BOOL(0);
     535             :                 }
     536             : 
     537          85 :                 if ((type = is_numeric_string(str, str_len, &p, &d, 0)) != 0) {
     538          17 :                         if (type == IS_LONG) {
     539          14 :                                 RETVAL_LONG(p);
     540           3 :                         } else if (type == IS_DOUBLE) {
     541           3 :                                 RETVAL_DOUBLE(d);
     542             :                         }
     543             :                 }
     544             : 
     545          85 :                 if (Z_TYPE_P(return_value) != IS_NULL) {
     546          21 :                         jp->error_code = PHP_JSON_ERROR_NONE;
     547             :                 }
     548             : 
     549          85 :                 zval_dtor(z);
     550             :         }
     551         143 :         FREE_ZVAL(z);
     552         143 :         efree(utf16);
     553         143 :         JSON_G(error_code) = jp->error_code;
     554         143 :         free_JSON_parser(jp);
     555             : }
     556             : /* }}} */
     557             : 
     558             : /* {{{ proto string json_encode(mixed data [, int options])
     559             :    Returns the JSON representation of a value */
     560          94 : static PHP_FUNCTION(json_encode)
     561             : {
     562             :         zval *parameter;
     563          94 :         smart_str buf = {0};
     564          94 :         long options = 0;
     565             : 
     566          94 :         if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z|l", &parameter, &options) == FAILURE) {
     567           2 :                 return;
     568             :         }
     569             : 
     570          92 :         JSON_G(error_code) = PHP_JSON_ERROR_NONE;
     571             : 
     572          92 :         php_json_encode(&buf, parameter, options TSRMLS_CC);
     573             : 
     574          92 :         ZVAL_STRINGL(return_value, buf.c, buf.len, 1);
     575             : 
     576          92 :         smart_str_free(&buf);
     577             : }
     578             : /* }}} */
     579             : 
     580             : /* {{{ proto mixed json_decode(string json [, bool assoc [, long depth]])
     581             :    Decodes the JSON representation into a PHP value */
     582         152 : static PHP_FUNCTION(json_decode)
     583             : {
     584             :         char *str;
     585             :         int str_len;
     586         152 :         zend_bool assoc = 0; /* return JS objects as PHP objects by default */
     587         152 :         long depth = JSON_PARSER_DEFAULT_DEPTH;
     588             : 
     589         152 :         if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|bl", &str, &str_len, &assoc, &depth) == FAILURE) {
     590           3 :                 return;
     591             :         }
     592             : 
     593         149 :         JSON_G(error_code) = 0;
     594             : 
     595         149 :         if (!str_len) {
     596           6 :                 RETURN_NULL();
     597             :         }
     598             : 
     599         143 :         php_json_decode(return_value, str, str_len, assoc, depth TSRMLS_CC);
     600             : }
     601             : /* }}} */
     602             : 
     603             : /* {{{ proto int json_last_error()
     604             :    Returns the error code of the last json_decode(). */
     605          13 : static PHP_FUNCTION(json_last_error)
     606             : {
     607          13 :         if (zend_parse_parameters_none() == FAILURE) {
     608           0 :                 return;
     609             :         }
     610             : 
     611          13 :         RETURN_LONG(JSON_G(error_code));
     612             : }
     613             : /* }}} */
     614             : 
     615             : /*
     616             :  * Local variables:
     617             :  * tab-width: 4
     618             :  * c-basic-offset: 4
     619             :  * End:
     620             :  * vim600: noet sw=4 ts=4 fdm=marker
     621             :  * vim<600: noet sw=4 ts=4
     622             :  */

Generated by: LCOV version 1.10

Generated at Sun, 27 Jul 2014 12:58:30 +0000 (5 days ago)

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