2 +--------------------------------------------------------------------+
4 +--------------------------------------------------------------------+
5 | Redistribution and use in source and binary forms, with or without |
6 | modification, are permitted provided that the conditions mentioned |
7 | in the accompanying LICENSE file are met. |
8 +--------------------------------------------------------------------+
9 | Copyright (c) 2015, Michael Wallner <mike@php.net> |
10 +--------------------------------------------------------------------+
20 #include "ext/standard/info.h"
21 #include "ext/json/php_json.h"
22 #include "php_json_post.h"
25 ZEND_DECLARE_MODULE_GLOBALS(json_post
);
28 STD_PHP_INI_ENTRY("json_post.flags", "1", PHP_INI_PERDIR
, OnUpdateLong
, flags
, zend_json_post_globals
, json_post_globals
)
29 STD_PHP_INI_ENTRY("json_post.onerror.response", "0", PHP_INI_PERDIR
, OnUpdateLong
, onerror
.response
, zend_json_post_globals
, json_post_globals
)
30 STD_PHP_INI_ENTRY("json_post.onerror.exit", "0", PHP_INI_PERDIR
, OnUpdateBool
, onerror
.exit
, zend_json_post_globals
, json_post_globals
)
31 STD_PHP_INI_ENTRY("json_post.onerror.warning", "0", PHP_INI_PERDIR
, OnUpdateBool
, onerror
.warning
, zend_json_post_globals
, json_post_globals
)
34 static void php_json_post_init_globals(zend_json_post_globals
*json_post_globals
)
36 memset(json_post_globals
, 0, sizeof(*json_post_globals
));
37 #if PHP_VERSION_ID >= 50400
38 json_post_globals
->flags
= PHP_JSON_OBJECT_AS_ARRAY
;
40 json_post_globals
->flags
= 1;
50 PHP_MINFO_FUNCTION(json_post
)
52 php_info_print_table_start();
53 php_info_print_table_header(2, "json_post support", "enabled");
54 php_info_print_table_end();
56 DISPLAY_INI_ENTRIES();
59 #if PHP_VERSION_ID < 70000
60 # define JSON_POST_LAST_ERROR() json_post_last_error(TSRMLS_C)
61 static inline int json_post_last_error(TSRMLS_D
)
64 zval
*zv
, **zv_ptr
= &zv
;
67 JSON_POST_G(json_last_error
)->internal_function
.handler(0, zv
, zv_ptr
, NULL
, 1);
74 # define JSON_POST_LAST_ERROR() JSON_G(error_code)
77 static SAPI_POST_HANDLER_FUNC(php_json_post_handler
)
79 int module_number
= 0;
81 #if PHP_VERSION_ID >= 70000
82 zend_string
*json
= NULL
;
84 if (SG(request_info
).request_body
) {
85 /* FG(stream_wrappers) not initialized yet, so we cannot use php://input */
86 php_stream_rewind(SG(request_info
).request_body
);
87 json
= php_stream_copy_to_mem(SG(request_info
).request_body
, PHP_STREAM_COPY_ALL
, 0);
93 long flags
= JSON_POST_G(flags
);
95 #ifdef PHP_JSON_THROW_ON_ERROR
96 /* there's no execute data, so we must ensure json_decode() is not throwing */
97 flags
&= ~PHP_JSON_THROW_ON_ERROR
;
101 php_json_decode_ex(&tmp
, json
->val
, json
->len
, flags
, PG(max_input_nesting_level
));
103 switch (Z_TYPE(tmp
)) {
106 if (zend_hash_num_elements(HASH_OF(&tmp
))) {
108 ZVAL_COPY_VALUE(&PG(http_globals
)[TRACK_VARS_POST
], &tmp
);
110 /* PHP-7.4 optimizes empty array */
118 zend_string_release(json
);
124 char *json_str
= NULL
;
127 # if PHP_VERSION_ID >= 50600
128 if (!SG(request_info
).request_body
) {
132 /* FG(stream_wrappers) not initialized yet, so we cannot use php://input */
133 php_stream_rewind(SG(request_info
).request_body
);
134 json_len
= php_stream_copy_to_mem(SG(request_info
).request_body
, &json_str
, PHP_STREAM_COPY_ALL
, 0);
136 json_str
= SG(request_info
).raw_post_data
;
137 json_len
= SG(request_info
).raw_post_data_length
;
145 # if PHP_VERSION_ID >= 50400
146 php_json_decode_ex(&zjson
, json_str
, json_len
, JSON_POST_G(flags
), PG(max_input_nesting_level
) TSRMLS_CC
);
147 if (Z_TYPE(zjson
) != IS_NULL
) {
149 ZVAL_COPY_VALUE(zarg
, (&zjson
));
151 php_json_decode(&zjson
, json_str
, json_len
, (zend_bool
)(JSON_POST_G(flags
)&1), PG(max_input_nesting_level
) TSRMLS_CC
);
152 if (Z_TYPE(zjson
) != IS_NULL
) {
154 zarg
->value
= zjson
.value
;
155 Z_TYPE_P(zarg
) = Z_TYPE(zjson
);
159 # if PHP_VERSION_ID >= 50600
166 REGISTER_LONG_CONSTANT("JSON_POST_ERROR", JSON_POST_LAST_ERROR(), CONST_CS
);
168 if (JSON_POST_LAST_ERROR()) {
169 if (JSON_POST_G(onerror
.response
)) {
170 sapi_header_op(SAPI_HEADER_SET_STATUS
, (void *) (zend_long
) JSON_POST_G(onerror
.response
) TSRMLS_CC
);
172 if (JSON_POST_G(onerror
.warning
)) {
173 zend_error(E_WARNING
, "json_post: json_decode failed with error code: %d", JSON_POST_LAST_ERROR());
175 if (JSON_POST_G(onerror
.exit
)) {
176 sapi_send_headers(TSRMLS_C
);
179 #if PHP_VERSION_ID >= 70000 && PHP_VERSION_ID < 80000
180 /* ext/json in PHP-7 fails to reset error_code in RINIT */
181 JSON_G(error_code
) = 0;
186 PHP_MINIT_FUNCTION(json_post
)
188 sapi_post_entry json_post_entries
[] = {
189 { "text/json", sizeof("text/json")-1, sapi_read_standard_form_data
, php_json_post_handler
},
190 { "application/json", sizeof("application/json")-1, sapi_read_standard_form_data
, php_json_post_handler
},
191 { NULL
, 0, NULL
, NULL
}
194 sapi_register_post_entries(json_post_entries TSRMLS_CC
);
196 ZEND_INIT_MODULE_GLOBALS(json_post
, php_json_post_init_globals
, NULL
);
198 #if PHP_VERSION_ID < 70000
199 zend_hash_find(EG(function_table
), ZEND_STRS("json_last_error"), (void **) &JSON_POST_G(json_last_error
));
202 REGISTER_INI_ENTRIES();
206 PHP_MSHUTDOWN_FUNCTION(json_post
)
208 UNREGISTER_INI_ENTRIES();
213 zend_function_entry json_post_functions
[] = {
217 static zend_module_dep json_post_module_deps
[] = {
218 ZEND_MOD_REQUIRED("json")
219 {NULL
, NULL
, NULL
, 0}
222 zend_module_entry json_post_module_entry
= {
223 STANDARD_MODULE_HEADER_EX
,
225 json_post_module_deps
,
228 PHP_MINIT(json_post
),
229 PHP_MSHUTDOWN(json_post
),
232 PHP_MINFO(json_post
),
233 PHP_JSON_POST_VERSION
,
234 STANDARD_MODULE_PROPERTIES
238 #ifdef COMPILE_DL_JSON_POST
239 ZEND_GET_MODULE(json_post
)
247 * vim600: noet sw=4 ts=4 fdm=marker
248 * vim<600: noet sw=4 ts=4