X-Git-Url: https://git.m6w6.name/?p=m6w6%2Fext-json_post;a=blobdiff_plain;f=php_json_post.c;h=6922b5107045e7750e928f252157ff7cbb59e72f;hp=c2e5ba69eabb4618b45c5c541a451472d351c959;hb=bda8b43e0418324d9caf532c146bca5a5be89fc1;hpb=88d61717dea2609ba0f358c87c0d540cfc3ec10a diff --git a/php_json_post.c b/php_json_post.c index c2e5ba6..6922b51 100644 --- a/php_json_post.c +++ b/php_json_post.c @@ -25,11 +25,15 @@ ZEND_DECLARE_MODULE_GLOBALS(json_post); PHP_INI_BEGIN() - STD_PHP_INI_ENTRY("json_post.flags", "1", PHP_INI_PERDIR, OnUpdateLong, flags, zend_json_post_globals, json_post_globals) + STD_PHP_INI_ENTRY("json_post.flags", "1", PHP_INI_PERDIR, OnUpdateLong, flags, zend_json_post_globals, json_post_globals) + STD_PHP_INI_ENTRY("json_post.onerror.response", "0", PHP_INI_PERDIR, OnUpdateLong, onerror.response, zend_json_post_globals, json_post_globals) + STD_PHP_INI_ENTRY("json_post.onerror.exit", "0", PHP_INI_PERDIR, OnUpdateBool, onerror.exit, zend_json_post_globals, json_post_globals) + STD_PHP_INI_ENTRY("json_post.onerror.warning", "0", PHP_INI_PERDIR, OnUpdateBool, onerror.warning, zend_json_post_globals, json_post_globals) PHP_INI_END() static void php_json_post_init_globals(zend_json_post_globals *json_post_globals) { + memset(json_post_globals, 0, sizeof(*json_post_globals)); #if PHP_VERSION_ID >= 50400 json_post_globals->flags = PHP_JSON_OBJECT_AS_ARRAY; #else @@ -37,6 +41,12 @@ static void php_json_post_init_globals(zend_json_post_globals *json_post_globals #endif } +#ifndef TSRMLS_CC +# define TSRMLS_D +# define TSRMLS_C +# define TSRMLS_CC +#endif + PHP_MINFO_FUNCTION(json_post) { php_info_print_table_start(); @@ -46,9 +56,29 @@ PHP_MINFO_FUNCTION(json_post) DISPLAY_INI_ENTRIES(); } -#if PHP_VERSION_ID >= 70000 +#if PHP_VERSION_ID < 70000 +# define JSON_POST_LAST_ERROR() json_post_last_error(TSRMLS_C) +static inline int json_post_last_error(TSRMLS_D) +{ + zend_long l; + zval *zv, **zv_ptr = &zv; + + ALLOC_ZVAL(zv); + JSON_POST_G(json_last_error)->internal_function.handler(0, zv, zv_ptr, NULL, 1); + l = Z_LVAL_P(zv); + FREE_ZVAL(zv); + + return l; +} +#else +# define JSON_POST_LAST_ERROR() JSON_G(error_code) +#endif + static SAPI_POST_HANDLER_FUNC(php_json_post_handler) { + int module_number = 0; + +#if PHP_VERSION_ID >= 70000 zend_string *json = NULL; if (SG(request_info).request_body) { @@ -60,10 +90,15 @@ static SAPI_POST_HANDLER_FUNC(php_json_post_handler) if (json) { if (json->len) { zval tmp; + long flags = JSON_POST_G(flags); - ZVAL_NULL(&tmp); +#ifdef PHP_JSON_THROW_ON_ERROR + /* there's no execute data, so we must ensure json_decode() is not throwing */ + flags &= ~PHP_JSON_THROW_ON_ERROR; +#endif - php_json_decode_ex(&tmp, json->val, json->len, JSON_POST_G(flags), PG(max_input_nesting_level)); + ZVAL_NULL(&tmp); + php_json_decode_ex(&tmp, json->val, json->len, flags, PG(max_input_nesting_level)); switch (Z_TYPE(tmp)) { case IS_OBJECT: @@ -82,12 +117,9 @@ static SAPI_POST_HANDLER_FUNC(php_json_post_handler) } zend_string_release(json); } -} #else -static SAPI_POST_HANDLER_FUNC(php_json_post_handler) -{ zval *zarg = arg; char *json_str = NULL; size_t json_len = 0; @@ -129,9 +161,27 @@ static SAPI_POST_HANDLER_FUNC(php_json_post_handler) efree(json_str); } # endif -} +#endif + REGISTER_LONG_CONSTANT("JSON_POST_ERROR", JSON_POST_LAST_ERROR(), CONST_CS); + + if (JSON_POST_LAST_ERROR()) { + if (JSON_POST_G(onerror.response)) { + sapi_header_op(SAPI_HEADER_SET_STATUS, (void *) (zend_long) JSON_POST_G(onerror.response) TSRMLS_CC); + } + if (JSON_POST_G(onerror.warning)) { + zend_error(E_WARNING, "json_post: json_decode failed with error code: %d", JSON_POST_LAST_ERROR()); + } + if (JSON_POST_G(onerror.exit)) { + sapi_send_headers(TSRMLS_C); + zend_bailout(); + } +#if PHP_VERSION_ID >= 70000 && PHP_VERSION_ID < 80000 + /* ext/json in PHP-7 fails to reset error_code in RINIT */ + JSON_G(error_code) = 0; #endif + } +} PHP_MINIT_FUNCTION(json_post) { @@ -141,12 +191,14 @@ PHP_MINIT_FUNCTION(json_post) { NULL, 0, NULL, NULL } }; -#ifndef TSRMLS_CC -# define TSRMLS_CC -#endif sapi_register_post_entries(json_post_entries TSRMLS_CC); ZEND_INIT_MODULE_GLOBALS(json_post, php_json_post_init_globals, NULL); + +#if PHP_VERSION_ID < 70000 + zend_hash_find(EG(function_table), ZEND_STRS("json_last_error"), (void **) &JSON_POST_G(json_last_error)); +#endif + REGISTER_INI_ENTRIES(); return SUCCESS; }