From 98b35c8f1a7c1c1bc818ee163048a76c81dd7141 Mon Sep 17 00:00:00 2001 From: Michael Wallner Date: Thu, 16 Sep 2021 12:55:43 +0200 Subject: [PATCH] for #3 * Add json_post.error_response INI entry, specifying whether and which response code to send when `json_decode` fails. * Add json_post.error_exit INI entry, specifying whether to exit PHP without running the script when `json_decode` fails. --- .gitignore | 1 + package.xml | 12 +++++++---- php_json_post.c | 50 +++++++++++++++++++++++++++++++++++---------- php_json_post.h | 4 +++- tests/error001.phpt | 28 +++++++++++++++++++++++++ tests/error002.phpt | 30 +++++++++++++++++++++++++++ tests/error003.phpt | 25 +++++++++++++++++++++++ tests/error004.phpt | 22 ++++++++++++++++++++ 8 files changed, 156 insertions(+), 16 deletions(-) create mode 100644 tests/error001.phpt create mode 100644 tests/error002.phpt create mode 100644 tests/error003.phpt create mode 100644 tests/error004.phpt diff --git a/.gitignore b/.gitignore index 6c8f7d6..31a90b9 100644 --- a/.gitignore +++ b/.gitignore @@ -36,3 +36,4 @@ tests/*/*.sh php_json_post.o json_post-*.tgz tmp-php.ini +*.dep diff --git a/package.xml b/package.xml index fdeb3d4..db743b6 100644 --- a/package.xml +++ b/package.xml @@ -24,9 +24,9 @@ This extension does not provide any constants, functions or classes. mike@php.net yes - 2020-05-25 + 2021-09-16 - 1.0.2 + 1.1.0 1.0.0 @@ -35,8 +35,12 @@ This extension does not provide any constants, functions or classes. BSD-2-Clause +* Fix gh-issue #3: + * Add json_post.error_response INI entry, specifying whether and which + response code to send when `json_decode` fails. + * Add json_post.error_exit INI entry, specifying whether to exit PHP + without running the script when `json_decode` fails. +]> diff --git a/php_json_post.c b/php_json_post.c index c2e5ba6..f767b22 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,10 +77,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 +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; @@ -129,10 +148,22 @@ 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(); + } + } +} + PHP_MINIT_FUNCTION(json_post) { sapi_post_entry json_post_entries[] = { @@ -141,9 +172,6 @@ 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); diff --git a/php_json_post.h b/php_json_post.h index dd3aa0f..76cb8fe 100644 --- a/php_json_post.h +++ b/php_json_post.h @@ -16,7 +16,7 @@ extern zend_module_entry json_post_module_entry; #define phpext_json_post_ptr &json_post_module_entry -#define PHP_JSON_POST_VERSION "1.0.2" +#define PHP_JSON_POST_VERSION "1.1.0" #ifdef PHP_WIN32 # define PHP_JSON_POST_API __declspec(dllexport) @@ -32,6 +32,8 @@ extern zend_module_entry json_post_module_entry; ZEND_BEGIN_MODULE_GLOBALS(json_post) long flags; + int error_response; + zend_bool error_exit; ZEND_END_MODULE_GLOBALS(json_post) ZEND_EXTERN_MODULE_GLOBALS(json_post); diff --git a/tests/error001.phpt b/tests/error001.phpt new file mode 100644 index 0000000..1a43334 --- /dev/null +++ b/tests/error001.phpt @@ -0,0 +1,28 @@ +--TEST-- +json_post with malformed JSON (https://github.com/m6w6/ext-json_post/issues/3) +--SKIPIF-- + +--INI-- +json_post.error_response = 400 +--POST_RAW-- +Content-Type: application/json + +{ + "greeting": "Hello World +} +--FILE-- + +Done +--EXPECTHEADERS-- +Status: 400 Bad Request +X-JSON-Error-Code: 3 +--EXPECTF-- +array(0) { +} +int(0) +Done diff --git a/tests/error002.phpt b/tests/error002.phpt new file mode 100644 index 0000000..3903d23 --- /dev/null +++ b/tests/error002.phpt @@ -0,0 +1,30 @@ +--TEST-- +json_post with malformed JSON (https://github.com/m6w6/ext-json_post/issues/3) +--SKIPIF-- + +--INI-- +json_post.error_response = 400 +json_post.flags = 4194305 +--POST_RAW-- +Content-Type: application/json + +{ + "greeting": "Hello World +} +--FILE-- + +Done +--EXPECTHEADERS-- +Status: 400 Bad Request +X-JSON-Error-Code: 3 +--EXPECTF-- +array(0) { +} +int(400) +Done diff --git a/tests/error003.phpt b/tests/error003.phpt new file mode 100644 index 0000000..9147a12 --- /dev/null +++ b/tests/error003.phpt @@ -0,0 +1,25 @@ +--TEST-- +json_post with malformed JSON (https://github.com/m6w6/ext-json_post/issues/3) +--SKIPIF-- + +--INI-- +json_post.error_response = 444 +json_post.error_exit = true +--POST_RAW-- +Content-Type: application/json + +{ + "greeting": "Hello World +} +--FILE-- + +Done +--EXPECTHEADERS-- +Status: 444 +X-JSON-Error-Code: 3 +--EXPECT-- diff --git a/tests/error004.phpt b/tests/error004.phpt new file mode 100644 index 0000000..42cfa34 --- /dev/null +++ b/tests/error004.phpt @@ -0,0 +1,22 @@ +--TEST-- +json_post with malformed JSON (https://github.com/m6w6/ext-json_post/issues/3) +--SKIPIF-- + +--INI-- +json_post.error_exit = true +--POST_RAW-- +Content-Type: application/json + +{ + "greeting": "Hello World +} +--FILE-- + +Done +--EXPECTHEADERS-- +--EXPECT-- -- 2.30.2