for #3
authorMichael Wallner <mike@php.net>
Thu, 16 Sep 2021 10:55:43 +0000 (12:55 +0200)
committerMichael Wallner <mike@php.net>
Thu, 16 Sep 2021 11:03:14 +0000 (13:03 +0200)
* 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
package.xml
php_json_post.c
php_json_post.h
tests/error001.phpt [new file with mode: 0644]
tests/error002.phpt [new file with mode: 0644]
tests/error003.phpt [new file with mode: 0644]
tests/error004.phpt [new file with mode: 0644]

index 6c8f7d69ceb8be6d3b38d04053011744eb12f206..31a90b925aa7db5f4870ac31bf5f49397cb96e3b 100644 (file)
@@ -36,3 +36,4 @@ tests/*/*.sh
 php_json_post.o
 json_post-*.tgz
 tmp-php.ini
+*.dep
index fdeb3d48c58bfc493d1fef03fd853fc700c4dd9e..db743b605764d9a75d21cec57e9c6cbe590cc2a2 100644 (file)
@@ -24,9 +24,9 @@ This extension does not provide any constants, functions or classes.
   <email>mike@php.net</email>
   <active>yes</active>
  </lead>
- <date>2020-05-25</date>
+ <date>2021-09-16</date>
  <version>
-  <release>1.0.2</release>
+  <release>1.1.0</release>
   <api>1.0.0</api>
  </version>
  <stability>
@@ -35,8 +35,12 @@ This extension does not provide any constants, functions or classes.
  </stability>
  <license uri="http://copyfree.org/content/standard/licenses/2bsd/license.txt">BSD-2-Clause</license>
  <notes><![CDATA[
- * Fix gh-issue #1: segfault on 7.4 with empty array (Mark Rigby-Jones)
-]]></notes>
+* 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.
+]></notes>
  <contents>
   <dir name="/">
    <file role="doc" name="AUTHORS"/>
index c2e5ba69eabb4618b45c5c541a451472d351c959..f767b22b7e738513a342350bdfbda2b47414e011 100644 (file)
@@ -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);
index dd3aa0f00101afa530afe8667fda90277dd50b0c..76cb8fe95506fe9489cb95592ab88bed398274ee 100644 (file)
@@ -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 (file)
index 0000000..1a43334
--- /dev/null
@@ -0,0 +1,28 @@
+--TEST--
+json_post with malformed JSON (https://github.com/m6w6/ext-json_post/issues/3)
+--SKIPIF--
+<?php
+extension_loaded("json_post") or die("skip need json_post support\n");
+?>
+--INI--
+json_post.error_response = 400
+--POST_RAW--
+Content-Type: application/json
+
+{
+       "greeting": "Hello World
+}
+--FILE--
+<?php
+var_dump($_POST);
+var_dump(json_last_error());
+?>
+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 (file)
index 0000000..3903d23
--- /dev/null
@@ -0,0 +1,30 @@
+--TEST--
+json_post with malformed JSON (https://github.com/m6w6/ext-json_post/issues/3)
+--SKIPIF--
+<?php
+extension_loaded("json_post") or die("skip need json_post support\n");
+if (PHP_VERSION_ID < 70000) doe("skip need PHP-7.0+\n");
+?>
+--INI--
+json_post.error_response = 400
+json_post.flags = 4194305
+--POST_RAW--
+Content-Type: application/json
+
+{
+       "greeting": "Hello World
+}
+--FILE--
+<?php
+var_dump($_POST);
+var_dump(http_response_code());
+?>
+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 (file)
index 0000000..9147a12
--- /dev/null
@@ -0,0 +1,25 @@
+--TEST--
+json_post with malformed JSON (https://github.com/m6w6/ext-json_post/issues/3)
+--SKIPIF--
+<?php
+extension_loaded("json_post") or die("skip need json_post support\n");
+?>
+--INI--
+json_post.error_response = 444
+json_post.error_exit = true
+--POST_RAW--
+Content-Type: application/json
+
+{
+       "greeting": "Hello World
+}
+--FILE--
+<?php
+var_dump($_POST);
+var_dump(http_response_code());
+?>
+Done
+--EXPECTHEADERS--
+Status: 444
+X-JSON-Error-Code: 3
+--EXPECT--
diff --git a/tests/error004.phpt b/tests/error004.phpt
new file mode 100644 (file)
index 0000000..42cfa34
--- /dev/null
@@ -0,0 +1,22 @@
+--TEST--
+json_post with malformed JSON (https://github.com/m6w6/ext-json_post/issues/3)
+--SKIPIF--
+<?php
+extension_loaded("json_post") or die("skip need json_post support\n");
+?>
+--INI--
+json_post.error_exit = true
+--POST_RAW--
+Content-Type: application/json
+
+{
+       "greeting": "Hello World
+}
+--FILE--
+<?php
+var_dump($_POST);
+var_dump(http_response_code());
+?>
+Done
+--EXPECTHEADERS--
+--EXPECT--