X-Git-Url: https://git.m6w6.name/?p=m6w6%2Fext-json_post;a=blobdiff_plain;f=php_json_post.c;h=fd7f972f15fd3a58935b0f1beb91539c3d86e870;hp=4a0fcd30387a1d9346461aa53343e017a2e6e76b;hb=9238ac82f5a27d09836a3db70893f8c1cd8eadf7;hpb=e54f65df2bcb68b4493832c83c141da9f579964e diff --git a/php_json_post.c b/php_json_post.c index 4a0fcd3..fd7f972 100644 --- a/php_json_post.c +++ b/php_json_post.c @@ -26,6 +26,8 @@ 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.error_response", "0", PHP_INI_PERDIR, OnUpdateLong, error_response, zend_json_post_globals, json_post_globals) + STD_PHP_INI_ENTRY("json_post.error_exit", "0", PHP_INI_PERDIR, OnUpdateBool, error_exit, zend_json_post_globals, json_post_globals) PHP_INI_END() static void php_json_post_init_globals(zend_json_post_globals *json_post_globals) @@ -37,6 +39,21 @@ static void php_json_post_init_globals(zend_json_post_globals *json_post_globals #endif } +#if PHP_VERSION_ID < 70000 +ZEND_EXTERN_MODULE_GLOBALS(json); +static inline void zend_print_long_to_buf(char *p, long l) { + do { + *--p = (char) (l % 10) + '0'; + } while (l /= 10); +} +#endif + +#ifndef TSRMLS_CC +# define TSRMLS_C +# define TSRMLS_CC +#endif + + PHP_MINFO_FUNCTION(json_post) { php_info_print_table_start(); @@ -46,9 +63,9 @@ PHP_MINFO_FUNCTION(json_post) DISPLAY_INI_ENTRIES(); } -#if PHP_VERSION_ID >= 70000 static SAPI_POST_HANDLER_FUNC(php_json_post_handler) { +#if PHP_VERSION_ID >= 70000 zend_string *json = NULL; if (SG(request_info).request_body) { @@ -60,16 +77,26 @@ 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: case IS_ARRAY: - zval_dtor(arg); - ZVAL_COPY_VALUE(&PG(http_globals)[TRACK_VARS_POST], &tmp); + if (zend_hash_num_elements(HASH_OF(&tmp))) { + zval_dtor(arg); + ZVAL_COPY_VALUE(&PG(http_globals)[TRACK_VARS_POST], &tmp); + } else { + /* PHP-7.4 optimizes empty array */ + zval_ptr_dtor(&tmp); + } break; default: break; @@ -77,12 +104,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; @@ -124,10 +148,24 @@ static SAPI_POST_HANDLER_FUNC(php_json_post_handler) efree(json_str); } # endif -} - #endif + if (JSON_G(error_code)) { + if (JSON_POST_G(error_response)) { + char header[] = "X-JSON-Error-Code: "; + zend_print_long_to_buf(header + sizeof(header) - 1, (JSON_G(error_code) & 0xff)); + sapi_header_op(SAPI_HEADER_SET_STATUS, (void *) (long) JSON_POST_G(error_response) TSRMLS_CC); + sapi_add_header(header, sizeof(header)-1, 1); + } + if (JSON_POST_G(error_exit)) { + sapi_send_headers(TSRMLS_C); + zend_bailout(); + } + /* ext/json in PHP-7 fails to reset error_code in RINIT */ + JSON_G(error_code) = 0; + } +} + PHP_MINIT_FUNCTION(json_post) { sapi_post_entry json_post_entries[] = {