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
2 changes: 1 addition & 1 deletion .github/scripts/download-bundled/uriparser.sh
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ cd "$(dirname "$0")/../../.."
tmp_dir=/tmp/php-src-download-bundled/uriparser
rm -rf "$tmp_dir"

revision=refs/tags/uriparser-1.0.1
revision=refs/tags/uriparser-1.0.2

git clone --depth 1 --revision="$revision" https://github.com/uriparser/uriparser.git "$tmp_dir"

Expand Down
2 changes: 2 additions & 0 deletions NEWS
Original file line number Diff line number Diff line change
Expand Up @@ -181,6 +181,8 @@ PHP NEWS
with re-entrant getHash()). (Pratik Bhujel)
. Fix bugs GH-8561, GH-8562, GH-8563, and GH-8564 (Fixing various
SplFileObject iterator desync bugs). (iliaal)
. Fix bug GH-22062 (SplDoublyLinkedList iterator UAF
via destructor releasing next node). (David Carlier)

- Sqlite3:
. Fix NUL byte truncation in sqlite3 TEXT column handling. (ndossche)
Expand Down
1 change: 1 addition & 0 deletions Zend/zend.c
Original file line number Diff line number Diff line change
Expand Up @@ -811,6 +811,7 @@ static void executor_globals_ctor(zend_executor_globals *executor_globals) /* {{
executor_globals->user_error_handler_error_reporting = 0;
ZVAL_UNDEF(&executor_globals->user_error_handler);
ZVAL_UNDEF(&executor_globals->user_exception_handler);
ZVAL_UNDEF(&executor_globals->last_fatal_error_backtrace);
executor_globals->current_execute_data = NULL;
executor_globals->current_module = NULL;
executor_globals->exit_status = 0;
Expand Down
5 changes: 5 additions & 0 deletions Zend/zend_vm.h
Original file line number Diff line number Diff line change
Expand Up @@ -31,13 +31,18 @@ ZEND_API void ZEND_FASTCALL zend_serialize_opcode_handler(zend_op *op);
ZEND_API void ZEND_FASTCALL zend_deserialize_opcode_handler(zend_op *op);
ZEND_API const void* ZEND_FASTCALL zend_get_opcode_handler_func(const zend_op *op);
ZEND_API const zend_op *zend_get_halt_op(void);
ZEND_API const zend_op *zend_get_interrupt_op(void);
ZEND_API int ZEND_FASTCALL zend_vm_call_opcode_handler(zend_execute_data *ex);
ZEND_API int zend_vm_kind(void);
ZEND_API bool zend_gcc_global_regs(void);

void zend_vm_init(void);
void zend_vm_dtor(void);

#if ZEND_VM_KIND == ZEND_VM_KIND_TAILCALL
const struct _zend_op *zend_vm_handle_interrupt(struct _zend_execute_data *execute_data, const struct _zend_op *opline);
#endif

END_EXTERN_C()

#define ZEND_VM_SET_OPCODE_HANDLER(opline) zend_vm_set_opcode_handler(opline)
Expand Down
5 changes: 5 additions & 0 deletions Zend/zend_vm_def.h
Original file line number Diff line number Diff line change
Expand Up @@ -10624,7 +10624,12 @@ ZEND_VM_DEFINE_OP(137, ZEND_OP_DATA);
ZEND_VM_HELPER(zend_interrupt_helper, ANY, ANY)
{
zend_atomic_bool_store_ex(&EG(vm_interrupt), false);
#if ZEND_VM_KIND == ZEND_VM_KIND_TAILCALL
/* opline is &call_interrupt_op. Load orig opline. */
LOAD_OPLINE();
#else
SAVE_OPLINE();
#endif
if (zend_atomic_bool_load_ex(&EG(timed_out))) {
zend_timeout();
} else if (zend_interrupt_function) {
Expand Down
50 changes: 48 additions & 2 deletions Zend/zend_vm_execute.h

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

16 changes: 16 additions & 0 deletions Zend/zend_vm_execute.skl
Original file line number Diff line number Diff line change
Expand Up @@ -161,6 +161,22 @@ ZEND_API const zend_op *zend_get_halt_op(void)
#endif
}

ZEND_API const zend_op *zend_get_interrupt_op(void)
{
#if ZEND_VM_KIND == ZEND_VM_KIND_TAILCALL
return &call_interrupt_op;
#else
return NULL;
#endif
}

#if ZEND_VM_KIND == ZEND_VM_KIND_TAILCALL
ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV zend_vm_handle_interrupt(ZEND_OPCODE_HANDLER_ARGS)
{
return zend_interrupt_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
}
#endif

ZEND_API int zend_vm_kind(void)
{
return ZEND_VM_KIND;
Expand Down
31 changes: 28 additions & 3 deletions Zend/zend_vm_gen.php
Original file line number Diff line number Diff line change
Expand Up @@ -1591,6 +1591,19 @@ function gen_halt_handler($f, $kind) {
out($f,"}\n\n");
}

function gen_interrupt_func($f, $kind, $spec) {
$cconv = $kind === ZEND_VM_KIND_TAILCALL ? 'ZEND_OPCODE_HANDLER_CCONV' : 'ZEND_OPCODE_HANDLER_FUNC_CCONV';
$variant = $kind === ZEND_VM_KIND_TAILCALL ? '_TAILCALL' : '';
out($f, "static ZEND_COLD zend_never_inline ZEND_OPCODE_HANDLER_RET {$cconv} zend_interrupt{$variant}(ZEND_OPCODE_HANDLER_ARGS) {\n");
out($f,"\tSAVE_OPLINE();\n");
if ($kind === ZEND_VM_KIND_TAILCALL) {
out($f,"\tZEND_VM_TAIL_CALL(zend_interrupt_helper".($spec?"_SPEC":"")."_TAILCALL(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU));\n");
} else {
out($f, "\treturn &call_interrupt_op;\n");
}
out($f, "}\n");
}

function extra_spec_name($extra_spec) {
global $prefix;

Expand Down Expand Up @@ -1801,10 +1814,14 @@ function gen_executor_code($f, $spec, $kind, $prolog, &$switch_labels = array())
switch ($kind) {
case ZEND_VM_KIND_CALL:
gen_null_handler($f, $kind);
out($f, "#if ZEND_VM_KIND == ZEND_VM_KIND_TAILCALL\n");
gen_interrupt_func($f, $kind, $spec);
out($f, "#endif\n");
break;
case ZEND_VM_KIND_TAILCALL:
gen_null_handler($f, $kind);
gen_halt_handler($f, $kind);
gen_interrupt_func($f, $kind, $spec);
break;
case ZEND_VM_KIND_SWITCH:
out($f,"default: ZEND_NULL_LABEL:\n");
Expand Down Expand Up @@ -1840,7 +1857,7 @@ function gen_executor_code($f, $spec, $kind, $prolog, &$switch_labels = array())
out($f, "#pragma push_macro(\"ZEND_VM_INTERRUPT\")\n");
out($f, "#undef ZEND_VM_INTERRUPT\n");
out($f, "#define ZEND_VM_CONTINUE(handler) return opline\n");
out($f, "#define ZEND_VM_INTERRUPT() return zend_interrupt_helper".($spec?"_SPEC":"")."(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)\n");
out($f, "#define ZEND_VM_INTERRUPT() return zend_interrupt(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)\n");
out($f, $delayed_helpers);
out($f, "#pragma pop_macro(\"ZEND_VM_INTERRUPT\")\n");
out($f, "#pragma pop_macro(\"ZEND_VM_CONTINUE\")\n");
Expand Down Expand Up @@ -1895,7 +1912,10 @@ function gen_executor($f, $skl, $spec, $kind, $executor_name, $initializer_name)
if ($kind == ZEND_VM_KIND_HYBRID || $kind == ZEND_VM_KIND_CALL) {
out($f,"#if ZEND_VM_KIND == ZEND_VM_KIND_HYBRID || ZEND_VM_KIND == ZEND_VM_KIND_TAILCALL\n\n");
out($f,"static zend_vm_opcode_handler_func_t const * zend_opcode_handler_funcs;\n");
out($f,"#endif\n");
out($f,"#endif\n\n");
out($f,"#if ZEND_VM_KIND == ZEND_VM_KIND_TAILCALL\n");
out($f,"static const zend_op call_interrupt_op;\n");
out($f,"#endif\n\n");
}
out($f,"#if (ZEND_VM_KIND != ZEND_VM_KIND_HYBRID && ZEND_VM_KIND != ZEND_VM_KIND_TAILCALL) || !ZEND_VM_SPEC\n");
out($f,"static zend_vm_opcode_handler_t zend_vm_get_opcode_handler(uint8_t opcode, const zend_op* op);\n");
Expand Down Expand Up @@ -2136,11 +2156,13 @@ function gen_executor($f, $skl, $spec, $kind, $executor_name, $initializer_name)
out($f," ZEND_VM_TAIL_CALL(opline->handler(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); \\\n");
out($f," } while (0)\n");
out($f,"# define ZEND_VM_DISPATCH_TO_LEAVE_HELPER(helper) opline = &call_leave_op; SAVE_OPLINE(); ZEND_VM_CONTINUE()\n");
out($f,"# define ZEND_VM_INTERRUPT() ZEND_VM_TAIL_CALL(zend_interrupt_helper".($spec?"_SPEC":"")."_TAILCALL(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU))\n");
out($f,"# define ZEND_VM_INTERRUPT() ZEND_VM_TAIL_CALL(zend_interrupt_TAILCALL(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU))\n");
out($f,"# define ZEND_VM_ENTER_EX() ZEND_VM_INTERRUPT_CHECK(); ZEND_VM_CONTINUE()\n");
out($f,"# define ZEND_VM_LEAVE() ZEND_VM_CONTINUE()\n");
out($f,"\n");
out($f,"static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV zend_interrupt_helper".($spec?"_SPEC":"")."_TAILCALL(ZEND_OPCODE_HANDLER_ARGS);\n");
out($f,"static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV zend_interrupt(ZEND_OPCODE_HANDLER_ARGS);\n");
out($f,"static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV zend_interrupt_TAILCALL(ZEND_OPCODE_HANDLER_ARGS);\n");
out($f,"static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_NULL_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS);\n");
out($f,"static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_HALT_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS);\n");
out($f,"static zend_never_inline const zend_op *ZEND_OPCODE_HANDLER_CCONV zend_leave_helper_SPEC_TAILCALL(zend_execute_data *ex, const zend_op *opline);\n");
Expand All @@ -2151,6 +2173,9 @@ function gen_executor($f, $skl, $spec, $kind, $executor_name, $initializer_name)
out($f,"static const zend_op call_leave_op = {\n");
out($f," .handler = zend_leave_helper_SPEC_TAILCALL,\n");
out($f,"};\n");
out($f,"static const zend_op call_interrupt_op = {\n");
out($f," .handler = zend_interrupt_helper_SPEC_TAILCALL,\n");
out($f,"};\n");
out($f,"\n");

gen_executor_code($f, $spec, ZEND_VM_KIND_TAILCALL, $m[1]);
Expand Down
14 changes: 4 additions & 10 deletions ext/date/php_date.c
Original file line number Diff line number Diff line change
Expand Up @@ -29,13 +29,7 @@
#include "win32/time.h"
#endif

#ifdef PHP_WIN32
static __inline __int64 php_date_llabs( __int64 i ) { return i >= 0? i: -i; }
#elif defined(__GNUC__) && __GNUC__ < 3
static __inline __int64_t php_date_llabs( __int64_t i ) { return i >= 0 ? i : -i; }
#else
static inline long long php_date_llabs( long long i ) { return i >= 0 ? i : -i; }
#endif
static inline uint64_t php_date_llabs(int64_t i) { return i >= 0 ? (uint64_t)i : -(uint64_t)i; }

#ifdef PHP_WIN32
#define DATE_I64_BUF_LEN 65
Expand Down Expand Up @@ -740,9 +734,9 @@ static zend_string *date_format(const char *format, size_t format_len, const tim
/* year */
case 'L': length = slprintf(buffer, sizeof(buffer), "%d", timelib_is_leap((int) t->y)); break;
case 'y': length = slprintf(buffer, sizeof(buffer), "%02d", (int) (t->y % 100)); break;
case 'Y': length = slprintf(buffer, sizeof(buffer), "%s%04lld", t->y < 0 ? "-" : "", php_date_llabs((timelib_sll) t->y)); break;
case 'x': length = slprintf(buffer, sizeof(buffer), "%s%04lld", t->y < 0 ? "-" : (t->y >= 10000 ? "+" : ""), php_date_llabs((timelib_sll) t->y)); break;
case 'X': length = slprintf(buffer, sizeof(buffer), "%s%04lld", t->y < 0 ? "-" : "+", php_date_llabs((timelib_sll) t->y)); break;
case 'Y': length = slprintf(buffer, sizeof(buffer), "%s%04" PRIu64, t->y < 0 ? "-" : "", php_date_llabs((timelib_sll) t->y)); break;
case 'x': length = slprintf(buffer, sizeof(buffer), "%s%04" PRIu64, t->y < 0 ? "-" : (t->y >= 10000 ? "+" : ""), php_date_llabs((timelib_sll) t->y)); break;
case 'X': length = slprintf(buffer, sizeof(buffer), "%s%04" PRIu64, t->y < 0 ? "-" : "+", php_date_llabs((timelib_sll) t->y)); break;

/* time */
case 'a': length = slprintf(buffer, sizeof(buffer), "%s", t->h >= 12 ? "pm" : "am"); break;
Expand Down
21 changes: 21 additions & 0 deletions ext/date/tests/gh18422.phpt
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
--TEST--
GH-18422 (int overflow in Date extension)
--FILE--
<?php
date_default_timezone_set('UTC');

$dto = date_create("2006-12-12");
date_isodate_set($dto, PHP_INT_MIN, 1, 1);
echo $dto->format("Y"), "\n";
echo $dto->format("x"), "\n";
echo $dto->format("X"), "\n";

echo date_create("2024-06-15")->format("Y"), "\n";
echo date_create("-0042-01-01")->format("Y"), "\n";
?>
--EXPECTF--
-%d
-%d
-%d
2024
-0042
2 changes: 1 addition & 1 deletion ext/dba/libinifile/inifile.c
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,7 @@ void inifile_free(inifile *dba, int persistent)
key_type inifile_key_split(const char *group_name)
{
key_type key;
char *name;
const char *name;

if (group_name[0] == '[' && (name = strchr(group_name, ']')) != NULL) {
key.group = estrndup(group_name+1, name - (group_name + 1));
Expand Down
2 changes: 2 additions & 0 deletions ext/opcache/jit/zend_jit.c
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,7 @@ int zend_jit_profile_counter_rid = -1;
int16_t zend_jit_hot_counters[ZEND_HOT_COUNTERS_COUNT];

const zend_op *zend_jit_halt_op = NULL;
const zend_op *zend_jit_interrupt_op = NULL;
#ifdef HAVE_PTHREAD_JIT_WRITE_PROTECT_NP
static int zend_write_protect = 1;
#endif
Expand Down Expand Up @@ -3776,6 +3777,7 @@ int zend_jit_check_support(void)
void zend_jit_startup(void *buf, size_t size, bool reattached)
{
zend_jit_halt_op = zend_get_halt_op();
zend_jit_interrupt_op = zend_get_interrupt_op();
zend_jit_profile_counter_rid = zend_get_op_array_extension_handle(ACCELERATOR_PRODUCT_NAME);

#ifdef HAVE_PTHREAD_JIT_WRITE_PROTECT_NP
Expand Down
1 change: 1 addition & 0 deletions ext/opcache/jit/zend_jit_internal.h
Original file line number Diff line number Diff line change
Expand Up @@ -175,6 +175,7 @@ typedef struct _zend_jit_op_array_hot_extension {
zend_jit_hash((op_array)->opcodes)

extern const zend_op *zend_jit_halt_op;
extern const zend_op *zend_jit_interrupt_op;

#ifdef HAVE_GCC_GLOBAL_REGS
# define EXECUTE_DATA_D void
Expand Down
5 changes: 5 additions & 0 deletions ext/opcache/jit/zend_jit_vm_helpers.c
Original file line number Diff line number Diff line change
Expand Up @@ -1070,6 +1070,11 @@ zend_jit_trace_stop ZEND_FASTCALL zend_jit_trace_execute(zend_execute_data *ex,
if (UNEXPECTED(opline == zend_jit_halt_op)) {
#else
opline = handler(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
# if ZEND_VM_KIND == ZEND_VM_KIND_TAILCALL
while (UNEXPECTED(opline == zend_jit_interrupt_op)) {
opline = zend_vm_handle_interrupt(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
}
# endif
if (UNEXPECTED(((uintptr_t)opline & ~ZEND_VM_ENTER_BIT) == 0)) {
#endif
if (prev_opline->opcode == ZEND_YIELD || prev_opline->opcode == ZEND_YIELD_FROM) {
Expand Down
3 changes: 2 additions & 1 deletion ext/readline/readline_cli.c
Original file line number Diff line number Diff line change
Expand Up @@ -527,7 +527,8 @@ static char *cli_completion_generator(const char *text, int index) /* {{{ */
} else if (text[0] == '#' && text[1] != '[') {
retval = cli_completion_generator_ini(text, textlen, &cli_completion_state);
} else {
char *lc_text, *class_name_end;
char *lc_text;
const char *class_name_end;
zend_string *class_name = NULL;
zend_class_entry *ce = NULL;

Expand Down
Loading