[PHP-CVS] com php-src: Improve json_encode error handling: ext/json/JSON_parser.h ext/json/json.c ext/json/tests/003.phpt ext/json/tests/004.phpt ext/json/tests/inf_nan_error.phpt ext/json/tests/json_

2012-06-23 Thread Nikita Popov
Commit:84fe2cc890e49f40bac7c3ba74b3cfc6dc4cef2f
Author:Nikita Popov  Sat, 23 Jun 2012 20:46:27 +0200
Parents:   cc90ac54beb7359e5a3210261ce09159bbc43e92
Branches:  PHP-5.3 PHP-5.4 master

Link:   
http://git.php.net/?p=php-src.git;a=commitdiff;h=84fe2cc890e49f40bac7c3ba74b3cfc6dc4cef2f

Log:
Improve json_encode error handling

json_encode() now returns bool(false) for all possible errors, throws the
respective warning and also sets the respective json_last_error() error
code. Three new error codes have been added:

  * JSON_ERROR_RECURSION
  * JSON_ERROR_INF_OR_NAN
  * JSON_ERROR_UNSUPPORTED_TYPE

To get a partial JSON output instead of bool(false) the option
JSON_PARTIAL_OUTPUT_ON_ERROR can be specified. In this case the invalid
segments will be replaced either by null (for recursion, unsupported type
and invalid JSON) or 0 (for Inf and NaN).

The warning for invalid UTF-8 stays intact and is thrown also with
display_errors = On. If this behavior is undesired this can be remedied
later.

Changed paths:
  M  ext/json/JSON_parser.h
  M  ext/json/json.c
  M  ext/json/tests/003.phpt
  M  ext/json/tests/004.phpt
  A  ext/json/tests/inf_nan_error.phpt
  M  ext/json/tests/json_encode_basic.phpt
  M  ext/json/tests/pass001.1.phpt
  M  ext/json/tests/pass001.phpt
  A  ext/json/tests/unsupported_type_error.phpt

diff --git a/ext/json/JSON_parser.h b/ext/json/JSON_parser.h
index 746190b..5037344 100644
--- a/ext/json/JSON_parser.h
+++ b/ext/json/JSON_parser.h
@@ -24,7 +24,10 @@ enum error_codes {
 PHP_JSON_ERROR_STATE_MISMATCH,  
 PHP_JSON_ERROR_CTRL_CHAR,   
 PHP_JSON_ERROR_SYNTAX,
-PHP_JSON_ERROR_UTF8
+PHP_JSON_ERROR_UTF8,
+PHP_JSON_ERROR_RECURSION,
+PHP_JSON_ERROR_INF_OR_NAN,
+PHP_JSON_ERROR_UNSUPPORTED_TYPE
 };
 
 extern JSON_parser new_JSON_parser(int depth);
diff --git a/ext/json/json.c b/ext/json/json.c
index ce2cf43..a904765 100644
--- a/ext/json/json.c
+++ b/ext/json/json.c
@@ -81,6 +81,9 @@ static PHP_MINIT_FUNCTION(json)
REGISTER_LONG_CONSTANT("JSON_ERROR_CTRL_CHAR", 
PHP_JSON_ERROR_CTRL_CHAR, CONST_CS | CONST_PERSISTENT);
REGISTER_LONG_CONSTANT("JSON_ERROR_SYNTAX", PHP_JSON_ERROR_SYNTAX, 
CONST_CS | CONST_PERSISTENT);
REGISTER_LONG_CONSTANT("JSON_ERROR_UTF8", PHP_JSON_ERROR_UTF8, CONST_CS 
| CONST_PERSISTENT);
+   REGISTER_LONG_CONSTANT("JSON_ERROR_RECURSION", 
PHP_JSON_ERROR_RECURSION, CONST_CS | CONST_PERSISTENT);
+   REGISTER_LONG_CONSTANT("JSON_ERROR_INF_OR_NAN", 
PHP_JSON_ERROR_INF_OR_NAN, CONST_CS | CONST_PERSISTENT);
+   REGISTER_LONG_CONSTANT("JSON_ERROR_UNSUPPORTED_TYPE", 
PHP_JSON_ERROR_UNSUPPORTED_TYPE, CONST_CS | CONST_PERSISTENT);
 
return SUCCESS;
 }
@@ -181,6 +184,7 @@ static void json_encode_array(smart_str *buf, zval **val, 
int options TSRMLS_DC)
}
 
if (myht && myht->nApplyCount > 1) {
+   JSON_G(error_code) = PHP_JSON_ERROR_RECURSION;
php_error_docref(NULL TSRMLS_CC, E_WARNING, "recursion 
detected");
smart_str_appendl(buf, "null", 4);
return;
@@ -303,7 +307,8 @@ static void json_escape_string(smart_str *buf, char *s, int 
len, int options TSR
smart_str_appendl(buf, tmp, l);
efree(tmp);
} else {
-   php_error_docref(NULL TSRMLS_CC, 
E_WARNING, "double %.9g does not conform to the JSON spec, encoded as 0", d);
+   JSON_G(error_code) = 
PHP_JSON_ERROR_INF_OR_NAN;
+   php_error_docref(NULL TSRMLS_CC, 
E_WARNING, "double %.9g does not conform to the JSON spec", d);
smart_str_appendc(buf, '0');
}
}
@@ -460,7 +465,8 @@ PHP_JSON_API void php_json_encode(smart_str *buf, zval 
*val, int options TSRMLS_
smart_str_appendl(buf, d, len);
efree(d);
} else {
-   php_error_docref(NULL TSRMLS_CC, 
E_WARNING, "double %.9g does not conform to the JSON spec, encoded as 0", dbl);
+   JSON_G(error_code) = 
PHP_JSON_ERROR_INF_OR_NAN;
+   php_error_docref(NULL TSRMLS_CC, 
E_WARNING, "double %.9g does not conform to the JSON spec", dbl);
smart_str_appendc(buf, '0');
}
}
@@ -476,7 +482,8 @@ PHP_JSON_API void php_json_encode(smart_str *buf, zval 
*val, int options TSRMLS_
break;
 
default:
-   php_error_docref(NULL TSRMLS_CC, E_WARNING, "type is 
unsupported, encoded as null");
+   JSON_G(error_code) = PHP_JSON_ERROR_UNSUPPORTED_TYPE;
+

[PHP-CVS] com php-src: Merge branch 'PHP-5.3' into PHP-5.4: ext/json/JSON_parser.h ext/json/json.c ext/json/php_json.h ext/json/tests/bug43941.phpt ext/json/tests/bug53946.phpt ext/json/tests/bug54058

2012-06-23 Thread Nikita Popov
Commit:36fa17a5fae84ab332366a202f0a709279a2466a
Author:Nikita Popov  Sat, 23 Jun 2012 21:14:45 +0200
Parents:   e8862725770c3d5ee27c6c8c8a01b226b610fa08 
84fe2cc890e49f40bac7c3ba74b3cfc6dc4cef2f
Branches:  PHP-5.4 master

Link:   
http://git.php.net/?p=php-src.git;a=commitdiff;h=36fa17a5fae84ab332366a202f0a709279a2466a

Log:
Merge branch 'PHP-5.3' into PHP-5.4

* PHP-5.3:
  Improve json_encode error handling
  - BFN

Conflicts:
ext/json/json.c

Changed paths:
  MM  ext/json/JSON_parser.h
  MM  ext/json/json.c
  MM  ext/json/php_json.h
  MA  ext/json/tests/bug43941.phpt
  MA  ext/json/tests/bug53946.phpt
  MM  ext/json/tests/bug54058.phpt
  MA  ext/json/tests/bug61978.phpt

diff --cc ext/json/json.c
index 557fbc3,a904765..bc30251
--- a/ext/json/json.c
+++ b/ext/json/json.c
@@@ -93,9 -73,7 +93,10 @@@ static PHP_MINIT_FUNCTION(json
REGISTER_LONG_CONSTANT("JSON_HEX_QUOT", PHP_JSON_HEX_QUOT, CONST_CS | 
CONST_PERSISTENT);
REGISTER_LONG_CONSTANT("JSON_FORCE_OBJECT", PHP_JSON_FORCE_OBJECT, 
CONST_CS | CONST_PERSISTENT);
REGISTER_LONG_CONSTANT("JSON_NUMERIC_CHECK", PHP_JSON_NUMERIC_CHECK, 
CONST_CS | CONST_PERSISTENT);
 +  REGISTER_LONG_CONSTANT("JSON_UNESCAPED_SLASHES", 
PHP_JSON_UNESCAPED_SLASHES, CONST_CS | CONST_PERSISTENT);
 +  REGISTER_LONG_CONSTANT("JSON_PRETTY_PRINT", PHP_JSON_PRETTY_PRINT, 
CONST_CS | CONST_PERSISTENT);
 +  REGISTER_LONG_CONSTANT("JSON_UNESCAPED_UNICODE", 
PHP_JSON_UNESCAPED_UNICODE, CONST_CS | CONST_PERSISTENT);
+   REGISTER_LONG_CONSTANT("JSON_PARTIAL_OUTPUT_ON_ERROR", 
PHP_JSON_PARTIAL_OUTPUT_ON_ERROR, CONST_CS | CONST_PERSISTENT);
  
REGISTER_LONG_CONSTANT("JSON_ERROR_NONE", PHP_JSON_ERROR_NONE, CONST_CS 
| CONST_PERSISTENT);
REGISTER_LONG_CONSTANT("JSON_ERROR_DEPTH", PHP_JSON_ERROR_DEPTH, 
CONST_CS | CONST_PERSISTENT);
@@@ -103,10 -81,10 +104,13 @@@
REGISTER_LONG_CONSTANT("JSON_ERROR_CTRL_CHAR", 
PHP_JSON_ERROR_CTRL_CHAR, CONST_CS | CONST_PERSISTENT);
REGISTER_LONG_CONSTANT("JSON_ERROR_SYNTAX", PHP_JSON_ERROR_SYNTAX, 
CONST_CS | CONST_PERSISTENT);
REGISTER_LONG_CONSTANT("JSON_ERROR_UTF8", PHP_JSON_ERROR_UTF8, CONST_CS 
| CONST_PERSISTENT);
+   REGISTER_LONG_CONSTANT("JSON_ERROR_RECURSION", 
PHP_JSON_ERROR_RECURSION, CONST_CS | CONST_PERSISTENT);
+   REGISTER_LONG_CONSTANT("JSON_ERROR_INF_OR_NAN", 
PHP_JSON_ERROR_INF_OR_NAN, CONST_CS | CONST_PERSISTENT);
+   REGISTER_LONG_CONSTANT("JSON_ERROR_UNSUPPORTED_TYPE", 
PHP_JSON_ERROR_UNSUPPORTED_TYPE, CONST_CS | CONST_PERSISTENT);
  
 +  REGISTER_LONG_CONSTANT("JSON_OBJECT_AS_ARRAY",  
PHP_JSON_OBJECT_AS_ARRAY,   CONST_CS | CONST_PERSISTENT);
 +  REGISTER_LONG_CONSTANT("JSON_BIGINT_AS_STRING", 
PHP_JSON_BIGINT_AS_STRING,  CONST_CS | CONST_PERSISTENT);
 +
return SUCCESS;
  }
  /* }}} */
@@@ -387,11 -324,9 +393,9 @@@ static void json_escape_string(smart_st
if (utf16) {
efree(utf16);
}
 -  if (len < 0) {
 +  if (ulen < 0) {
JSON_G(error_code) = PHP_JSON_ERROR_UTF8;
-   if (!PG(display_errors)) {
-   php_error_docref(NULL TSRMLS_CC, E_WARNING, 
"Invalid UTF-8 sequence in argument");
-   }
+   php_error_docref(NULL TSRMLS_CC, E_WARNING, "Invalid 
UTF-8 sequence in argument");
smart_str_appendl(buf, "null", 4);
} else {
smart_str_appendl(buf, "\"\"", 2);
@@@ -502,56 -430,7 +506,57 @@@
}
  
smart_str_appendc(buf, '"');
 -  efree(utf16);
 +  if (utf16) {
 +  efree(utf16);
 +  }
 +}
 +/* }}} */
 +
 +
 +static void json_encode_serializable_object(smart_str *buf, zval *val, int 
options TSRMLS_DC) /* {{{ */
 +{
 +  zend_class_entry *ce = Z_OBJCE_P(val);
 +  zval *retval = NULL, fname;
 +  HashTable* myht;
 +  
 +  if (Z_TYPE_P(val) == IS_ARRAY) {
 +  myht = HASH_OF(val);
 +  } else {
 +  myht = Z_OBJPROP_P(val);
 +  }   
 +  
 +  if (myht && myht->nApplyCount > 1) {
++  JSON_G(error_code) = PHP_JSON_ERROR_RECURSION;
 +  php_error_docref(NULL TSRMLS_CC, E_WARNING, "recursion 
detected");
 +  smart_str_appendl(buf, "null", 4);
 +  return;
 +  }
 +
 +  ZVAL_STRING(&fname, "jsonSerialize", 0);
 +
 +  if (FAILURE == call_user_function_ex(EG(function_table), &val, &fname, 
&retval, 0, NULL, 1, NULL TSRMLS_CC) || !retval) {
 +  zend_throw_exception_ex(NULL, 0 TSRMLS_CC, "Failed calling 
%s::jsonSerialize()", ce->name);
 +  smart_str_appendl(buf, "null", sizeof("null") - 1);
 +  return;
 +}   
 +
 +  if (EG(exception)) {
 +  /* Error already raised */
 +  zval_ptr_dtor(&retval);
 +  smart_str_appe

[PHP-CVS] com php-src: - BFN: NEWS

2012-06-23 Thread Felipe Pena
Commit:cc90ac54beb7359e5a3210261ce09159bbc43e92
Author:Felipe Pena  Sat, 23 Jun 2012 15:21:20 
-0300
Parents:   c3f34796a053f5ff1016d872f8c339e32468783f
Branches:  PHP-5.3

Link:   
http://git.php.net/?p=php-src.git;a=commitdiff;h=cc90ac54beb7359e5a3210261ce09159bbc43e92

Log:
- BFN

Changed paths:
  M  NEWS


Diff:
diff --git a/NEWS b/NEWS
index 79b7325..b9bb009 100644
--- a/NEWS
+++ b/NEWS
@@ -50,6 +50,8 @@ PHP   
 NEWS
   . Fixed bug #62227 (Invalid phar stream path causes crash). (Felipe)
 
 - Reflection:
+  . Fixed bug #62384 (Attempting to invoke a Closure more than once causes 
+segfault). (Felipe)
   . Fixed bug #62202 (ReflectionParameter::getDefaultValue() memory leaks 
 with constant). (Laruence)


--
PHP CVS Mailing List (http://www.php.net/)
To unsubscribe, visit: http://www.php.net/unsub.php



[PHP-CVS] com php-src: - BFN: NEWS

2012-06-23 Thread Felipe Pena
Commit:e8862725770c3d5ee27c6c8c8a01b226b610fa08
Author:Felipe Pena  Sat, 23 Jun 2012 15:21:32 
-0300
Parents:   5e36306feb8ce2b43eb494d5c486fd341b0a1ea7
Branches:  PHP-5.4

Link:   
http://git.php.net/?p=php-src.git;a=commitdiff;h=e8862725770c3d5ee27c6c8c8a01b226b610fa08

Log:
- BFN

Changed paths:
  M  NEWS


Diff:
diff --git a/NEWS b/NEWS
index dfad253..e93d717 100644
--- a/NEWS
+++ b/NEWS
@@ -52,8 +52,10 @@ PHP  
  NEWS
 return a value). (Johannes)
 
 - Reflection:
-   . Fixed bug #62202 (ReflectionParameter::getDefaultValue() memory leaks 
- with constant). (Laruence)
+  . Fixed bug #62384 (Attempting to invoke a Closure more than once causes 
+segfault). (Felipe)
+  . Fixed bug #62202 (ReflectionParameter::getDefaultValue() memory leaks 
+with constant). (Laruence)
 
 - Sockets:
   . Fixed bug #62025 (__ss_family was changed on AIX 5.3). (Felipe)


--
PHP CVS Mailing List (http://www.php.net/)
To unsubscribe, visit: http://www.php.net/unsub.php



[PHP-CVS] com php-src: Merge branch 'PHP-5.3' into PHP-5.4: ext/reflection/php_reflection.c

2012-06-23 Thread Felipe Pena
Commit:5e36306feb8ce2b43eb494d5c486fd341b0a1ea7
Author:Felipe Pena  Sat, 23 Jun 2012 15:16:13 
-0300
Parents:   2418791731a2d4b983bccb73d8b8835044f66673 
c3f34796a053f5ff1016d872f8c339e32468783f
Branches:  PHP-5.4 master

Link:   
http://git.php.net/?p=php-src.git;a=commitdiff;h=5e36306feb8ce2b43eb494d5c486fd341b0a1ea7

Log:
Merge branch 'PHP-5.3' into PHP-5.4

* PHP-5.3:
  - Improved fix for #62384

Bugs:
https://bugs.php.net/62384

Changed paths:
  MM  ext/reflection/php_reflection.c


Diff:



--
PHP CVS Mailing List (http://www.php.net/)
To unsubscribe, visit: http://www.php.net/unsub.php



[PHP-CVS] com php-src: - Improved fix for #62384: ext/reflection/php_reflection.c

2012-06-23 Thread Felipe Pena
Commit:c3f34796a053f5ff1016d872f8c339e32468783f
Author:Felipe Pena  Sat, 23 Jun 2012 15:10:47 
-0300
Parents:   84b1c568f4d593c2f415b05f3b1b8bd0465eec27
Branches:  PHP-5.3 PHP-5.4 master

Link:   
http://git.php.net/?p=php-src.git;a=commitdiff;h=c3f34796a053f5ff1016d872f8c339e32468783f

Log:
- Improved fix for #62384

Bugs:
https://bugs.php.net/62384

Changed paths:
  M  ext/reflection/php_reflection.c


Diff:
diff --git a/ext/reflection/php_reflection.c b/ext/reflection/php_reflection.c
index 966c9a5..180ce8f 100644
--- a/ext/reflection/php_reflection.c
+++ b/ext/reflection/php_reflection.c
@@ -2749,12 +2749,10 @@ ZEND_METHOD(reflection_method, invokeArgs)
fcc.object_ptr = object;

/* 
-* Closure::__invoke() actually expects a copy of zend_function, so 
that it
-* frees it after the invoking.
+* Copy the zend_function when calling via handler (e.g. 
Closure::__invoke())
 */
-   if (obj_ce == zend_ce_closure && object &&
-   strlen(mptr->common.function_name) == 
sizeof(ZEND_INVOKE_FUNC_NAME)-1 &&
-   memcmp(mptr->common.function_name, ZEND_INVOKE_FUNC_NAME, 
sizeof(ZEND_INVOKE_FUNC_NAME)-1) == 0) {
+   if (mptr->type == ZEND_INTERNAL_FUNCTION &&
+   (mptr->internal_function.fn_flags & ZEND_ACC_CALL_VIA_HANDLER) 
!= 0) {
fcc.function_handler = _copy_function(mptr TSRMLS_CC);
}


--
PHP CVS Mailing List (http://www.php.net/)
To unsubscribe, visit: http://www.php.net/unsub.php