Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
70 changes: 26 additions & 44 deletions ext/session/mod_user.c
Original file line number Diff line number Diff line change
Expand Up @@ -22,9 +22,8 @@ const ps_module ps_mod_user = {
PS_MOD_UPDATE_TIMESTAMP(user)
};

static void ps_call_handler(zval *func, int argc, zval *argv, zval *retval)
static void ps_call_handler(zval *func, uint32_t argc, zval *argv, zval *retval)
{
int i;
if (PS(in_save_handler)) {
PS(in_save_handler) = false;
ZVAL_UNDEF(retval);
Expand All @@ -34,12 +33,10 @@ static void ps_call_handler(zval *func, int argc, zval *argv, zval *retval)
if (call_user_function(NULL, NULL, func, retval, argc, argv) == FAILURE) {
zval_ptr_dtor(retval);
ZVAL_UNDEF(retval);
} else if (Z_ISUNDEF_P(retval)) {
ZVAL_NULL(retval);
}
PS(in_save_handler) = false;
}
for (i = 0; i < argc; i++) {
for (uint32_t i = 0; i < argc; i++) {
zval_ptr_dtor(&argv[i]);
}
}
Expand All @@ -48,34 +45,27 @@ static void ps_call_handler(zval *func, int argc, zval *argv, zval *retval)

static zend_result verify_bool_return_type_userland_calls(const zval *value)
{
/* Exit or exception in userland call */
if (Z_TYPE_P(value) == IS_UNDEF) {
return FAILURE;
}
if (Z_TYPE_P(value) == IS_TRUE) {
return SUCCESS;
}
if (Z_TYPE_P(value) == IS_FALSE) {
return FAILURE;
}
if ((Z_TYPE_P(value) == IS_LONG) && (Z_LVAL_P(value) == -1)) {
/* TODO Why are exceptions checked? */
if (!EG(exception)) {
php_error_docref(NULL, E_DEPRECATED, "Session callback must have a return value of type bool, %s returned", zend_zval_value_name(value));
}
return FAILURE;
}
if ((Z_TYPE_P(value) == IS_LONG) && (Z_LVAL_P(value) == 0)) {
/* TODO Why are exceptions checked? */
if (!EG(exception)) {
php_error_docref(NULL, E_DEPRECATED, "Session callback must have a return value of type bool, %s returned", zend_zval_value_name(value));
}
return SUCCESS;
}
if (!EG(exception)) {
zend_type_error("Session callback must have a return value of type bool, %s returned", zend_zval_value_name(value)); \
switch (Z_TYPE_P(value)) {
case IS_TRUE:
return SUCCESS;
case IS_FALSE:
/* Exit or exception in userland call */
case IS_UNDEF:
return FAILURE;
case IS_LONG:
/* Deprecated cases */
if (Z_LVAL_P(value) == 0) {
php_error_docref(NULL, E_DEPRECATED, "Session callback must have a return value of type bool, %s returned", zend_zval_value_name(value));
return SUCCESS;
} else if (Z_LVAL_P(value) == -1) {
php_error_docref(NULL, E_DEPRECATED, "Session callback must have a return value of type bool, %s returned", zend_zval_value_name(value));
return FAILURE;
}
ZEND_FALLTHROUGH;
default:
zend_type_error("Session callback must have a return value of type bool, %s returned", zend_zval_value_name(value));
return FAILURE;
}
return FAILURE;
}

PS_OPEN_FUNC(user)
Expand All @@ -92,9 +82,7 @@ PS_OPEN_FUNC(user)
ps_call_handler(&PSF(open), 2, args, &retval);
} zend_catch {
PS(session_status) = php_session_none;
if (!Z_ISUNDEF(retval)) {
zval_ptr_dtor(&retval);
}
zval_ptr_dtor(&retval);
zend_bailout();
} zend_end_try();

Expand All @@ -107,7 +95,6 @@ PS_OPEN_FUNC(user)

PS_CLOSE_FUNC(user)
{
bool bailout = false;
zval retval;
zend_result ret = FAILURE;

Expand All @@ -121,18 +108,13 @@ PS_CLOSE_FUNC(user)
zend_try {
ps_call_handler(&PSF(close), 0, NULL, &retval);
} zend_catch {
bailout = true;
PS(mod_user_implemented) = false;
zval_ptr_dtor(&retval);
zend_bailout();
} zend_end_try();

PS(mod_user_implemented) = false;

if (bailout) {
if (!Z_ISUNDEF(retval)) {
zval_ptr_dtor(&retval);
}
zend_bailout();
}

ret = verify_bool_return_type_userland_calls(&retval);
zval_ptr_dtor(&retval);
return ret;
Expand Down
20 changes: 18 additions & 2 deletions sapi/fuzzer/fuzzer-json.c
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
#include <stdlib.h>

#include "fuzzer-sapi.h"
#include "ext/json/php_json.h"
#include "ext/json/php_json_parser.h"

int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) {
Expand All @@ -36,10 +37,25 @@ int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) {
memcpy(data, Data, Size);
data[Size] = '\0';

for (int option = 0; option <=1; ++option) {
int options[12] = {
0,
PHP_JSON_OBJECT_AS_ARRAY,
PHP_JSON_OBJECT_AS_ARRAY | PHP_JSON_BIGINT_AS_STRING,
PHP_JSON_OBJECT_AS_ARRAY | PHP_JSON_BIGINT_AS_STRING | PHP_JSON_INVALID_UTF8_IGNORE,
PHP_JSON_OBJECT_AS_ARRAY | PHP_JSON_BIGINT_AS_STRING | PHP_JSON_INVALID_UTF8_SUBSTITUTE,
PHP_JSON_OBJECT_AS_ARRAY | PHP_JSON_INVALID_UTF8_IGNORE,
PHP_JSON_OBJECT_AS_ARRAY | PHP_JSON_INVALID_UTF8_SUBSTITUTE,
PHP_JSON_BIGINT_AS_STRING,
PHP_JSON_BIGINT_AS_STRING | PHP_JSON_INVALID_UTF8_IGNORE,
PHP_JSON_BIGINT_AS_STRING | PHP_JSON_INVALID_UTF8_SUBSTITUTE,
PHP_JSON_INVALID_UTF8_IGNORE,
PHP_JSON_INVALID_UTF8_SUBSTITUTE
};

for (int index = 0; index < 12; ++index) {
zval result;
php_json_parser parser;
php_json_parser_init(&parser, &result, data, Size, option, 10);
php_json_parser_init(&parser, &result, data, Size, options[index], 10);
if (php_json_yyparse(&parser) == SUCCESS) {
zval_ptr_dtor(&result);
}
Expand Down