diff --git a/.github/actions/verify-generated-files/action.yml b/.github/actions/verify-generated-files/action.yml index 21aa125a1cbbc..4bd838f631728 100644 --- a/.github/actions/verify-generated-files/action.yml +++ b/.github/actions/verify-generated-files/action.yml @@ -9,4 +9,5 @@ runs: scripts/dev/genfiles Zend/zend_vm_gen.php build/gen_stub.php -f + build/gen_stub.php --generate-optimizer-info git add . -Nu && git diff --exit-code diff --git a/NEWS b/NEWS index 882586f251201..79368afc0aa75 100644 --- a/NEWS +++ b/NEWS @@ -1,6 +1,76 @@ PHP NEWS ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||| -?? ??? ????, PHP 8.1.7 +07 Jul 2022, PHP 8.1.8 + +- Core: + . Fixed bug GH-8338 (Intel CET is disabled unintentionally). (Chen, Hu) + . Fixed leak in Enum::from/tryFrom for internal enums when using JIT (ilutov) + . Fixed calling internal methods with a static return type from + extension code. (Sara) + . Fixed bug GH-8655 (Casting an object to array does not unwrap refcount=1 + references). (Nicolas Grekas) + . Fixed potential use after free in php_binary_init(). (Heiko Weber) + +- CLI: + . Fixed GH-8827 (Intentionally closing std handles no longer possible). (cmb) + +- COM: + . Fixed bug GH-8778 (Integer arithmethic with large number variants fails). + (cmb) + +- Curl: + . Fixed CURLOPT_TLSAUTH_TYPE is not treated as a string option. (Pierrick) + +- Date: + . Fixed bug #72963 (Null-byte injection in CreateFromFormat and related + functions). (Derick) + . Fixed bug #74671 (DST timezone abbreviation has incorrect offset). (Derick) + . Fixed bug #77243 (Weekdays are calculated incorrectly for negative years). + (Derick) + . Fixed bug #78139 (timezone_open accepts invalid timezone string argument). + (Derick) + +- Fileinfo: + . Fixed bug #81723 (Heap buffer overflow in finfo_buffer). (CVE-2022-31627) + (cmb) + +- FPM: + . Fixed bug #67764 (fpm: syslog.ident don't work). (Jakub Zelenka) + +- GD: + . Fixed imagecreatefromavif() memory leak. (cmb) + +- MBString: + . mb_detect_encoding recognizes all letters in Czech alphabet (alexdowad) + . mb_detect_encoding recognizes all letters in Hungarian alphabet (alexdowad) + . Fixed bug GH-8685 (pcre not ready at mbstring startup). (Remi) + . Backwards-compatible mappings for 0x5C/0x7E in Shift-JIS are restored, + after they had been changed in 8.1.0. (Alex Dowad) + +- ODBC: + . Fixed handling of single-key connection strings. (Calvin Buckley) + +- OPcache: + . Fixed bug GH-8591 (tracing JIT crash after private instance method change). + (Arnaud, Dmitry, Oleg Stepanischev) + +- OpenSSL: + . Fixed bug #50293 (Several openssl functions ignore the VCWD). + (Jakub Zelenka, cmb) + . Fixed bug #81713 (NULL byte injection in several OpenSSL functions working + with certificates). (Jakub Zelenka) + +- PDO_ODBC: + . Fixed handling of single-key connection strings. (Calvin Buckley) + +- SPL: + . Fixed bug GH-8563 (Different results for seek() on SplFileObject and SplTempFileObject). (Girgias) + +- Zip: + . Fixed bug GH-8781 (ZipArchive::close deletes zip file without updating stat + cache). (Remi) + +09 Jun 2022, PHP 8.1.7 - CLI: . Fixed bug GH-8575 (CLI closes standard streams too early). (Levi Morrison) @@ -22,6 +92,11 @@ PHP NEWS . Fixed ACL build check on MacOS. (David Carlier) . Fixed bug #72185: php-fpm writes empty fcgi record causing nginx 502. (Jakub Zelenka, loveharmful) + . Fixes use after free. (Heiko Weber). + +- mysqlnd: + . Fixed bug #81719: mysqlnd/pdo password buffer overflow. (CVE-2022-31626) + (c dot fol at ambionics dot io) - OPcache: . Fixed bug GH-8461 (tracing JIT crash after function/method change). @@ -34,6 +109,10 @@ PHP NEWS - Pcntl: . Fixed Haiku build. (David Carlier) +- pgsql + . Fixed bug #81720: Uninitialized array in pg_query_params(). + (CVE-2022-31625) (cmb) + - Soap: . Fixed bug GH-8578 (Error on wrong parameter on SoapHeader constructor). (robertnisipeanu) @@ -210,6 +289,10 @@ PHP NEWS . Fixed bug GH-7867 (FFI::cast() from pointer to array is broken). (cmb, dmitry) +- Filter: + . Fix #81708: UAF due to php_filter_float() failing for ints. + (CVE-2021-21708) (cmb) + - FPM: . Fixed memory leak on invalid port. (David Carlier) . Fixed bug GH-7842 (Invalid OpenMetrics response format returned by FPM diff --git a/Zend/Optimizer/block_pass.c b/Zend/Optimizer/block_pass.c index 00454d5d96fb3..79207edb3d8b9 100644 --- a/Zend/Optimizer/block_pass.c +++ b/Zend/Optimizer/block_pass.c @@ -300,7 +300,8 @@ static void zend_optimize_block(zend_basic_block *block, zend_op_array *op_array src->opcode != ZEND_FETCH_STATIC_PROP_R && src->opcode != ZEND_FETCH_DIM_R && src->opcode != ZEND_FETCH_OBJ_R && - src->opcode != ZEND_NEW) { + src->opcode != ZEND_NEW && + src->opcode != ZEND_FETCH_THIS) { src->result_type = IS_UNUSED; MAKE_NOP(opline); ++(*opt_count); diff --git a/Zend/Optimizer/zend_inference.c b/Zend/Optimizer/zend_inference.c index 9c205ac507589..867d2a5ddb578 100644 --- a/Zend/Optimizer/zend_inference.c +++ b/Zend/Optimizer/zend_inference.c @@ -3227,21 +3227,34 @@ static zend_always_inline int _zend_update_type_info( tmp |= t1 & (MAY_BE_RC1|MAY_BE_RCN); } if (opline->op2_type == IS_UNUSED) { - if (t1 & (MAY_BE_UNDEF|MAY_BE_NULL)) { + if (t1 & (MAY_BE_UNDEF|MAY_BE_NULL|MAY_BE_FALSE)) { key_type |= MAY_BE_ARRAY_PACKED; } if (t1 & MAY_BE_ARRAY) { - key_type |= MAY_BE_HASH_ONLY(t1) ? MAY_BE_ARRAY_NUMERIC_HASH : MAY_BE_ARRAY_KEY_LONG; + key_type |= MAY_BE_HASH_ONLY(t1) ? + MAY_BE_ARRAY_NUMERIC_HASH : MAY_BE_ARRAY_KEY_LONG; } } else { if (t2 & (MAY_BE_LONG|MAY_BE_FALSE|MAY_BE_TRUE|MAY_BE_RESOURCE|MAY_BE_DOUBLE)) { - key_type |= MAY_BE_HASH_ONLY(t1) ? MAY_BE_ARRAY_NUMERIC_HASH : MAY_BE_ARRAY_KEY_LONG; + if (t1 & (MAY_BE_UNDEF|MAY_BE_NULL|MAY_BE_FALSE)) { + key_type |= MAY_BE_ARRAY_PACKED; + } + if (t1 & MAY_BE_ARRAY) { + key_type |= MAY_BE_HASH_ONLY(t1) ? + MAY_BE_ARRAY_NUMERIC_HASH : MAY_BE_ARRAY_KEY_LONG; + } } if (t2 & MAY_BE_STRING) { key_type |= MAY_BE_ARRAY_KEY_STRING; if (opline->op2_type != IS_CONST) { // FIXME: numeric string - key_type |= MAY_BE_HASH_ONLY(t1) ? MAY_BE_ARRAY_NUMERIC_HASH : MAY_BE_ARRAY_KEY_LONG; + if (t1 & (MAY_BE_UNDEF|MAY_BE_NULL|MAY_BE_FALSE)) { + key_type |= MAY_BE_ARRAY_PACKED; + } + if (t1 & MAY_BE_ARRAY) { + key_type |= MAY_BE_HASH_ONLY(t1) ? + MAY_BE_ARRAY_NUMERIC_HASH : MAY_BE_ARRAY_KEY_LONG; + } } } if (t2 & (MAY_BE_UNDEF | MAY_BE_NULL)) { diff --git a/Zend/asm/jump_x86_64_sysv_elf_gas.S b/Zend/asm/jump_x86_64_sysv_elf_gas.S index 0c4a1a39eb8b0..c675c8c774c23 100644 --- a/Zend/asm/jump_x86_64_sysv_elf_gas.S +++ b/Zend/asm/jump_x86_64_sysv_elf_gas.S @@ -24,12 +24,18 @@ * * ****************************************************************************************/ +# if defined __CET__ +# include +# else +# define _CET_ENDBR +# endif .file "jump_x86_64_sysv_elf_gas.S" .text .globl jump_fcontext .type jump_fcontext,@function .align 16 jump_fcontext: + _CET_ENDBR leaq -0x38(%rsp), %rsp /* prepare stack */ #if !defined(BOOST_USE_TSX) diff --git a/Zend/asm/make_x86_64_sysv_elf_gas.S b/Zend/asm/make_x86_64_sysv_elf_gas.S index 0ef37569a0299..d422c6972df9c 100644 --- a/Zend/asm/make_x86_64_sysv_elf_gas.S +++ b/Zend/asm/make_x86_64_sysv_elf_gas.S @@ -24,12 +24,18 @@ * * ****************************************************************************************/ +# if defined __CET__ +# include +# else +# define _CET_ENDBR +# endif .file "make_x86_64_sysv_elf_gas.S" .text .globl make_fcontext .type make_fcontext,@function .align 16 make_fcontext: + _CET_ENDBR /* first arg of make_fcontext() == top of context-stack */ movq %rdi, %rax @@ -66,11 +72,13 @@ make_fcontext: trampoline: /* store return address on stack */ /* fix stack alignment */ + _CET_ENDBR push %rbp /* jump to context-function */ jmp *%rbx finish: + _CET_ENDBR /* exit code is zero */ xorq %rdi, %rdi /* exit application */ diff --git a/Zend/tests/bugGH-8655.phpt b/Zend/tests/bugGH-8655.phpt new file mode 100644 index 0000000000000..d484c65d0e5e6 --- /dev/null +++ b/Zend/tests/bugGH-8655.phpt @@ -0,0 +1,29 @@ +--TEST-- +Bug GH-8655 (zval reference is not released when targetting a declared property) +--FILE-- + &$value) { + $object->$name = &$value; + } +}; + +$object = new Foo; + +hydrate(['foo' => 123], $object); + +$arrayCast = (array) $object; + +$object->foo = 234; +var_dump(ReflectionReference::fromArrayElement($arrayCast, 'foo')); +echo $arrayCast['foo']; +?> +--EXPECT-- +NULL +123 diff --git a/Zend/tests/enum/internal_enums.phpt b/Zend/tests/enum/internal_enums.phpt index f02f72f95831c..868e3132a112e 100644 --- a/Zend/tests/enum/internal_enums.phpt +++ b/Zend/tests/enum/internal_enums.phpt @@ -21,6 +21,9 @@ var_dump(ZendTestStringEnum::Foo->value); var_dump($bar = ZendTestStringEnum::from("Test2")); var_dump($bar === ZendTestStringEnum::Bar); var_dump(ZendTestStringEnum::tryFrom("Test3")); +var_dump(ZendTestStringEnum::tryFrom(42)); +var_dump(ZendTestStringEnum::tryFrom(43)); +var_dump(ZendTestStringEnum::tryFrom(0)); var_dump(ZendTestStringEnum::cases()); var_dump($s = serialize($foo)); @@ -47,13 +50,18 @@ string(5) "Test1" enum(ZendTestStringEnum::Bar) bool(true) NULL -array(3) { +enum(ZendTestStringEnum::FortyTwo) +NULL +NULL +array(4) { [0]=> enum(ZendTestStringEnum::Foo) [1]=> enum(ZendTestStringEnum::Bar) [2]=> enum(ZendTestStringEnum::Baz) + [3]=> + enum(ZendTestStringEnum::FortyTwo) } string(30) "E:22:"ZendTestStringEnum:Foo";" enum(ZendTestStringEnum::Foo) diff --git a/Zend/tests/enum/internal_enums_strict_types.phpt b/Zend/tests/enum/internal_enums_strict_types.phpt new file mode 100644 index 0000000000000..3d5ea231a2711 --- /dev/null +++ b/Zend/tests/enum/internal_enums_strict_types.phpt @@ -0,0 +1,28 @@ +--TEST-- +Internal enums from/tryFrom in strict_types=1 +--EXTENSIONS-- +zend_test +--FILE-- +getMessage(), "\n"; +} + +try { + var_dump(ZendTestStringEnum::tryFrom(43)); +} catch (Error $e) { + echo $e->getMessage(), "\n"; +} + +?> +--EXPECT-- +enum(ZendTestStringEnum::Bar) +ZendTestStringEnum::from(): Argument #1 ($value) must be of type string, int given +ZendTestStringEnum::tryFrom(): Argument #1 ($value) must be of type string, int given diff --git a/Zend/zend.h b/Zend/zend.h index c88d53ee27a9b..b76a713b613e2 100644 --- a/Zend/zend.h +++ b/Zend/zend.h @@ -20,7 +20,7 @@ #ifndef ZEND_H #define ZEND_H -#define ZEND_VERSION "4.1.7-dev" +#define ZEND_VERSION "4.1.8" #define ZEND_ENGINE_3 diff --git a/Zend/zend_API.c b/Zend/zend_API.c index 1684fd50dc860..e8ff66fe97ed0 100644 --- a/Zend/zend_API.c +++ b/Zend/zend_API.c @@ -357,7 +357,7 @@ ZEND_API ZEND_COLD void ZEND_FASTCALL zend_unexpected_extra_named_error(void) class_name, space, get_active_function_name()); } -static ZEND_COLD void ZEND_FASTCALL zend_argument_error_variadic(zend_class_entry *error_ce, uint32_t arg_num, const char *format, va_list va) /* {{{ */ +ZEND_API ZEND_COLD void ZEND_FASTCALL zend_argument_error_variadic(zend_class_entry *error_ce, uint32_t arg_num, const char *format, va_list va) /* {{{ */ { zend_string *func_name; const char *arg_name; diff --git a/Zend/zend_API.h b/Zend/zend_API.h index a51d3f3ad1e94..3e33859ca64f9 100644 --- a/Zend/zend_API.h +++ b/Zend/zend_API.h @@ -1333,6 +1333,7 @@ ZEND_API ZEND_COLD void ZEND_FASTCALL zend_wrong_parameter_class_or_string_or_nu ZEND_API ZEND_COLD void ZEND_FASTCALL zend_wrong_callback_error(uint32_t num, char *error); ZEND_API ZEND_COLD void ZEND_FASTCALL zend_wrong_callback_or_null_error(uint32_t num, char *error); ZEND_API ZEND_COLD void ZEND_FASTCALL zend_unexpected_extra_named_error(void); +ZEND_API ZEND_COLD void ZEND_FASTCALL zend_argument_error_variadic(zend_class_entry *error_ce, uint32_t arg_num, const char *format, va_list va); ZEND_API ZEND_COLD void zend_argument_error(zend_class_entry *error_ce, uint32_t arg_num, const char *format, ...); ZEND_API ZEND_COLD void zend_argument_type_error(uint32_t arg_num, const char *format, ...); ZEND_API ZEND_COLD void zend_argument_value_error(uint32_t arg_num, const char *format, ...); diff --git a/Zend/zend_enum.c b/Zend/zend_enum.c index 4494782d565c1..3366fb7d3f570 100644 --- a/Zend/zend_enum.c +++ b/Zend/zend_enum.c @@ -210,6 +210,7 @@ static ZEND_NAMED_FUNCTION(zend_enum_cases_func) static void zend_enum_from_base(INTERNAL_FUNCTION_PARAMETERS, bool try) { zend_class_entry *ce = execute_data->func->common.scope; + bool release_string = false; zend_string *string_key; zend_long long_key; @@ -221,17 +222,33 @@ static void zend_enum_from_base(INTERNAL_FUNCTION_PARAMETERS, bool try) case_name_zv = zend_hash_index_find(ce->backed_enum_table, long_key); } else { - ZEND_PARSE_PARAMETERS_START(1, 1) - Z_PARAM_STR(string_key) - ZEND_PARSE_PARAMETERS_END(); - ZEND_ASSERT(ce->enum_backing_type == IS_STRING); + + if (ZEND_ARG_USES_STRICT_TYPES()) { + ZEND_PARSE_PARAMETERS_START(1, 1) + Z_PARAM_STR(string_key) + ZEND_PARSE_PARAMETERS_END(); + } else { + // We allow long keys so that coercion to string doesn't happen implicitly. The JIT + // skips deallocation of params that don't require it. In the case of from/tryFrom + // passing int to from(int|string) looks like no coercion will happen, so the JIT + // won't emit a dtor call. Thus we allocate/free the string manually. + ZEND_PARSE_PARAMETERS_START(1, 1) + Z_PARAM_STR_OR_LONG(string_key, long_key) + ZEND_PARSE_PARAMETERS_END(); + + if (string_key == NULL) { + release_string = true; + string_key = zend_long_to_str(long_key); + } + } + case_name_zv = zend_hash_find(ce->backed_enum_table, string_key); } if (case_name_zv == NULL) { if (try) { - RETURN_NULL(); + goto return_null; } if (ce->enum_backing_type == IS_LONG) { @@ -240,7 +257,7 @@ static void zend_enum_from_base(INTERNAL_FUNCTION_PARAMETERS, bool try) ZEND_ASSERT(ce->enum_backing_type == IS_STRING); zend_value_error("\"%s\" is not a valid backing value for enum \"%s\"", ZSTR_VAL(string_key), ZSTR_VAL(ce->name)); } - RETURN_THROWS(); + goto throw; } // TODO: We might want to store pointers to constants in backed_enum_table instead of names, @@ -251,11 +268,26 @@ static void zend_enum_from_base(INTERNAL_FUNCTION_PARAMETERS, bool try) zval *case_zv = &c->value; if (Z_TYPE_P(case_zv) == IS_CONSTANT_AST) { if (zval_update_constant_ex(case_zv, c->ce) == FAILURE) { - RETURN_THROWS(); + goto throw; } } - ZVAL_COPY(return_value, case_zv); + if (release_string) { + zend_string_release(string_key); + } + RETURN_COPY(case_zv); + +throw: + if (release_string) { + zend_string_release(string_key); + } + RETURN_THROWS(); + +return_null: + if (release_string) { + zend_string_release(string_key); + } + RETURN_NULL(); } static ZEND_NAMED_FUNCTION(zend_enum_from_func) diff --git a/Zend/zend_execute_API.c b/Zend/zend_execute_API.c index 42c4bb773bab5..7ccfaa6034ae0 100644 --- a/Zend/zend_execute_API.c +++ b/Zend/zend_execute_API.c @@ -921,11 +921,6 @@ zend_result zend_call_function(zend_fcall_info *fci, zend_fcall_info_cache *fci_ } else { zend_execute_internal(call, fci->retval); } - EG(current_execute_data) = call->prev_execute_data; - zend_vm_stack_free_args(call); - if (UNEXPECTED(ZEND_CALL_INFO(call) & ZEND_CALL_HAS_EXTRA_NAMED_PARAMS)) { - zend_array_release(call->extra_named_params); - } #if ZEND_DEBUG if (!EG(exception) && call->func) { @@ -938,6 +933,11 @@ zend_result zend_call_function(zend_fcall_info *fci, zend_fcall_info_cache *fci_ ? Z_ISREF_P(fci->retval) : !Z_ISREF_P(fci->retval)); } #endif + EG(current_execute_data) = call->prev_execute_data; + zend_vm_stack_free_args(call); + if (UNEXPECTED(ZEND_CALL_INFO(call) & ZEND_CALL_HAS_EXTRA_NAMED_PARAMS)) { + zend_array_release(call->extra_named_params); + } if (EG(exception)) { zval_ptr_dtor(fci->retval); diff --git a/Zend/zend_fibers.c b/Zend/zend_fibers.c index dd06f86ae8da6..1fec85528fbb3 100644 --- a/Zend/zend_fibers.c +++ b/Zend/zend_fibers.c @@ -141,7 +141,7 @@ typedef struct { /* These functions are defined in assembler files provided by boost.context (located in "Zend/asm"). */ extern void *make_fcontext(void *sp, size_t size, void (*fn)(boost_context_data)); -extern boost_context_data jump_fcontext(void *to, zend_fiber_transfer *transfer); +extern ZEND_INDIRECT_RETURN boost_context_data jump_fcontext(void *to, zend_fiber_transfer *transfer); #endif ZEND_API zend_class_entry *zend_ce_fiber; diff --git a/Zend/zend_object_handlers.c b/Zend/zend_object_handlers.c index 3b0cfab1778d4..966ba0dd6ed72 100644 --- a/Zend/zend_object_handlers.c +++ b/Zend/zend_object_handlers.c @@ -111,6 +111,10 @@ ZEND_API HashTable *zend_std_build_object_properties_array(zend_object *zobj) /* continue; } + if (Z_ISREF_P(prop) && Z_REFCOUNT_P(prop) == 1) { + prop = Z_REFVAL_P(prop); + } + Z_TRY_ADDREF_P(prop); _zend_hash_append(ht, prop_info->name, prop); } diff --git a/Zend/zend_portability.h b/Zend/zend_portability.h index 6ad9f1b1db2f9..74f8be3c1a26c 100644 --- a/Zend/zend_portability.h +++ b/Zend/zend_portability.h @@ -679,4 +679,10 @@ extern "C++" { # define ZEND_VOIDP(ptr) (ptr) #endif +#if defined(__GNUC__) && ZEND_GCC_VERSION >= 9000 +# define ZEND_INDIRECT_RETURN __attribute__((__indirect_return__)) +#else +# define ZEND_INDIRECT_RETURN +#endif + #endif /* ZEND_PORTABILITY_H */ diff --git a/configure.ac b/configure.ac index b4fa28f288136..3b908f2df0591 100644 --- a/configure.ac +++ b/configure.ac @@ -17,7 +17,7 @@ dnl Basic autoconf initialization, generation of config.nice. dnl ---------------------------------------------------------------------------- AC_PREREQ([2.68]) -AC_INIT([PHP],[8.1.7-dev],[https://bugs.php.net],[php],[https://www.php.net]) +AC_INIT([PHP],[8.1.8],[https://bugs.php.net],[php],[https://www.php.net]) AC_CONFIG_SRCDIR([main/php_version.h]) AC_CONFIG_AUX_DIR([build]) AC_PRESERVE_HELP_ORDER diff --git a/ext/com_dotnet/com_handlers.c b/ext/com_dotnet/com_handlers.c index afab1dc069ba0..9dcaf15a2adb3 100644 --- a/ext/com_dotnet/com_handlers.c +++ b/ext/com_dotnet/com_handlers.c @@ -453,7 +453,11 @@ static int com_object_cast(zend_object *readobj, zval *writeobj, int type) switch(type) { case IS_LONG: case _IS_NUMBER: - vt = VT_INT; +#if SIZEOF_ZEND_LONG == 4 + vt = VT_I4; +#else + vt = VT_I8; +#endif break; case IS_DOUBLE: vt = VT_R8; diff --git a/ext/com_dotnet/tests/gh8778.phpt b/ext/com_dotnet/tests/gh8778.phpt new file mode 100644 index 0000000000000..968804b7c5c81 --- /dev/null +++ b/ext/com_dotnet/tests/gh8778.phpt @@ -0,0 +1,18 @@ +--TEST-- +Bug GH-8778 (Integer arithmethic with large number variants fails) +--SKIPIF-- + +--FILE-- + +--EXPECT-- +int(4294967296) +int(4294967297) diff --git a/ext/curl/interface.c b/ext/curl/interface.c index 319137b38d88f..4fc0415e78757 100644 --- a/ext/curl/interface.c +++ b/ext/curl/interface.c @@ -2363,7 +2363,6 @@ static int _php_curl_setopt(php_curl *ch, zend_long option, zval *zvalue, bool i case CURLOPT_RTSP_REQUEST: case CURLOPT_RTSP_SERVER_CSEQ: case CURLOPT_WILDCARDMATCH: - case CURLOPT_TLSAUTH_TYPE: case CURLOPT_GSSAPI_DELEGATION: case CURLOPT_ACCEPTTIMEOUT_MS: case CURLOPT_SSL_OPTIONS: @@ -2482,6 +2481,7 @@ static int _php_curl_setopt(php_curl *ch, zend_long option, zval *zvalue, bool i case CURLOPT_MAIL_FROM: case CURLOPT_RTSP_STREAM_URI: case CURLOPT_RTSP_TRANSPORT: + case CURLOPT_TLSAUTH_TYPE: case CURLOPT_TLSAUTH_PASSWORD: case CURLOPT_TLSAUTH_USERNAME: case CURLOPT_ACCEPT_ENCODING: diff --git a/ext/date/lib/dow.c b/ext/date/lib/dow.c index 52f43b1a89d26..c288e5db97281 100644 --- a/ext/date/lib/dow.c +++ b/ext/date/lib/dow.c @@ -52,7 +52,7 @@ static timelib_sll timelib_day_of_week_ex(timelib_sll y, timelib_sll m, timelib_ /* Only valid for Gregorian calendar, commented out as we don't handle * Julian calendar. We just return the 'wrong' day of week to be * consistent. */ - c1 = century_value(y / 100); + c1 = century_value(positive_mod(y, 400) / 100); y1 = positive_mod(y, 100); m1 = timelib_is_leap(y) ? m_table_leap[m] : m_table_common[m]; dow = positive_mod((c1 + y1 + m1 + (y1 / 4) + d), 7); diff --git a/ext/date/php_date.c b/ext/date/php_date.c index 49e1cb0045188..c22b9159fd8a5 100644 --- a/ext/date/php_date.c +++ b/ext/date/php_date.c @@ -2379,7 +2379,7 @@ PHP_FUNCTION(date_create_from_format) ZEND_PARSE_PARAMETERS_START(2, 3) Z_PARAM_STRING(format_str, format_str_len) - Z_PARAM_STRING(time_str, time_str_len) + Z_PARAM_PATH(time_str, time_str_len) Z_PARAM_OPTIONAL Z_PARAM_OBJECT_OF_CLASS_OR_NULL(timezone_object, date_ce_timezone) ZEND_PARSE_PARAMETERS_END(); @@ -2401,7 +2401,7 @@ PHP_FUNCTION(date_create_immutable_from_format) ZEND_PARSE_PARAMETERS_START(2, 3) Z_PARAM_STRING(format_str, format_str_len) - Z_PARAM_STRING(time_str, time_str_len) + Z_PARAM_PATH(time_str, time_str_len) Z_PARAM_OPTIONAL Z_PARAM_OBJECT_OF_CLASS_OR_NULL(timezone_object, date_ce_timezone) ZEND_PARSE_PARAMETERS_END(); @@ -2803,7 +2803,7 @@ PHP_FUNCTION(date_parse_from_format) ZEND_PARSE_PARAMETERS_START(2, 2) Z_PARAM_STR(format) - Z_PARAM_STR(date) + Z_PARAM_PATH_STR(date) ZEND_PARSE_PARAMETERS_END(); parsed_time = timelib_parse_from_format(ZSTR_VAL(format), ZSTR_VAL(date), ZSTR_LEN(date), &error, DATE_TIMEZONEDB, php_date_parse_tzfile_wrapper); @@ -3437,6 +3437,13 @@ static int timezone_initialize(php_timezone_obj *tzobj, const char *tz, size_t t } dummy_t->z = timelib_parse_zone(&tz, &dst, dummy_t, ¬_found, DATE_TIMEZONEDB, php_date_parse_tzfile_wrapper); + dummy_t->dst = dst; + if (!not_found && (*tz != '\0')) { + php_error_docref(NULL, E_WARNING, "Unknown or bad timezone (%s)", orig_tz); + timelib_free(dummy_t->tz_abbr); + efree(dummy_t); + return FAILURE; + } if (not_found) { php_error_docref(NULL, E_WARNING, "Unknown or bad timezone (%s)", orig_tz); efree(dummy_t); diff --git a/ext/date/tests/bug49585.phpt b/ext/date/tests/bug49585.phpt index d21bba6c5ce0b..c078618b3d96b 100644 --- a/ext/date/tests/bug49585.phpt +++ b/ext/date/tests/bug49585.phpt @@ -13,5 +13,5 @@ var_dump($date->format('c')); ?> --EXPECT-- string(32) "Fri, 01 Jan -1500 00:00:00 +0000" -string(38) "Mon, 01 Jan -2147483648 00:00:00 +0000" +string(38) "Tue, 01 Jan -2147483648 00:00:00 +0000" string(32) "-2147483648-01-01T00:00:00+00:00" diff --git a/ext/date/tests/bug72963.phpt b/ext/date/tests/bug72963.phpt new file mode 100644 index 0000000000000..0fd01808a8445 --- /dev/null +++ b/ext/date/tests/bug72963.phpt @@ -0,0 +1,92 @@ +--TEST-- +Bug #72963 (Null-byte injection in CreateFromFormat and related functions) +--INI-- +date.timezone=UTC +--FILE-- +getMessage(), "\n"; + } + + try { + $d2 = DateTimeImmutable::createFromFormat('!m/d/Y', $string); + } catch (ValueError $v) { + echo $v->getMessage(), "\n"; + } + + try { + $d3 = date_parse_from_format('m/d/Y', $string); + } catch (ValueError $v) { + echo $v->getMessage(), "\n"; + } + + var_dump($d1, $d2, $d3); +} +?> +--EXPECT-- +Covering string: 8/8/2016 + +object(DateTime)#1 (3) { + ["date"]=> + string(26) "2016-08-08 00:00:00.000000" + ["timezone_type"]=> + int(3) + ["timezone"]=> + string(3) "UTC" +} +object(DateTimeImmutable)#2 (3) { + ["date"]=> + string(26) "2016-08-08 00:00:00.000000" + ["timezone_type"]=> + int(3) + ["timezone"]=> + string(3) "UTC" +} +array(12) { + ["year"]=> + int(2016) + ["month"]=> + int(8) + ["day"]=> + int(8) + ["hour"]=> + bool(false) + ["minute"]=> + bool(false) + ["second"]=> + bool(false) + ["fraction"]=> + bool(false) + ["warning_count"]=> + int(0) + ["warnings"]=> + array(0) { + } + ["error_count"]=> + int(0) + ["errors"]=> + array(0) { + } + ["is_localtime"]=> + bool(false) +} + +Covering string: 8/8/2016\0asf + +DateTime::createFromFormat(): Argument #2 ($datetime) must not contain any null bytes +DateTimeImmutable::createFromFormat(): Argument #2 ($datetime) must not contain any null bytes +date_parse_from_format(): Argument #2 ($datetime) must not contain any null bytes +NULL +NULL +NULL diff --git a/ext/date/tests/bug74671.phpt b/ext/date/tests/bug74671.phpt new file mode 100644 index 0000000000000..a553ffa3ff173 --- /dev/null +++ b/ext/date/tests/bug74671.phpt @@ -0,0 +1,21 @@ +--TEST-- +Bug #74671 (DST timezone abbreviation has incorrect offset) +--FILE-- +format('c')); +?> +--EXPECTF-- +object(DateTime)#%d (%d) { + ["date"]=> + string(26) "2017-05-16 10:11:32.000000" + ["timezone_type"]=> + int(2) + ["timezone"]=> + string(4) "CEST" +} +string(25) "2017-05-16T10:11:32+02:00" diff --git a/ext/date/tests/bug75851.phpt b/ext/date/tests/bug75851.phpt index d447792b93161..0427e09885cd9 100644 --- a/ext/date/tests/bug75851.phpt +++ b/ext/date/tests/bug75851.phpt @@ -13,9 +13,9 @@ echo date(DATE_ATOM."\n".DATE_RFC2822."\nc\nr\no\ny\nY\nU\n\n", PHP_INT_MAX); ?> --EXPECT-- -292277022657-01-27T08:29:52+00:00 -Fri, 27 Jan -292277022657 08:29:52 +0000 +Sun, 27 Jan -292277022657 08:29:52 +0000 -292277022657-01-27T08:29:52+00:00 -Fri, 27 Jan -292277022657 08:29:52 +0000 +Sun, 27 Jan -292277022657 08:29:52 +0000 -292277022657 -57 -292277022657 diff --git a/ext/date/tests/bug77243-001.phpt b/ext/date/tests/bug77243-001.phpt new file mode 100644 index 0000000000000..b347d033429e0 --- /dev/null +++ b/ext/date/tests/bug77243-001.phpt @@ -0,0 +1,36 @@ +--TEST-- +Bug #77243 (Weekdays are calculated incorrectly for negative years) +--SKIPIF-- + +--FILE-- + +--EXPECT-- +-0001-12-24 -1-51-5 +-0001-12-25 -1-51-6 +-0001-12-26 -1-51-7 +-0001-12-27 -1-52-1 +-0001-12-28 -1-52-2 +-0001-12-29 -1-52-3 +-0001-12-30 -1-52-4 +-0001-12-31 -1-52-5 +0000-01-01 -1-52-6 +0000-01-02 -1-52-7 +0000-01-03 0-01-1 +0000-01-04 0-01-2 +0000-01-05 0-01-3 +0000-01-06 0-01-4 +0000-01-07 0-01-5 +0000-01-08 0-01-6 +0000-01-09 0-01-7 +0000-01-10 0-02-1 +0000-01-11 0-02-2 +0000-01-12 0-02-3 diff --git a/ext/date/tests/bug77243-002.phpt b/ext/date/tests/bug77243-002.phpt new file mode 100644 index 0000000000000..fa6408da18ae1 --- /dev/null +++ b/ext/date/tests/bug77243-002.phpt @@ -0,0 +1,70 @@ +--TEST-- +Bug #77243 (Weekdays are calculated incorrectly for negative years) +--SKIPIF-- + +--FILE-- + +--EXPECT-- +-0102-12-26 -102-52-1 +-0102-12-27 -102-52-2 +-0102-12-28 -102-52-3 +-0102-12-29 -102-52-4 +-0102-12-30 -102-52-5 +-0102-12-31 -102-52-6 +-0101-01-01 -102-52-7 +-0101-01-02 -101-01-1 +-0101-01-03 -101-01-2 +-0101-01-04 -101-01-3 +-0101-01-05 -101-01-4 +-0101-01-06 -101-01-5 +-0101-01-07 -101-01-6 +-0101-01-08 -101-01-7 + + +-0101-12-26 -101-52-2 +-0101-12-27 -101-52-3 +-0101-12-28 -101-52-4 +-0101-12-29 -101-52-5 +-0101-12-30 -101-52-6 +-0101-12-31 -101-52-7 +-0100-01-01 -100-01-1 +-0100-01-02 -100-01-2 +-0100-01-03 -100-01-3 +-0100-01-04 -100-01-4 +-0100-01-05 -100-01-5 +-0100-01-06 -100-01-6 +-0100-01-07 -100-01-7 +-0100-01-08 -100-02-1 + + +-0100-12-26 -100-52-3 +-0100-12-27 -100-52-4 +-0100-12-28 -100-52-5 +-0100-12-29 -100-52-6 +-0100-12-30 -100-52-7 +-0100-12-31 -99-01-1 +-0099-01-01 -99-01-2 +-0099-01-02 -99-01-3 +-0099-01-03 -99-01-4 +-0099-01-04 -99-01-5 +-0099-01-05 -99-01-6 +-0099-01-06 -99-01-7 +-0099-01-07 -99-02-1 +-0099-01-08 -99-02-2 diff --git a/ext/date/tests/bug78139.phpt b/ext/date/tests/bug78139.phpt new file mode 100644 index 0000000000000..0ecf404274b03 --- /dev/null +++ b/ext/date/tests/bug78139.phpt @@ -0,0 +1,73 @@ +--TEST-- +Bug #78139 (timezone_open accepts invalid timezone string argument) +--FILE-- +getMessage(), "\n"; + } + + echo "\n\n"; +} +?> +--EXPECTF-- +Parsing 'x': +object(DateTimeZone)#1 (2) { + ["timezone_type"]=> + int(2) + ["timezone"]=> + string(1) "X" +} + + +Parsing 'x UTC': + +Warning: timezone_open(): Unknown or bad timezone (x UTC) in %sbug78139.php on line %d +bool(false) +DateTimeZone::__construct(): Unknown or bad timezone (x UTC) + + +Parsing 'xx UTC': + +Warning: timezone_open(): Unknown or bad timezone (xx UTC) in %sbug78139.php on line %d +bool(false) +DateTimeZone::__construct(): Unknown or bad timezone (xx UTC) + + +Parsing 'xUTC': + +Warning: timezone_open(): Unknown or bad timezone (xUTC) in %sbug78139.php on line %d +bool(false) +DateTimeZone::__construct(): Unknown or bad timezone (xUTC) + + +Parsing 'UTCx': + +Warning: timezone_open(): Unknown or bad timezone (UTCx) in %sbug78139.php on line %d +bool(false) +DateTimeZone::__construct(): Unknown or bad timezone (UTCx) + + +Parsing 'UTC xx': + +Warning: timezone_open(): Unknown or bad timezone (UTC xx) in %sbug78139.php on line %d +bool(false) +DateTimeZone::__construct(): Unknown or bad timezone (UTC xx) + diff --git a/ext/fileinfo/libmagic.patch b/ext/fileinfo/libmagic.patch index 27124692a00a9..3373ae451989e 100644 --- a/ext/fileinfo/libmagic.patch +++ b/ext/fileinfo/libmagic.patch @@ -1,6 +1,6 @@ -diff -ur libmagic.orig/apprentice.c libmagic/apprentice.c +diff -u libmagic.orig/apprentice.c libmagic/apprentice.c --- libmagic.orig/apprentice.c 2021-02-23 01:51:11.000000000 +0100 -+++ libmagic/apprentice.c 2021-04-06 21:34:57.332978922 +0200 ++++ libmagic/apprentice.c 2022-06-16 13:39:41.570984700 +0200 @@ -29,6 +29,8 @@ * apprentice - make one pass through /etc/magic, learning its secrets. */ @@ -925,9 +925,9 @@ diff -ur libmagic.orig/apprentice.c libmagic/apprentice.c m->str_range = swap4(m->str_range); m->str_flags = swap4(m->str_flags); } -diff -ur libmagic.orig/ascmagic.c libmagic/ascmagic.c +diff -u libmagic.orig/ascmagic.c libmagic/ascmagic.c --- libmagic.orig/ascmagic.c 2021-02-23 01:49:06.000000000 +0100 -+++ libmagic/ascmagic.c 2021-04-06 21:34:57.332978922 +0200 ++++ libmagic/ascmagic.c 2022-06-16 13:39:41.570984700 +0200 @@ -96,7 +96,7 @@ rv = file_ascmagic_with_encoding(ms, &bb, ubuf, ulen, code, type, text); @@ -956,9 +956,9 @@ diff -ur libmagic.orig/ascmagic.c libmagic/ascmagic.c return rv; } -diff -ur libmagic.orig/buffer.c libmagic/buffer.c +diff -u libmagic.orig/buffer.c libmagic/buffer.c --- libmagic.orig/buffer.c 2021-02-23 01:49:26.000000000 +0100 -+++ libmagic/buffer.c 2021-04-06 21:34:57.332978922 +0200 ++++ libmagic/buffer.c 2021-09-21 13:27:27.982716100 +0200 @@ -31,19 +31,23 @@ #endif /* lint */ @@ -1012,9 +1012,9 @@ diff -ur libmagic.orig/buffer.c libmagic/buffer.c b->ebuf = NULL; goto out; } -diff -ur libmagic.orig/cdf.c libmagic/cdf.c +diff -u libmagic.orig/cdf.c libmagic/cdf.c --- libmagic.orig/cdf.c 2021-02-23 01:49:06.000000000 +0100 -+++ libmagic/cdf.c 2021-04-06 21:34:57.332978922 +0200 ++++ libmagic/cdf.c 2021-09-21 13:27:27.983695600 +0200 @@ -43,7 +43,17 @@ #include #endif @@ -1247,9 +1247,9 @@ diff -ur libmagic.orig/cdf.c libmagic/cdf.c } #endif -diff -ur libmagic.orig/cdf.h libmagic/cdf.h +diff -u libmagic.orig/cdf.h libmagic/cdf.h --- libmagic.orig/cdf.h 2021-02-23 01:49:06.000000000 +0100 -+++ libmagic/cdf.h 2021-04-06 21:34:57.332978922 +0200 ++++ libmagic/cdf.h 2021-09-21 13:27:27.984674900 +0200 @@ -35,10 +35,10 @@ #ifndef _H_CDF_ #define _H_CDF_ @@ -1264,9 +1264,9 @@ diff -ur libmagic.orig/cdf.h libmagic/cdf.h #endif #ifdef __DJGPP__ #define timespec timeval -diff -ur libmagic.orig/cdf_time.c libmagic/cdf_time.c +diff -u libmagic.orig/cdf_time.c libmagic/cdf_time.c --- libmagic.orig/cdf_time.c 2021-02-23 01:49:06.000000000 +0100 -+++ libmagic/cdf_time.c 2021-04-06 21:34:57.336978894 +0200 ++++ libmagic/cdf_time.c 2021-09-21 13:27:27.985654400 +0200 @@ -23,6 +23,7 @@ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. @@ -1293,9 +1293,9 @@ diff -ur libmagic.orig/cdf_time.c libmagic/cdf_time.c if (ptr != NULL) return buf; (void)snprintf(buf, 26, "*Bad* %#16.16" INT64_T_FORMAT "x\n", -diff -ur libmagic.orig/compress.c libmagic/compress.c +diff -u libmagic.orig/compress.c libmagic/compress.c --- libmagic.orig/compress.c 2021-02-23 01:49:07.000000000 +0100 -+++ libmagic/compress.c 2021-04-06 21:34:57.336978894 +0200 ++++ libmagic/compress.c 2022-06-16 13:39:41.586609800 +0200 @@ -51,7 +51,7 @@ #ifndef HAVE_SIG_T typedef void (*sig_t)(int); @@ -1430,9 +1430,9 @@ diff -ur libmagic.orig/compress.c libmagic/compress.c } #endif +#endif -diff -ur libmagic.orig/der.c libmagic/der.c +diff -u libmagic.orig/der.c libmagic/der.c --- libmagic.orig/der.c 2021-02-23 01:49:06.000000000 +0100 -+++ libmagic/der.c 2021-04-06 21:34:57.336978894 +0200 ++++ libmagic/der.c 2022-06-16 13:39:41.586609800 +0200 @@ -54,7 +54,9 @@ #include "magic.h" #include "der.h" @@ -1443,9 +1443,9 @@ diff -ur libmagic.orig/der.c libmagic/der.c #include #include #endif -diff -ur libmagic.orig/elfclass.h libmagic/elfclass.h +diff -u libmagic.orig/elfclass.h libmagic/elfclass.h --- libmagic.orig/elfclass.h 2021-02-23 01:49:06.000000000 +0100 -+++ libmagic/elfclass.h 2021-04-06 21:34:57.336978894 +0200 ++++ libmagic/elfclass.h 2021-09-21 13:27:27.989571700 +0200 @@ -41,7 +41,7 @@ return toomany(ms, "program headers", phnum); flags |= FLAGS_IS_CORE; @@ -1473,9 +1473,9 @@ diff -ur libmagic.orig/elfclass.h libmagic/elfclass.h CAST(size_t, elf_getu16(swap, elfhdr.e_shentsize)), fsize, elf_getu16(swap, elfhdr.e_machine), CAST(int, elf_getu16(swap, elfhdr.e_shstrndx)), -diff -ur libmagic.orig/encoding.c libmagic/encoding.c +diff -u libmagic.orig/encoding.c libmagic/encoding.c --- libmagic.orig/encoding.c 2021-02-23 01:49:06.000000000 +0100 -+++ libmagic/encoding.c 2021-04-06 21:34:57.336978894 +0200 ++++ libmagic/encoding.c 2022-06-16 13:39:41.586609800 +0200 @@ -98,14 +98,14 @@ nbytes = ms->encoding_max; @@ -1514,9 +1514,9 @@ diff -ur libmagic.orig/encoding.c libmagic/encoding.c } \ if (u < 3) \ return 0; \ -diff -ur libmagic.orig/file.h libmagic/file.h +diff -u libmagic.orig/file.h libmagic/file.h --- libmagic.orig/file.h 2021-02-23 01:49:06.000000000 +0100 -+++ libmagic/file.h 2021-04-06 21:34:57.336978894 +0200 ++++ libmagic/file.h 2022-06-16 13:39:41.586609800 +0200 @@ -33,17 +33,14 @@ #ifndef __file_h__ #define __file_h__ @@ -1775,9 +1775,9 @@ diff -ur libmagic.orig/file.h libmagic/file.h +#endif + #endif /* __file_h__ */ -diff -ur libmagic.orig/fsmagic.c libmagic/fsmagic.c +diff -u libmagic.orig/fsmagic.c libmagic/fsmagic.c --- libmagic.orig/fsmagic.c 2021-02-23 01:49:06.000000000 +0100 -+++ libmagic/fsmagic.c 2021-04-06 21:34:57.336978894 +0200 ++++ libmagic/fsmagic.c 2021-09-21 13:27:27.992511000 +0200 @@ -66,26 +66,10 @@ # define minor(dev) ((dev) & 0xff) #endif @@ -2068,9 +2068,9 @@ diff -ur libmagic.orig/fsmagic.c libmagic/fsmagic.c #ifdef S_IFSOCK #ifndef __COHERENT__ case S_IFSOCK: -diff -ur libmagic.orig/funcs.c libmagic/funcs.c +diff -u libmagic.orig/funcs.c libmagic/funcs.c --- libmagic.orig/funcs.c 2021-02-23 01:49:06.000000000 +0100 -+++ libmagic/funcs.c 2021-04-06 21:34:57.336978894 +0200 ++++ libmagic/funcs.c 2022-06-16 13:39:41.586609800 +0200 @@ -51,6 +51,13 @@ #define SIZE_MAX ((size_t)~0) #endif @@ -2388,9 +2388,9 @@ diff -ur libmagic.orig/funcs.c libmagic/funcs.c protected char * file_strtrim(char *str) -diff -ur libmagic.orig/magic.c libmagic/magic.c +diff -u libmagic.orig/magic.c libmagic/magic.c --- libmagic.orig/magic.c 2021-02-23 01:49:06.000000000 +0100 -+++ libmagic/magic.c 2021-04-06 21:34:57.336978894 +0200 ++++ libmagic/magic.c 2022-06-16 13:39:41.586609800 +0200 @@ -25,11 +25,6 @@ * SUCH DAMAGE. */ @@ -2867,9 +2867,9 @@ diff -ur libmagic.orig/magic.c libmagic/magic.c return NULL; } return file_getbuffer(ms); -diff -ur libmagic.orig/magic.h libmagic/magic.h ---- libmagic.orig/magic.h 2021-04-06 22:37:37.647426536 +0200 -+++ libmagic/magic.h 2021-04-06 21:34:57.336978894 +0200 +diff -u libmagic.orig/magic.h libmagic/magic.h +--- libmagic.orig/magic.h 2022-06-30 17:16:06.144009900 +0200 ++++ libmagic/magic.h 2022-06-16 13:39:41.586609800 +0200 @@ -126,6 +126,7 @@ const char *magic_getpath(const char *, int); @@ -2878,9 +2878,9 @@ diff -ur libmagic.orig/magic.h libmagic/magic.h const char *magic_descriptor(magic_t, int); const char *magic_buffer(magic_t, const void *, size_t); -diff -ur libmagic.orig/print.c libmagic/print.c +diff -u libmagic.orig/print.c libmagic/print.c --- libmagic.orig/print.c 2021-02-23 01:49:07.000000000 +0100 -+++ libmagic/print.c 2021-04-06 21:34:57.340978869 +0200 ++++ libmagic/print.c 2021-09-21 13:27:27.998388700 +0200 @@ -28,6 +28,7 @@ /* * print.c - debugging printout routines @@ -2943,9 +2943,9 @@ diff -ur libmagic.orig/print.c libmagic/print.c if (pp == NULL) goto out; -diff -ur libmagic.orig/readcdf.c libmagic/readcdf.c +diff -u libmagic.orig/readcdf.c libmagic/readcdf.c --- libmagic.orig/readcdf.c 2021-02-23 01:49:08.000000000 +0100 -+++ libmagic/readcdf.c 2021-04-06 21:34:57.340978869 +0200 ++++ libmagic/readcdf.c 2021-09-21 13:27:27.999369100 +0200 @@ -31,7 +31,11 @@ #include @@ -3067,9 +3067,9 @@ diff -ur libmagic.orig/readcdf.c libmagic/readcdf.c out0: /* If we handled it already, return */ if (i != -1) -diff -ur libmagic.orig/softmagic.c libmagic/softmagic.c +diff -u libmagic.orig/softmagic.c libmagic/softmagic.c --- libmagic.orig/softmagic.c 2021-02-23 01:49:06.000000000 +0100 -+++ libmagic/softmagic.c 2021-04-06 21:34:57.340978869 +0200 ++++ libmagic/softmagic.c 2022-06-30 16:58:15.521661800 +0200 @@ -43,6 +43,10 @@ #include #include "der.h" @@ -3247,7 +3247,29 @@ diff -ur libmagic.orig/softmagic.c libmagic/softmagic.c return rv; } -@@ -1845,15 +1847,15 @@ +@@ -1531,11 +1533,7 @@ + size_t len; + *c = ms->c; + len = c->len * sizeof(*c->li); +- ms->c.li = CAST(struct level_info *, malloc(len)); +- if (ms->c.li == NULL) { +- ms->c = *c; +- return -1; +- } ++ ms->c.li = CAST(struct level_info *, emalloc(len)); + memcpy(ms->c.li, c->li, len); + return 0; + } +@@ -1543,7 +1541,7 @@ + private void + restore_cont(struct magic_set *ms, struct cont *c) + { +- free(ms->c.li); ++ efree(ms->c.li); + ms->c = *c; + } + +@@ -1845,15 +1843,15 @@ if ((ms->flags & MAGIC_NODESC) == 0 && file_printf(ms, F(ms, m->desc, "%u"), offset) == -1) { @@ -3266,7 +3288,7 @@ diff -ur libmagic.orig/softmagic.c libmagic/softmagic.c return rv; case FILE_USE: -@@ -1958,10 +1960,13 @@ +@@ -1958,10 +1956,13 @@ } else if ((flags & STRING_COMPACT_WHITESPACE) && isspace(*a)) { @@ -3281,7 +3303,7 @@ diff -ur libmagic.orig/softmagic.c libmagic/softmagic.c b++; } else { -@@ -1997,6 +2002,60 @@ +@@ -1997,6 +1998,60 @@ return file_strncmp(a, b, len, maxlen, flags); } @@ -3342,7 +3364,7 @@ diff -ur libmagic.orig/softmagic.c libmagic/softmagic.c private int magiccheck(struct magic_set *ms, struct magic *m) { -@@ -2176,65 +2235,77 @@ +@@ -2176,65 +2231,77 @@ break; } case FILE_REGEX: { @@ -3471,9 +3493,9 @@ diff -ur libmagic.orig/softmagic.c libmagic/softmagic.c break; } case FILE_USE: -diff -ur libmagic.orig/strcasestr.c libmagic/strcasestr.c +diff -u libmagic.orig/strcasestr.c libmagic/strcasestr.c --- libmagic.orig/strcasestr.c 2021-02-23 01:49:12.000000000 +0100 -+++ libmagic/strcasestr.c 2021-04-06 21:34:57.340978869 +0200 ++++ libmagic/strcasestr.c 2021-09-21 13:27:28.002306200 +0200 @@ -39,6 +39,8 @@ #include "file.h" @@ -3483,7 +3505,3 @@ diff -ur libmagic.orig/strcasestr.c libmagic/strcasestr.c #include #include #include ---- libmagic/config.h 2021-04-06 22:19:57.552120067 +0200 -+++ /dev/null 2021-03-31 20:37:24.776503884 +0200 -@@ -1 +0,0 @@ --#include "php.h" diff --git a/ext/fileinfo/libmagic/softmagic.c b/ext/fileinfo/libmagic/softmagic.c index c86524e31e623..5132b4ddea7ed 100644 --- a/ext/fileinfo/libmagic/softmagic.c +++ b/ext/fileinfo/libmagic/softmagic.c @@ -1533,11 +1533,7 @@ save_cont(struct magic_set *ms, struct cont *c) size_t len; *c = ms->c; len = c->len * sizeof(*c->li); - ms->c.li = CAST(struct level_info *, malloc(len)); - if (ms->c.li == NULL) { - ms->c = *c; - return -1; - } + ms->c.li = CAST(struct level_info *, emalloc(len)); memcpy(ms->c.li, c->li, len); return 0; } @@ -1545,7 +1541,7 @@ save_cont(struct magic_set *ms, struct cont *c) private void restore_cont(struct magic_set *ms, struct cont *c) { - free(ms->c.li); + efree(ms->c.li); ms->c = *c; } diff --git a/ext/fileinfo/tests/bug81723.phpt b/ext/fileinfo/tests/bug81723.phpt new file mode 100644 index 0000000000000..16bfb81f10de8 --- /dev/null +++ b/ext/fileinfo/tests/bug81723.phpt @@ -0,0 +1,12 @@ +--TEST-- +Bug #81723 (Memory corruption in finfo_buffer()) +--EXTENSIONS-- +fileinfo +--FILE-- + +--EXPECT-- diff --git a/ext/gd/libgd/gd_avif.c b/ext/gd/libgd/gd_avif.c index 6b1d448de7baf..30075d2a899c8 100644 --- a/ext/gd/libgd/gd_avif.c +++ b/ext/gd/libgd/gd_avif.c @@ -150,6 +150,11 @@ static avifBool isAvifError(avifResult result, const char *msg) { } +typedef struct avifIOCtxReader { + avifIO io; // this must be the first member for easy casting to avifIO* + avifROData rodata; +} avifIOCtxReader; + /* implements the avifIOReadFunc interface by calling the relevant functions in the gdIOCtx. Our logic is inspired by avifIOMemoryReaderRead() and avifIOFileReaderRead(). @@ -165,8 +170,8 @@ static avifBool isAvifError(avifResult result, const char *msg) { */ static avifResult readFromCtx(avifIO *io, uint32_t readFlags, uint64_t offset, size_t size, avifROData *out) { - void *dataBuf = NULL; gdIOCtx *ctx = (gdIOCtx *) io->data; + avifIOCtxReader *reader = (avifIOCtxReader *) io; // readFlags is unsupported if (readFlags != 0) { @@ -182,28 +187,34 @@ static avifResult readFromCtx(avifIO *io, uint32_t readFlags, uint64_t offset, s if (!ctx->seek(ctx, (int) offset)) return AVIF_RESULT_IO_ERROR; - dataBuf = avifAlloc(size); - if (!dataBuf) { + if (size > reader->rodata.size) { + reader->rodata.data = gdRealloc((void *) reader->rodata.data, size); + reader->rodata.size = size; + } + if (!reader->rodata.data) { gd_error("avif error - couldn't allocate memory"); return AVIF_RESULT_UNKNOWN_ERROR; } // Read the number of bytes requested. // If getBuf() returns a negative value, that means there was an error. - int charsRead = ctx->getBuf(ctx, dataBuf, (int) size); + int charsRead = ctx->getBuf(ctx, (void *) reader->rodata.data, (int) size); if (charsRead < 0) { - avifFree(dataBuf); return AVIF_RESULT_IO_ERROR; } - out->data = dataBuf; + out->data = reader->rodata.data; out->size = charsRead; return AVIF_RESULT_OK; } // avif.h says this is optional, but it seemed easy to implement. static void destroyAvifIO(struct avifIO *io) { - gdFree(io); + avifIOCtxReader *reader = (avifIOCtxReader *) io; + if (reader->rodata.data != NULL) { + gdFree((void *) reader->rodata.data); + } + gdFree(reader); } /* Set up an avifIO object. @@ -217,21 +228,23 @@ static void destroyAvifIO(struct avifIO *io) { // TODO: can we get sizeHint somehow? static avifIO *createAvifIOFromCtx(gdIOCtx *ctx) { - avifIO *io; + struct avifIOCtxReader *reader; - io = gdMalloc(sizeof(*io)); - if (io == NULL) + reader = gdMalloc(sizeof(*reader)); + if (reader == NULL) return NULL; // TODO: setting persistent=FALSE is safe, but it's less efficient. Is it necessary? - io->persistent = AVIF_FALSE; - io->read = readFromCtx; - io->write = NULL; // this function is currently unused; see avif.h - io->destroy = destroyAvifIO; - io->sizeHint = 0; // sadly, we don't get this information from the gdIOCtx. - io->data = ctx; - - return io; + reader->io.persistent = AVIF_FALSE; + reader->io.read = readFromCtx; + reader->io.write = NULL; // this function is currently unused; see avif.h + reader->io.destroy = destroyAvifIO; + reader->io.sizeHint = 0; // sadly, we don't get this information from the gdIOCtx. + reader->io.data = ctx; + reader->rodata.data = NULL; + reader->rodata.size = 0; + + return (avifIO *) reader; } @@ -576,6 +589,9 @@ void gdImageAvifCtx(gdImagePtr im, gdIOCtx *outfile, int quality, int speed) if (avifOutput.data) avifRWDataFree(&avifOutput); + + if (avifIm) + avifImageDestroy(avifIm); } void gdImageAvifEx(gdImagePtr im, FILE *outFile, int quality, int speed) diff --git a/ext/intl/tests/dateformat_format_variant3.phpt b/ext/intl/tests/dateformat_format_variant3.phpt index c8601aadefd88..f1336c5ed3195 100644 --- a/ext/intl/tests/dateformat_format_variant3.phpt +++ b/ext/intl/tests/dateformat_format_variant3.phpt @@ -2,6 +2,8 @@ datefmt_format_code() --EXTENSIONS-- intl +--XFAIL-- +This test assumes wrong data wrt to PDT. It is also too big and needs splitting up. --SKIPIF-- = 52.1'); ?> --FILE-- @@ -157,165 +159,165 @@ ut_run(); Input timestamp is : 0 ------------ -IntlDateFormatter locale= en_US ,datetype = 0 ,timetype =0 +IntlDateFormatter locale= en_US ,datetype = 0 ,timetype =0 Formatted timestamp is : Wednesday, December 31, 1969 at 2:00:00 PM GMT-10:00 -IntlDateFormatter locale= en_US ,datetype = 1 ,timetype =1 +IntlDateFormatter locale= en_US ,datetype = 1 ,timetype =1 Formatted timestamp is : December 31, 1969 at 2:00:00 PM GMT-10 -IntlDateFormatter locale= en_US ,datetype = 2 ,timetype =2 +IntlDateFormatter locale= en_US ,datetype = 2 ,timetype =2 Formatted timestamp is : Dec 31, 1969, 2:00:00 PM -IntlDateFormatter locale= en_US ,datetype = 3 ,timetype =3 +IntlDateFormatter locale= en_US ,datetype = 3 ,timetype =3 Formatted timestamp is : 12/31/69, 2:00 PM -IntlDateFormatter locale= en_US ,datetype = -1 ,timetype =-1 +IntlDateFormatter locale= en_US ,datetype = -1 ,timetype =-1 Formatted timestamp is : 19691231 02:00 PM ------------ Input timestamp is : -1200000 ------------ -IntlDateFormatter locale= en_US ,datetype = 0 ,timetype =0 +IntlDateFormatter locale= en_US ,datetype = 0 ,timetype =0 Formatted timestamp is : Wednesday, December 17, 1969 at 4:40:00 PM GMT-10:00 -IntlDateFormatter locale= en_US ,datetype = 1 ,timetype =1 +IntlDateFormatter locale= en_US ,datetype = 1 ,timetype =1 Formatted timestamp is : December 17, 1969 at 4:40:00 PM GMT-10 -IntlDateFormatter locale= en_US ,datetype = 2 ,timetype =2 +IntlDateFormatter locale= en_US ,datetype = 2 ,timetype =2 Formatted timestamp is : Dec 17, 1969, 4:40:00 PM -IntlDateFormatter locale= en_US ,datetype = 3 ,timetype =3 +IntlDateFormatter locale= en_US ,datetype = 3 ,timetype =3 Formatted timestamp is : 12/17/69, 4:40 PM -IntlDateFormatter locale= en_US ,datetype = -1 ,timetype =-1 +IntlDateFormatter locale= en_US ,datetype = -1 ,timetype =-1 Formatted timestamp is : 19691217 04:40 PM ------------ Input timestamp is : 1200000 ------------ -IntlDateFormatter locale= en_US ,datetype = 0 ,timetype =0 +IntlDateFormatter locale= en_US ,datetype = 0 ,timetype =0 Formatted timestamp is : Wednesday, January 14, 1970 at 11:20:00 AM GMT-10:00 -IntlDateFormatter locale= en_US ,datetype = 1 ,timetype =1 +IntlDateFormatter locale= en_US ,datetype = 1 ,timetype =1 Formatted timestamp is : January 14, 1970 at 11:20:00 AM GMT-10 -IntlDateFormatter locale= en_US ,datetype = 2 ,timetype =2 +IntlDateFormatter locale= en_US ,datetype = 2 ,timetype =2 Formatted timestamp is : Jan 14, 1970, 11:20:00 AM -IntlDateFormatter locale= en_US ,datetype = 3 ,timetype =3 +IntlDateFormatter locale= en_US ,datetype = 3 ,timetype =3 Formatted timestamp is : 1/14/70, 11:20 AM -IntlDateFormatter locale= en_US ,datetype = -1 ,timetype =-1 +IntlDateFormatter locale= en_US ,datetype = -1 ,timetype =-1 Formatted timestamp is : 19700114 11:20 AM ------------ Input timestamp is : 2200000000 ------------ -IntlDateFormatter locale= en_US ,datetype = 0 ,timetype =0 +IntlDateFormatter locale= en_US ,datetype = 0 ,timetype =0 Formatted timestamp is : Sunday, September 18, 2039 at 1:06:40 PM GMT-10:00 -IntlDateFormatter locale= en_US ,datetype = 1 ,timetype =1 +IntlDateFormatter locale= en_US ,datetype = 1 ,timetype =1 Formatted timestamp is : September 18, 2039 at 1:06:40 PM GMT-10 -IntlDateFormatter locale= en_US ,datetype = 2 ,timetype =2 +IntlDateFormatter locale= en_US ,datetype = 2 ,timetype =2 Formatted timestamp is : Sep 18, 2039, 1:06:40 PM -IntlDateFormatter locale= en_US ,datetype = 3 ,timetype =3 +IntlDateFormatter locale= en_US ,datetype = 3 ,timetype =3 Formatted timestamp is : 9/18/39, 1:06 PM -IntlDateFormatter locale= en_US ,datetype = -1 ,timetype =-1 +IntlDateFormatter locale= en_US ,datetype = -1 ,timetype =-1 Formatted timestamp is : 20390918 01:06 PM ------------ Input timestamp is : -2200000000 ------------ -IntlDateFormatter locale= en_US ,datetype = 0 ,timetype =0 +IntlDateFormatter locale= en_US ,datetype = 0 ,timetype =0 Formatted timestamp is : Saturday, April 14, 1900 at 2:53:20 PM GMT-10:00 -IntlDateFormatter locale= en_US ,datetype = 1 ,timetype =1 +IntlDateFormatter locale= en_US ,datetype = 1 ,timetype =1 Formatted timestamp is : April 14, 1900 at 2:53:20 PM GMT-10 -IntlDateFormatter locale= en_US ,datetype = 2 ,timetype =2 +IntlDateFormatter locale= en_US ,datetype = 2 ,timetype =2 Formatted timestamp is : Apr 14, 1900, 2:53:20 PM -IntlDateFormatter locale= en_US ,datetype = 3 ,timetype =3 +IntlDateFormatter locale= en_US ,datetype = 3 ,timetype =3 Formatted timestamp is : 4/14/00, 2:53 PM -IntlDateFormatter locale= en_US ,datetype = -1 ,timetype =-1 +IntlDateFormatter locale= en_US ,datetype = -1 ,timetype =-1 Formatted timestamp is : 19000414 02:53 PM ------------ Input timestamp is : 90099999 ------------ -IntlDateFormatter locale= en_US ,datetype = 0 ,timetype =0 +IntlDateFormatter locale= en_US ,datetype = 0 ,timetype =0 Formatted timestamp is : Wednesday, November 8, 1972 at 9:46:39 AM GMT-10:00 -IntlDateFormatter locale= en_US ,datetype = 1 ,timetype =1 +IntlDateFormatter locale= en_US ,datetype = 1 ,timetype =1 Formatted timestamp is : November 8, 1972 at 9:46:39 AM GMT-10 -IntlDateFormatter locale= en_US ,datetype = 2 ,timetype =2 +IntlDateFormatter locale= en_US ,datetype = 2 ,timetype =2 Formatted timestamp is : Nov 8, 1972, 9:46:39 AM -IntlDateFormatter locale= en_US ,datetype = 3 ,timetype =3 +IntlDateFormatter locale= en_US ,datetype = 3 ,timetype =3 Formatted timestamp is : 11/8/72, 9:46 AM -IntlDateFormatter locale= en_US ,datetype = -1 ,timetype =-1 +IntlDateFormatter locale= en_US ,datetype = -1 ,timetype =-1 Formatted timestamp is : 19721108 09:46 AM ------------ Input timestamp is : 3600 ------------ -IntlDateFormatter locale= en_US ,datetype = 0 ,timetype =0 +IntlDateFormatter locale= en_US ,datetype = 0 ,timetype =0 Formatted timestamp is : Wednesday, December 31, 1969 at 3:00:00 PM GMT-10:00 -IntlDateFormatter locale= en_US ,datetype = 1 ,timetype =1 +IntlDateFormatter locale= en_US ,datetype = 1 ,timetype =1 Formatted timestamp is : December 31, 1969 at 3:00:00 PM GMT-10 -IntlDateFormatter locale= en_US ,datetype = 2 ,timetype =2 +IntlDateFormatter locale= en_US ,datetype = 2 ,timetype =2 Formatted timestamp is : Dec 31, 1969, 3:00:00 PM -IntlDateFormatter locale= en_US ,datetype = 3 ,timetype =3 +IntlDateFormatter locale= en_US ,datetype = 3 ,timetype =3 Formatted timestamp is : 12/31/69, 3:00 PM -IntlDateFormatter locale= en_US ,datetype = -1 ,timetype =-1 +IntlDateFormatter locale= en_US ,datetype = -1 ,timetype =-1 Formatted timestamp is : 19691231 03:00 PM ------------ Input timestamp is : -3600 ------------ -IntlDateFormatter locale= en_US ,datetype = 0 ,timetype =0 +IntlDateFormatter locale= en_US ,datetype = 0 ,timetype =0 Formatted timestamp is : Wednesday, December 31, 1969 at 1:00:00 PM GMT-10:00 -IntlDateFormatter locale= en_US ,datetype = 1 ,timetype =1 +IntlDateFormatter locale= en_US ,datetype = 1 ,timetype =1 Formatted timestamp is : December 31, 1969 at 1:00:00 PM GMT-10 -IntlDateFormatter locale= en_US ,datetype = 2 ,timetype =2 +IntlDateFormatter locale= en_US ,datetype = 2 ,timetype =2 Formatted timestamp is : Dec 31, 1969, 1:00:00 PM -IntlDateFormatter locale= en_US ,datetype = 3 ,timetype =3 +IntlDateFormatter locale= en_US ,datetype = 3 ,timetype =3 Formatted timestamp is : 12/31/69, 1:00 PM -IntlDateFormatter locale= en_US ,datetype = -1 ,timetype =-1 +IntlDateFormatter locale= en_US ,datetype = -1 ,timetype =-1 Formatted timestamp is : 19691231 01:00 PM ------------ -Input localtime is : tm_sec : '24' , tm_min : '3' , tm_hour : '19' , tm_mday : '3' , tm_mon : '3' , tm_year : '105' , +Input localtime is : tm_sec : '24' , tm_min : '3' , tm_hour : '19' , tm_mday : '3' , tm_mon : '3' , tm_year : '105' , ------------ -IntlDateFormatter locale= en_US ,datetype = 0 ,timetype =0 +IntlDateFormatter locale= en_US ,datetype = 0 ,timetype =0 Formatted localtime_array is : Sunday, April 3, 2005 at 7:03:24 PM GMT-10:00 -IntlDateFormatter locale= en_US ,datetype = 1 ,timetype =1 +IntlDateFormatter locale= en_US ,datetype = 1 ,timetype =1 Formatted localtime_array is : April 3, 2005 at 7:03:24 PM GMT-10 -IntlDateFormatter locale= en_US ,datetype = 2 ,timetype =2 +IntlDateFormatter locale= en_US ,datetype = 2 ,timetype =2 Formatted localtime_array is : Apr 3, 2005, 7:03:24 PM -IntlDateFormatter locale= en_US ,datetype = 3 ,timetype =3 +IntlDateFormatter locale= en_US ,datetype = 3 ,timetype =3 Formatted localtime_array is : 4/3/05, 7:03 PM -IntlDateFormatter locale= en_US ,datetype = -1 ,timetype =-1 +IntlDateFormatter locale= en_US ,datetype = -1 ,timetype =-1 Formatted localtime_array is : 20050403 07:03 PM ------------ -Input localtime is : tm_sec : '21' , tm_min : '5' , tm_hour : '7' , tm_mday : '13' , tm_mon : '4' , tm_year : '205' , +Input localtime is : tm_sec : '21' , tm_min : '5' , tm_hour : '7' , tm_mday : '13' , tm_mon : '4' , tm_year : '205' , ------------ -IntlDateFormatter locale= en_US ,datetype = 0 ,timetype =0 +IntlDateFormatter locale= en_US ,datetype = 0 ,timetype =0 Formatted localtime_array is : Wednesday, May 13, 2105 at 7:05:21 AM GMT-10:00 -IntlDateFormatter locale= en_US ,datetype = 1 ,timetype =1 +IntlDateFormatter locale= en_US ,datetype = 1 ,timetype =1 Formatted localtime_array is : May 13, 2105 at 7:05:21 AM GMT-10 -IntlDateFormatter locale= en_US ,datetype = 2 ,timetype =2 +IntlDateFormatter locale= en_US ,datetype = 2 ,timetype =2 Formatted localtime_array is : May 13, 2105, 7:05:21 AM -IntlDateFormatter locale= en_US ,datetype = 3 ,timetype =3 +IntlDateFormatter locale= en_US ,datetype = 3 ,timetype =3 Formatted localtime_array is : 5/13/05, 7:05 AM -IntlDateFormatter locale= en_US ,datetype = -1 ,timetype =-1 +IntlDateFormatter locale= en_US ,datetype = -1 ,timetype =-1 Formatted localtime_array is : 21050513 07:05 AM ------------ -Input localtime is : tm_sec : '11' , tm_min : '13' , tm_hour : '0' , tm_mday : '17' , tm_mon : '11' , tm_year : '-5' , +Input localtime is : tm_sec : '11' , tm_min : '13' , tm_hour : '0' , tm_mday : '17' , tm_mon : '11' , tm_year : '-5' , ------------ -IntlDateFormatter locale= en_US ,datetype = 0 ,timetype =0 +IntlDateFormatter locale= en_US ,datetype = 0 ,timetype =0 Formatted localtime_array is : Tuesday, December 17, 1895 at 12:13:11 AM GMT-10:00 -IntlDateFormatter locale= en_US ,datetype = 1 ,timetype =1 +IntlDateFormatter locale= en_US ,datetype = 1 ,timetype =1 Formatted localtime_array is : December 17, 1895 at 12:13:11 AM GMT-10 -IntlDateFormatter locale= en_US ,datetype = 2 ,timetype =2 +IntlDateFormatter locale= en_US ,datetype = 2 ,timetype =2 Formatted localtime_array is : Dec 17, 1895, 12:13:11 AM -IntlDateFormatter locale= en_US ,datetype = 3 ,timetype =3 +IntlDateFormatter locale= en_US ,datetype = 3 ,timetype =3 Formatted localtime_array is : 12/17/95, 12:13 AM -IntlDateFormatter locale= en_US ,datetype = -1 ,timetype =-1 +IntlDateFormatter locale= en_US ,datetype = -1 ,timetype =-1 Formatted localtime_array is : 18951217 12:13 AM ------------ Date is: DateTime::__set_state(array( diff --git a/ext/mbstring/common_codepoints.txt b/ext/mbstring/common_codepoints.txt index ff528592be007..d89426cedfa27 100644 --- a/ext/mbstring/common_codepoints.txt +++ b/ext/mbstring/common_codepoints.txt @@ -4,12 +4,17 @@ 0x00A1 0x00AC # Pound sign, Yen sign, copyright sign... 0x00AE 0x00FF # Accented Latin characters 0x0104 0x0107 # Polish -0x0118 0x0119 # Polish +0x010C 0x010F # Czech +0x0118 0x011B # Polish, Czech 0x0141 0x0144 # Polish -0x015A 0x015B # Polish +0x0147 0x0148 # Czech +0x0150 0x0151 # Hungarian +0x0158 0x015B # Czech, Polish 0x0160 0x0161 # Used in Slavic names -0x0179 0x017C # Polish -0x017D 0x017E # Used in Slavic names +0x0164 0x0165 # Czech +0x016E 0x016F # Czech +0x0170 0x0171 # Hungarian +0x0179 0x017E # Polish, Czech, other Slavic languages 0x0300 0x030A # Diacritical marks 0x0370 0x0377 # Greek 0x037A 0x037F # Greek diff --git a/ext/mbstring/libmbfl/filters/mbfilter_sjis.c b/ext/mbstring/libmbfl/filters/mbfilter_sjis.c index 188f162bf8785..96456b26e7eb6 100644 --- a/ext/mbstring/libmbfl/filters/mbfilter_sjis.c +++ b/ext/mbstring/libmbfl/filters/mbfilter_sjis.c @@ -141,11 +141,7 @@ int mbfl_filt_conv_sjis_wchar(int c, mbfl_convert_filter *filter) switch (filter->status) { case 0: - if (c == 0x5C) { - CK((*filter->output_function)(0xA5, filter->data)); - } else if (c == 0x7E) { - CK((*filter->output_function)(0x203E, filter->data)); - } else if (c >= 0 && c < 0x80) { /* ASCII */ + if (c >= 0 && c < 0x80) { /* ASCII */ CK((*filter->output_function)(c, filter->data)); } else if (c > 0xA0 && c < 0xE0) { /* Kana */ CK((*filter->output_function)(0xFEC0 + c, filter->data)); @@ -197,17 +193,7 @@ int mbfl_filt_conv_wchar_sjis(int c, mbfl_convert_filter *filter) int c1, c2, s1, s2; s1 = 0; - if (c == 0x5C) { - /* Unicode 0x5C is a backslash; but Shift-JIS uses 0x5C for the - * Yen sign. JIS X 0208 kuten 0x2140 is a backslash. */ - s1 = 0x2140; - } else if (c == 0x7E) { - /* Unicode 0x7E is a tilde, but Shift-JIS uses 0x7E for overline (or - * macron). JIS X 0208 kuten 0x2141 is 'WAVE DASH' */ - s1 = 0x2141; - } else if (c == 0xAF || c == 0x203E) { /* U+00AF is MACRON, U+203E is OVERLINE */ - s1 = 0x7E; /* Halfwidth overline/macron */ - } else if (c >= ucs_a1_jis_table_min && c < ucs_a1_jis_table_max) { + if (c >= ucs_a1_jis_table_min && c < ucs_a1_jis_table_max) { s1 = ucs_a1_jis_table[c - ucs_a1_jis_table_min]; } else if (c >= ucs_a2_jis_table_min && c < ucs_a2_jis_table_max) { s1 = ucs_a2_jis_table[c - ucs_a2_jis_table_min]; @@ -218,7 +204,9 @@ int mbfl_filt_conv_wchar_sjis(int c, mbfl_convert_filter *filter) } if (s1 <= 0) { if (c == 0xA5) { /* YEN SIGN */ - s1 = 0x5C; + s1 = 0x216F; /* FULLWIDTH YEN SIGN */ + } else if (c == 0xAF || c == 0x203E) { /* U+00AF is MACRON, U+203E is OVERLINE */ + s1 = 0x2131; /* FULLWIDTH MACRON */ } else if (c == 0xFF3C) { /* FULLWIDTH REVERSE SOLIDUS */ s1 = 0x2140; } else if (c == 0xFF5E) { /* FULLWIDTH TILDE */ diff --git a/ext/mbstring/mbstring.c b/ext/mbstring/mbstring.c index 01d2877f37c49..81863d1a6eda0 100644 --- a/ext/mbstring/mbstring.c +++ b/ext/mbstring/mbstring.c @@ -161,9 +161,18 @@ static const php_mb_nls_ident_list php_mb_default_identify_list[] = { /* }}} */ +/* {{{ mbstring_deps[] */ +static const zend_module_dep mbstring_deps[] = { + ZEND_MOD_REQUIRED("pcre") + ZEND_MOD_END +}; +/* }}} */ + /* {{{ zend_module_entry mbstring_module_entry */ zend_module_entry mbstring_module_entry = { - STANDARD_MODULE_HEADER, + STANDARD_MODULE_HEADER_EX, + NULL, + mbstring_deps, "mbstring", ext_functions, PHP_MINIT(mbstring), diff --git a/ext/mbstring/rare_cp_bitvec.h b/ext/mbstring/rare_cp_bitvec.h index 10f492ab3d1b7..451c588bd64d6 100644 --- a/ext/mbstring/rare_cp_bitvec.h +++ b/ext/mbstring/rare_cp_bitvec.h @@ -11,7 +11,7 @@ static uint32_t rare_codepoint_bitvec[] = { 0xffffd9ff, 0x00000000, 0x00000000, 0x80000000, 0xffffffff, 0x00002001, 0x00000000, 0x00000000, -0xfcffff0f, 0xffffffff, 0xf3ffffe1, 0x81fffffc, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, +0xf0ff0f0f, 0xffffffff, 0xf0fcfe61, 0x81fc3fcc, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xfffff800, 0xffffffff, 0xffffffff, 0x0300ffff, 0x0000280f, 0x00000004, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, diff --git a/ext/mbstring/tests/mb_detect_encoding.phpt b/ext/mbstring/tests/mb_detect_encoding.phpt index ba88be6443afb..a9d48ee5f9488 100644 --- a/ext/mbstring/tests/mb_detect_encoding.phpt +++ b/ext/mbstring/tests/mb_detect_encoding.phpt @@ -15,6 +15,7 @@ $euc_jp = "\xC6\xFC\xCB\xDC\xB8\xEC\xA5\xC6\xA5\xAD\xA5\xB9\xA5\xC8\xA4\xC7\xA4\ // UTF-8 $polish1 = "Zażółć gęślą jaźń."; $polish2 = "Wół poszedł spać bardzo wcześnie. A to zdanie bez ogonka."; +$hungarian = "Árvíztűrő tükörfúrógép"; echo "== BASIC TEST ==\n"; @@ -233,6 +234,84 @@ test($deStrings, $deEncodings); test([$polish1, $polish2], ['UTF-32BE', 'UTF-32LE', 'UTF-16BE', 'UTF-16LE', 'UTF-8', 'ISO-8859-2']); +$czechStrings = [ + // Gotta love these Czech proverbs + // "Some like girls, others like muffins." Truer words were never spoken. + 'Bezdomovec je doma všude.', + 'Bez práce nejsou koláče.', + 'Bez peněz do hospody nelez.', + 'Bližší košile nežli kabát.', + 'Boží mlýny melou pomalu, ale jistě.', + 'Co je dovoleno pánovi, není dovoleno kmánovi.', + 'Co je šeptem, to je s čertem.', + 'Co je v domě, není pro mě.', + 'Co je v domě, to se počítá.', + 'Co jsi z úst vypustil, ani párem koní nedostaneš zpět.', + 'Co můžeš udělat dnes, neodkládej na zítřek.', + 'Co nejde po dobrým, to půjde po zlým.', + 'Co oči nevidí, to srdce nebolí (a ruce neukradnou).', + 'Co se škádlívá, to se rádo mívá.', + 'Co se v mládí naučíš, ke stáru jako když najdeš.', + 'Co sis uvařil, to si sněz.', + 'Co tě nezabije, to tě posílí.', + 'Cvik dělá mistra.', + 'Co tě nepálí, nehas.', + 'Co na srdci, to na jazyku.', + 'Co nejde silou, jde rozumem.', + 'Čas všechny rány zahojí.', + 'Častá krůpěj kámen proráží.', + 'Čím výše vystoupíš, tím hlouběji padáš.', + 'Čím výše vystoupíš, tím větší rozhled.', + 'Čiň čertu dobře, peklem se ti odmění.', + 'Čistota – půl zdraví.', + 'Dal ses na vojnu, tak bojuj.', + 'Darovanému koni na zuby nehleď.', + 'Devatero řemesel – desátá bída.', + 'Dějiny píší vítězové.', + 'Dobré slovo i železná vrata otvírá.', + 'Dočkej času jako husa klasu.', + 'Drzé čelo lepší než poplužní dvůr.', + 'Dvakrát měř, jednou řež.', + 'Důvěřuj, ale prověřuj', + 'Hlad je nejlepší kuchař.', + 'Hlad má velké oči.', + 'Hloupý, kdo dává, hloupější, kdo nebere.', + 'Hněv je špatný rádce.', + 'Někdo rád holky, jinej zas vdolky.', + 'Volům kroky a jelenům skoky.', + 'Vrána k vráně sedá, rovný rovného si hledá.', + 'Všeho nechám, už tam spěchám.', + 'Všechna sláva, polní tráva.', + 'Všeho s mírou.', + 'Všechno zlé je pro něco dobré.', + 'Všude dobře, doma nejlépe.', + 'Vrána vráně oči nevyklove.', + 'Výjimka potvrzuje pravidlo.', + 'Vzduch – boží duch.', + 'Za dobrotu na žebrotu.', + 'Zadarmo ani kuře nehrabe.', + 'Zahálky jsa služebníkem, neběduj, žes hadrníkem.', + 'Z cizího krev neteče.', + 'Zítra je taky den.', + 'Zakázané ovoce chutná nejlépe.', + 'Zlaté slovo, které zůstane v ústech.', + 'Zvyk je železná košile.', + 'Žába močál vždy najde.', + 'Žádná píseň není tak dlouhá, aby jí nebyl konec.', + 'Žádný strom neroste do nebe.', + 'Žádný učený z nebe nespadl.', + 'Žízeň je věčná.' +]; +$czechEncodings = [ + 'UTF-8', + 'UTF-16', + // 'Windows-1250', // Windows-1250 is not supported by mbstring + // 'ISO-8859-2' // We are not able to accurately distinguish UTF-8 and ISO-8859-2 +]; +test($czechStrings, $czechEncodings); + +test([$hungarian], ['UTF-8', 'UTF-16', 'Windows-1252']); + echo "Done!\n"; ?> diff --git a/ext/mbstring/tests/sjis_encoding.phpt b/ext/mbstring/tests/sjis_encoding.phpt index aece04b0f2221..c94cc464714c1 100644 --- a/ext/mbstring/tests/sjis_encoding.phpt +++ b/ext/mbstring/tests/sjis_encoding.phpt @@ -20,13 +20,37 @@ for ($i = 0; $i < 0x20; $i++) { $fromUnicode["\x00" . chr($i)] = chr($i); } -/* U+007E is TILDE; convert to Shift-JIS 0x8160 (WAVE DASH) */ -$fromUnicode["\x00\x7E"] = "\x81\x60"; +/* According to the relevant Japan Industrial Standards Committee standards, + * SJIS 0x5C is a Yen sign, and 0x7E is an overline. + * + * However, this conflicts with the implementation of SJIS in various legacy + * software (notably Microsoft products), where SJIS 0x5C and 0x7E are taken + * as equivalent to the same ASCII bytes. + * + * Prior to PHP 8.1, mbstring's implementation of SJIS handled these bytes + * compatibly with Microsoft products. This was changed in PHP 8.1.0, in an + * attempt to comply with the JISC specifications. However, after discussion + * with various concerned Japanese developers, it seems that the historical + * behavior was more useful in the majority of applications which process + * SJIS-encoded text. */ +$validChars["\x5C"] = "\x00\x5C"; +$validChars["\x7E"] = "\x00\x7E"; +$fromUnicode["\x00\x5C"] = "\x5C"; +$fromUnicode["\x00\x7E"] = "\x7E"; + +/* That means it does not make sense to convert U+203E (OVERLINE) + * to 0x7E; convert it to JIS X 0208 FULLWIDTH MACRON instead */ +$fromUnicode["\x20\x3E"] = "\x81\x50"; +/* U+00AF is MACRON; convert that to FULLWIDTH MACRON as well */ +$fromUnicode["\x00\xAF"] = "\x81\x50"; +/* Since we are treating 0x5C as equivalent to U+005C, it does not + * make sense to convert U+00A5 (YEN SIGN) to 0x5C + * Convert it to JIS X 0208 FULLWIDTH YEN SIGN instead */ +$fromUnicode["\x00\xA5"] = "\x81\x8F"; + /* DEL character */ $validChars["\x7F"] = "\x00\x7F"; $fromUnicode["\x00\x7F"] = "\x7F"; -/* U+00AF is MACRON; Shift-JIS 0x7E is overline */ -$fromUnicode["\x00\xAF"] = "\x7E"; /* Use fullwidth reverse solidus, not (halfwidth) backslash (0x5C) */ $validChars["\x81\x5F"] = "\xFF\x3C"; $fromUnicode["\xFF\x3C"] = "\x81\x5F"; diff --git a/ext/mysqli/tests/clean_table.inc b/ext/mysqli/tests/clean_table.inc index a3dc8b66debf1..229b42f5eddcc 100644 --- a/ext/mysqli/tests/clean_table.inc +++ b/ext/mysqli/tests/clean_table.inc @@ -8,7 +8,4 @@ if (!$link = my_mysqli_connect($host, $user, $passwd, $db, $port, $socket)) { if (!mysqli_query($link, 'DROP TABLE IF EXISTS test')) { printf("[clean] Failed to drop old test table: [%d] %s\n", mysqli_errno($link), mysqli_error($link)); -} - -mysqli_close($link); -?> +} \ No newline at end of file diff --git a/ext/mysqlnd/mysqlnd_charset.c b/ext/mysqlnd/mysqlnd_charset.c index a44cc0da2ee61..802822128be2e 100644 --- a/ext/mysqlnd/mysqlnd_charset.c +++ b/ext/mysqlnd/mysqlnd_charset.c @@ -188,9 +188,9 @@ static unsigned int mysqlnd_mbcharlen_utf8(const unsigned int utf8) /* {{{ big5 functions */ -#define valid_big5head(c) (0xA1 <= (unsigned int)(c) && (unsigned int)(c) <= 0xF9) -#define valid_big5tail(c) ((0x40 <= (unsigned int)(c) && (unsigned int)(c) <= 0x7E) || \ - (0xA1 <= (unsigned int)(c) && (unsigned int)(c) <= 0xFE)) +#define valid_big5head(c) (0xA1 <= (zend_uchar)(c) && (zend_uchar)(c) <= 0xF9) +#define valid_big5tail(c) ((0x40 <= (zend_uchar)(c) && (zend_uchar)(c) <= 0x7E) || \ + (0xA1 <= (zend_uchar)(c) && (zend_uchar)(c) <= 0xFE)) #define isbig5code(c,d) (isbig5head(c) && isbig5tail(d)) diff --git a/ext/mysqlnd/mysqlnd_wireprotocol.c b/ext/mysqlnd/mysqlnd_wireprotocol.c index 700fb9073746e..0c9a5138172da 100644 --- a/ext/mysqlnd/mysqlnd_wireprotocol.c +++ b/ext/mysqlnd/mysqlnd_wireprotocol.c @@ -776,7 +776,8 @@ php_mysqlnd_change_auth_response_write(MYSQLND_CONN_DATA * conn, void * _packet) MYSQLND_VIO * vio = conn->vio; MYSQLND_STATS * stats = conn->stats; MYSQLND_CONNECTION_STATE * connection_state = &conn->state; - zend_uchar * const buffer = pfc->cmd_buffer.length >= packet->auth_data_len? pfc->cmd_buffer.buffer : mnd_emalloc(packet->auth_data_len); + size_t total_packet_size = packet->auth_data_len + MYSQLND_HEADER_SIZE; + zend_uchar * const buffer = pfc->cmd_buffer.length >= total_packet_size? pfc->cmd_buffer.buffer : mnd_emalloc(total_packet_size); zend_uchar * p = buffer + MYSQLND_HEADER_SIZE; /* start after the header */ DBG_ENTER("php_mysqlnd_change_auth_response_write"); diff --git a/ext/odbc/php_odbc.c b/ext/odbc/php_odbc.c index a99785985ffc2..dd2bbd03e79b8 100644 --- a/ext/odbc/php_odbc.c +++ b/ext/odbc/php_odbc.c @@ -2167,7 +2167,8 @@ int odbc_sqlconnect(odbc_connection **conn, char *db, char *uid, char *pwd, int char *ldb = 0; int ldb_len = 0; - if (strstr((char*)db, ";")) { + /* a connection string may have = but not ; - i.e. "DSN=PHP" */ + if (strstr((char*)db, "=")) { direct = 1; if (uid && !strstr ((char*)db, "uid") && !strstr((char*)db, "UID")) { spprintf(&ldb, 0, "%s;UID=%s;PWD=%s", db, uid, pwd); diff --git a/ext/opcache/jit/zend_jit_arm64.dasc b/ext/opcache/jit/zend_jit_arm64.dasc index 0694733217b23..fdebed8f066e3 100644 --- a/ext/opcache/jit/zend_jit_arm64.dasc +++ b/ext/opcache/jit/zend_jit_arm64.dasc @@ -3660,6 +3660,16 @@ static int zend_jit_update_regs(dasm_State **Dst, uint32_t var, zend_jit_addr sr } else { ZEND_UNREACHABLE(); } + } else if (Z_MODE(dst) == IS_REG && Z_STORE(dst)) { + dst = ZEND_ADDR_MEM_ZVAL(ZREG_FP, var); + if (!zend_jit_spill_store(Dst, src, dst, info, + JIT_G(trigger) != ZEND_JIT_ON_HOT_TRACE || + JIT_G(current_frame) == NULL || + STACK_MEM_TYPE(JIT_G(current_frame)->stack, EX_VAR_TO_NUM(var)) == IS_UNKNOWN || + (1 << STACK_MEM_TYPE(JIT_G(current_frame)->stack, EX_VAR_TO_NUM(var))) != (info & MAY_BE_ANY) + )) { + return 0; + } } return 1; } @@ -5737,7 +5747,7 @@ static int zend_jit_assign_to_typed_ref(dasm_State **Dst, | // if (UNEXPECTED(EG(exception) != NULL)) { | MEM_LOAD_64_ZTS ldr, REG0, executor_globals, exception, TMP1 | cbz REG0, >8 // END OF zend_jit_assign_to_variable() - | b ->exception_handler_undef + | b ->exception_handler } else { | b >8 } @@ -8998,7 +9008,7 @@ static int zend_jit_init_method_call(dasm_State **Dst, |2: } - if (!func + if ((!func || zend_jit_may_be_modified(func, op_array)) && trace && trace->op == ZEND_JIT_TRACE_INIT_CALL && trace->func @@ -9006,7 +9016,7 @@ static int zend_jit_init_method_call(dasm_State **Dst, int32_t exit_point; const void *exit_addr; - exit_point = zend_jit_trace_get_exit_point(opline, ZEND_JIT_EXIT_METHOD_CALL); + exit_point = zend_jit_trace_get_exit_point(opline, func ? ZEND_JIT_EXIT_INVALIDATE : ZEND_JIT_EXIT_METHOD_CALL); exit_addr = zend_jit_trace_get_exit_addr(exit_point); if (!exit_addr) { return 0; diff --git a/ext/opcache/jit/zend_jit_helpers.c b/ext/opcache/jit/zend_jit_helpers.c index 0f312fb415cd9..f953d704ca090 100644 --- a/ext/opcache/jit/zend_jit_helpers.c +++ b/ext/opcache/jit/zend_jit_helpers.c @@ -811,7 +811,7 @@ static zval* ZEND_FASTCALL zend_jit_fetch_dim_rw_helper(zend_array *ht, zval *di opline = EX(opline); zend_incompatible_double_to_long_error(Z_DVAL_P(dim)); if (!(GC_FLAGS(ht) & IS_ARRAY_IMMUTABLE) && GC_DELREF(ht) != 1) { - if (GC_REFCOUNT(ht)) { + if (!GC_REFCOUNT(ht)) { zend_array_destroy(ht); } if (opline->result_type & (IS_VAR | IS_TMP_VAR)) { @@ -841,7 +841,7 @@ static zval* ZEND_FASTCALL zend_jit_fetch_dim_rw_helper(zend_array *ht, zval *di opline = EX(opline); zend_use_resource_as_offset(dim); if (!(GC_FLAGS(ht) & IS_ARRAY_IMMUTABLE) && GC_DELREF(ht) != 1) { - if (GC_REFCOUNT(ht)) { + if (!GC_REFCOUNT(ht)) { zend_array_destroy(ht); } if (opline->result_type & (IS_VAR | IS_TMP_VAR)) { diff --git a/ext/opcache/jit/zend_jit_internal.h b/ext/opcache/jit/zend_jit_internal.h index 4190b224672c9..a1b8b98baa7c7 100644 --- a/ext/opcache/jit/zend_jit_internal.h +++ b/ext/opcache/jit/zend_jit_internal.h @@ -719,6 +719,26 @@ static zend_always_inline const zend_op* zend_jit_trace_get_exit_opline(zend_jit return NULL; } +static inline bool zend_jit_may_be_modified(const zend_function *func, const zend_op_array *called_from) +{ + if (func->type == ZEND_INTERNAL_FUNCTION) { +#ifdef _WIN32 + /* ASLR */ + return 1; +#else + return 0; +#endif + } else if (func->type == ZEND_USER_FUNCTION) { + if (func->common.fn_flags & ZEND_ACC_PRELOADED) { + return 0; + } + if (func->op_array.filename == called_from->filename && !func->op_array.scope) { + return 0; + } + } + return 1; +} + static zend_always_inline bool zend_jit_may_be_polymorphic_call(const zend_op *opline) { if (opline->opcode == ZEND_INIT_FCALL diff --git a/ext/opcache/jit/zend_jit_trace.c b/ext/opcache/jit/zend_jit_trace.c index a7c5b13240d69..7c473ad78b1b9 100644 --- a/ext/opcache/jit/zend_jit_trace.c +++ b/ext/opcache/jit/zend_jit_trace.c @@ -366,26 +366,6 @@ static int zend_jit_trace_may_exit(const zend_op_array *op_array, const zend_op return 0; } -static bool zend_jit_may_be_modified(const zend_function *func, const zend_op_array *called_from) -{ - if (func->type == ZEND_INTERNAL_FUNCTION) { -#ifdef _WIN32 - /* ASLR */ - return 1; -#else - return 0; -#endif - } else if (func->type == ZEND_USER_FUNCTION) { - if (func->common.fn_flags & ZEND_ACC_PRELOADED) { - return 0; - } - if (func->op_array.filename == called_from->filename && !func->op_array.scope) { - return 0; - } - } - return 1; -} - static zend_always_inline uint32_t zend_jit_trace_type_to_info_ex(zend_uchar type, uint32_t info) { if (type == IS_UNKNOWN) { diff --git a/ext/opcache/jit/zend_jit_x86.dasc b/ext/opcache/jit/zend_jit_x86.dasc index 1515c32e211fd..3335f3cefe33e 100644 --- a/ext/opcache/jit/zend_jit_x86.dasc +++ b/ext/opcache/jit/zend_jit_x86.dasc @@ -4000,6 +4000,16 @@ static int zend_jit_update_regs(dasm_State **Dst, uint32_t var, zend_jit_addr sr } else { ZEND_UNREACHABLE(); } + } else if (Z_MODE(dst) == IS_REG && Z_STORE(dst)) { + dst = ZEND_ADDR_MEM_ZVAL(ZREG_FP, var); + if (!zend_jit_spill_store(Dst, src, dst, info, + JIT_G(trigger) != ZEND_JIT_ON_HOT_TRACE || + JIT_G(current_frame) == NULL || + STACK_MEM_TYPE(JIT_G(current_frame)->stack, EX_VAR_TO_NUM(var)) == IS_UNKNOWN || + (1 << STACK_MEM_TYPE(JIT_G(current_frame)->stack, EX_VAR_TO_NUM(var))) != (info & MAY_BE_ANY) + )) { + return 0; + } } return 1; } @@ -6256,7 +6266,7 @@ static int zend_jit_assign_to_typed_ref(dasm_State **Dst, | // if (UNEXPECTED(EG(exception) != NULL)) { | MEM_CMP_ZTS aword, executor_globals, exception, 0, r0 | je >8 // END OF zend_jit_assign_to_variable() - | jmp ->exception_handler_undef + | jmp ->exception_handler } else { | jmp >8 } @@ -9630,7 +9640,7 @@ static int zend_jit_init_method_call(dasm_State **Dst, |2: } - if (!func + if ((!func || zend_jit_may_be_modified(func, op_array)) && trace && trace->op == ZEND_JIT_TRACE_INIT_CALL && trace->func @@ -9641,7 +9651,7 @@ static int zend_jit_init_method_call(dasm_State **Dst, int32_t exit_point; const void *exit_addr; - exit_point = zend_jit_trace_get_exit_point(opline, ZEND_JIT_EXIT_METHOD_CALL); + exit_point = zend_jit_trace_get_exit_point(opline, func ? ZEND_JIT_EXIT_INVALIDATE : ZEND_JIT_EXIT_METHOD_CALL); exit_addr = zend_jit_trace_get_exit_addr(exit_point); if (!exit_addr) { return 0; diff --git a/ext/opcache/tests/jit/assign_053.phpt b/ext/opcache/tests/jit/assign_053.phpt new file mode 100644 index 0000000000000..6e785fa76f75c --- /dev/null +++ b/ext/opcache/tests/jit/assign_053.phpt @@ -0,0 +1,26 @@ +--TEST-- +JIT ASSIGN: memory leak +--INI-- +opcache.enable=1 +opcache.enable_cli=1 +opcache.file_update_protection=0 +opcache.jit_buffer_size=1M +opcache.protect_memory=1 +--FILE-- +x = " $y "; +$r = &$test->x + ($r = $y); +?> +--EXPECTF-- +Warning: Undefined variable $y in %sassign_053.php on line 6 + +Warning: Undefined variable $y in %sassign_053.php on line 7 + +Fatal error: Uncaught TypeError: Cannot assign null to reference held by property Test::$x of type string in %sassign_053.php:7 +Stack trace: +#0 {main} + thrown in %sassign_053.php on line 7 \ No newline at end of file diff --git a/ext/opcache/tests/jit/gh8591-001.inc b/ext/opcache/tests/jit/gh8591-001.inc new file mode 100644 index 0000000000000..720c41015343a --- /dev/null +++ b/ext/opcache/tests/jit/gh8591-001.inc @@ -0,0 +1,7 @@ +cast(); + } + } + + private function cast() + { + global $x; + $x = static::$field; + } +} + +new Model(); + +// mark the file as changed (important) +touch(__DIR__ . '/gh8591-001.inc'); + +var_dump($x); + +print "OK"; +--EXPECT-- +int(1) +OK diff --git a/ext/opcache/tests/jit/gh8591-002.inc b/ext/opcache/tests/jit/gh8591-002.inc new file mode 100644 index 0000000000000..720c41015343a --- /dev/null +++ b/ext/opcache/tests/jit/gh8591-002.inc @@ -0,0 +1,7 @@ +cast(); + } + } + + private function cast() + { + global $x; + $x = static::$field; + } +} + +new Model(); + +var_dump($x); + +print "OK"; +--EXPECT-- +int(1) +OK diff --git a/ext/opcache/tests/jit/gh8591-003.phpt b/ext/opcache/tests/jit/gh8591-003.phpt new file mode 100644 index 0000000000000..dc71e17dddf89 --- /dev/null +++ b/ext/opcache/tests/jit/gh8591-003.phpt @@ -0,0 +1,45 @@ +--TEST-- +Bug GH-8591 003 (JIT does not account for class re-compile) +--EXTENSIONS-- +opcache +--INI-- +opcache.enable=1 +opcache.enable_cli=1 +opcache.jit_buffer_size=1M +opcache.jit=1255 +opcache.file_update_protection=0 +opcache.revalidate_freq=0 +opcache.protect_memory=1 +--FILE-- +cast(); + } + } + + private function cast() + { + global $x; + $x = static::$field; + } +} + +new Model(); + +var_dump($x); + +print "OK"; +--EXPECT-- +int(1) +OK diff --git a/ext/opcache/tests/jit/gh8591-004.inc b/ext/opcache/tests/jit/gh8591-004.inc new file mode 100644 index 0000000000000..ae5be814d9be4 --- /dev/null +++ b/ext/opcache/tests/jit/gh8591-004.inc @@ -0,0 +1,7 @@ +cast(); + } + } + + private function cast() + { + global $x; + $x = static::$field; + } +} + +new Model(); + +// mark the file as changed (important) +touch(__DIR__ . '/gh8591-004.inc'); + +var_dump($x); + +print "OK"; +--EXPECT-- +int(1) +OK diff --git a/ext/opcache/tests/jit/gh8591-005.inc b/ext/opcache/tests/jit/gh8591-005.inc new file mode 100644 index 0000000000000..5eb8a84eee795 --- /dev/null +++ b/ext/opcache/tests/jit/gh8591-005.inc @@ -0,0 +1,12 @@ +cast(); + } + } +} + +new Model(); + +// mark the file as changed (important) +touch(__DIR__ . '/gh8591-005.inc'); + +var_dump($x); + +print "OK"; +--EXPECT-- +int(1) +OK diff --git a/ext/opcache/tests/jit/gh8591-006.inc b/ext/opcache/tests/jit/gh8591-006.inc new file mode 100644 index 0000000000000..5eb8a84eee795 --- /dev/null +++ b/ext/opcache/tests/jit/gh8591-006.inc @@ -0,0 +1,12 @@ + +--FILE-- +cast(); + } + } +} + +new Model(); + +var_dump($x); + +print "OK"; +--EXPECT-- +int(1) +OK diff --git a/ext/opcache/tests/jit/reg_alloc_015.phpt b/ext/opcache/tests/jit/reg_alloc_015.phpt new file mode 100644 index 0000000000000..579b34dadcc70 --- /dev/null +++ b/ext/opcache/tests/jit/reg_alloc_015.phpt @@ -0,0 +1,22 @@ +--TEST-- +Register Alloction 015: Missing store +--INI-- +opcache.enable=1 +opcache.enable_cli=1 +opcache.file_update_protection=0 +opcache.jit_buffer_size=1M +--FILE-- +> -$y; + } +} +foo() +?> +DONE +--EXPECTF-- +Warning: Undefined variable $y in %sreg_alloc_015.php on line 3 + +Warning: Undefined variable $y in %sreg_alloc_015.php on line 3 +DONE diff --git a/ext/opcache/tests/opt/inference_009.phpt b/ext/opcache/tests/opt/inference_009.phpt new file mode 100644 index 0000000000000..e79737777b97f --- /dev/null +++ b/ext/opcache/tests/opt/inference_009.phpt @@ -0,0 +1,18 @@ +--TEST-- +Type inference 009: FRTCH_DIM_W +--INI-- +opcache.enable=1 +opcache.enable_cli=1 +opcache.optimization_level=-1 +--FILE-- +y]; + } +} +?> +DONE +--EXPECT-- +DONE diff --git a/ext/opcache/tests/opt/inference_010.phpt b/ext/opcache/tests/opt/inference_010.phpt new file mode 100644 index 0000000000000..b07362ccfe51d --- /dev/null +++ b/ext/opcache/tests/opt/inference_010.phpt @@ -0,0 +1,18 @@ +--TEST-- +Type inference 010: FRTCH_DIM_W +--INI-- +opcache.enable=1 +opcache.enable_cli=1 +opcache.optimization_level=-1 +--FILE-- + +DONE +--EXPECTF-- +Deprecated: Automatic conversion of false to array is deprecated in %sinference_010.php on line 4 +DONE diff --git a/ext/opcache/tests/opt/inference_011.phpt b/ext/opcache/tests/opt/inference_011.phpt new file mode 100644 index 0000000000000..58f7078b61eda --- /dev/null +++ b/ext/opcache/tests/opt/inference_011.phpt @@ -0,0 +1,17 @@ +--TEST-- +Type inference 011: FETCH_DIM_FUNC_ARG +--INI-- +opcache.enable=1 +opcache.enable_cli=1 +opcache.optimization_level=-1 +--FILE-- + +DONE +--EXPECTF-- +DONE diff --git a/ext/opcache/tests/opt/inline_001.phpt b/ext/opcache/tests/opt/inline_001.phpt new file mode 100644 index 0000000000000..063f240c1a74e --- /dev/null +++ b/ext/opcache/tests/opt/inline_001.phpt @@ -0,0 +1,22 @@ +--TEST-- +Fuction inlining 001: FETCH_THIS is incompatible with unused result +--INI-- +opcache.enable=1 +opcache.enable_cli=1 +opcache.optimization_level=-1 +--FILE-- + +DONE +--EXPECT-- +DONE diff --git a/ext/openssl/openssl.c b/ext/openssl/openssl.c index 506074172a3b3..b3e62b5a75ef4 100644 --- a/ext/openssl/openssl.c +++ b/ext/openssl/openssl.c @@ -470,20 +470,107 @@ void php_openssl_store_errors() } /* }}} */ -static int ssl_stream_data_index; +/* openssl file path check error function */ +static void php_openssl_check_path_error(uint32_t arg_num, int type, const char *format, ...) +{ + va_list va; + const char *arg_name; -/* }}} */ + va_start(va, format); + + if (type == E_ERROR) { + zend_argument_error_variadic(zend_ce_value_error, arg_num, format, va); + } else { + arg_name = get_active_function_arg_name(arg_num); + php_verror(NULL, arg_name, type, format, va); + } + va_end(va); +} -/* {{{ openssl open_basedir check */ -inline static int php_openssl_open_base_dir_chk(char *filename) +/* openssl file path check extended */ +static bool php_openssl_check_path_ex( + const char *file_path, size_t file_path_len, char *real_path, uint32_t arg_num, + bool contains_file_protocol, bool is_from_array, const char *option_name) { - if (php_check_open_basedir(filename)) { - return -1; + const char *fs_file_path; + size_t fs_file_path_len; + const char *error_msg = NULL; + int error_type = E_WARNING; + + if (file_path_len == 0) { + real_path[0] = '\0'; + return true; } - return 0; + if (contains_file_protocol) { + size_t path_prefix_len = sizeof("file://") - 1; + if (file_path_len <= path_prefix_len) { + return false; + } + fs_file_path = file_path + path_prefix_len; + fs_file_path_len = file_path_len - path_prefix_len; + } else { + fs_file_path = file_path; + fs_file_path_len = file_path_len; + } + + if (CHECK_NULL_PATH(fs_file_path, fs_file_path_len)) { + error_msg = "must not contain any null bytes"; + error_type = E_ERROR; + } else if (expand_filepath(fs_file_path, real_path) == NULL) { + error_msg = "The argument must be a valid file path"; + } + + if (error_msg != NULL) { + if (arg_num == 0) { + const char *option_title = option_name ? option_name : "unknown"; + const char *option_label = is_from_array ? "array item" : "option"; + php_error_docref(NULL, E_WARNING, "Path '%s' for %s %s %s", + real_path, option_title, option_label, error_msg); + } else if (is_from_array && option_name != NULL) { + php_openssl_check_path_error( + arg_num, error_type, "option %s array item %s", option_name, error_msg); + } else if (is_from_array) { + php_openssl_check_path_error(arg_num, error_type, "array item %s", error_msg); + } else if (option_name != NULL) { + php_openssl_check_path_error( + arg_num, error_type, "option %s %s", option_name, error_msg); + } else { + php_openssl_check_path_error(arg_num, error_type, "%s", error_msg); + } + } else if (!php_check_open_basedir(real_path)) { + return true; + } + + return false; } -/* }}} */ + +/* openssl file path check */ +static inline bool php_openssl_check_path( + const char *file_path, size_t file_path_len, char *real_path, uint32_t arg_num) +{ + return php_openssl_check_path_ex( + file_path, file_path_len, real_path, arg_num, false, false, NULL); +} + +/* openssl file path extra check with zend string */ +static inline bool php_openssl_check_path_str_ex( + zend_string *file_path, char *real_path, uint32_t arg_num, + bool contains_file_protocol, bool is_from_array, const char *option_name) +{ + return php_openssl_check_path_ex( + ZSTR_VAL(file_path), ZSTR_LEN(file_path), real_path, arg_num, contains_file_protocol, + is_from_array, option_name); +} + +/* openssl file path check with zend string */ +static inline bool php_openssl_check_path_str( + zend_string *file_path, char *real_path, uint32_t arg_num) +{ + return php_openssl_check_path_str_ex(file_path, real_path, arg_num, true, false, NULL); +} + +static int ssl_stream_data_index; php_stream* php_openssl_get_stream_from_ssl_handle(const SSL *ssl) { @@ -524,13 +611,18 @@ struct php_x509_request { /* {{{ */ }; /* }}} */ -static X509 *php_openssl_x509_from_param(zend_object *cert_obj, zend_string *cert_str); -static X509 *php_openssl_x509_from_zval(zval *val, bool *free_cert); -static X509_REQ *php_openssl_csr_from_param(zend_object *csr_obj, zend_string *csr_str); -static EVP_PKEY *php_openssl_pkey_from_zval(zval *val, int public_key, char *passphrase, size_t passphrase_len); - -static X509_STORE * php_openssl_setup_verify(zval * calist); -static STACK_OF(X509) * php_openssl_load_all_certs_from_file(char *certfile); +static X509 *php_openssl_x509_from_param( + zend_object *cert_obj, zend_string *cert_str, uint32_t arg_num); +static X509 *php_openssl_x509_from_zval( + zval *val, bool *free_cert, uint32_t arg_num, bool is_from_array, const char *option_name); +static X509_REQ *php_openssl_csr_from_param( + zend_object *csr_obj, zend_string *csr_str, uint32_t arg_num); +static EVP_PKEY *php_openssl_pkey_from_zval( + zval *val, int public_key, char *passphrase, size_t passphrase_len, uint32_t arg_num); + +static X509_STORE * php_openssl_setup_verify(zval * calist, uint32_t arg_num); +static STACK_OF(X509) * php_openssl_load_all_certs_from_file( + char *cert_file, size_t cert_file_len, uint32_t arg_num); static EVP_PKEY * php_openssl_generate_private_key(struct php_x509_request * req); static void php_openssl_add_assoc_name_entry(zval * val, char * key, X509_NAME * name, int shortname) /* {{{ */ @@ -825,7 +917,7 @@ static int php_openssl_spki_cleanup(const char *src, char *dest) static int php_openssl_parse_config(struct php_x509_request * req, zval * optional_args) /* {{{ */ { - char * str; + char * str, path[MAXPATHLEN]; zval * item; SET_OPTIONAL_STRING_ARG("config", req->config_filename, default_ssl_conf_filename); @@ -842,8 +934,8 @@ static int php_openssl_parse_config(struct php_x509_request * req, zval * option /* read in the oids */ str = php_openssl_conf_get_string(req->req_config, NULL, "oid_file"); - if (str != NULL && !php_openssl_open_base_dir_chk(str)) { - BIO *oid_bio = BIO_new_file(str, PHP_OPENSSL_BIO_MODE_R(PKCS7_BINARY)); + if (str != NULL && php_openssl_check_path_ex(str, strlen(str), path, 0, false, false, "oid_file")) { + BIO *oid_bio = BIO_new_file(path, PHP_OPENSSL_BIO_MODE_R(PKCS7_BINARY)); if (oid_bio) { OBJ_create_objects(oid_bio); BIO_free(oid_bio); @@ -1397,16 +1489,18 @@ PHP_FUNCTION(openssl_get_cert_locations) } /* }}} */ -static X509 *php_openssl_x509_from_str(zend_string *cert_str) { +static X509 *php_openssl_x509_from_str( + zend_string *cert_str, uint32_t arg_num, bool is_from_array, const char *option_name) { X509 *cert = NULL; + char cert_path[MAXPATHLEN]; BIO *in; if (ZSTR_LEN(cert_str) > 7 && memcmp(ZSTR_VAL(cert_str), "file://", sizeof("file://") - 1) == 0) { - if (php_openssl_open_base_dir_chk(ZSTR_VAL(cert_str) + (sizeof("file://") - 1))) { + if (!php_openssl_check_path_str_ex(cert_str, cert_path, arg_num, true, is_from_array, option_name)) { return NULL; } - in = BIO_new_file(ZSTR_VAL(cert_str) + (sizeof("file://") - 1), PHP_OPENSSL_BIO_MODE_R(PKCS7_BINARY)); + in = BIO_new_file(cert_path, PHP_OPENSSL_BIO_MODE_R(PKCS7_BINARY)); if (in == NULL) { php_openssl_store_errors(); return NULL; @@ -1444,18 +1538,20 @@ static X509 *php_openssl_x509_from_str(zend_string *cert_str) { . a path to that cert if it starts with file:// . the cert data otherwise */ -static X509 *php_openssl_x509_from_param(zend_object *cert_obj, zend_string *cert_str) { +static X509 *php_openssl_x509_from_param( + zend_object *cert_obj, zend_string *cert_str, uint32_t arg_num) { if (cert_obj) { return php_openssl_certificate_from_obj(cert_obj)->x509; } ZEND_ASSERT(cert_str); - return php_openssl_x509_from_str(cert_str); + return php_openssl_x509_from_str(cert_str, arg_num, false, NULL); } /* }}} */ -static X509 *php_openssl_x509_from_zval(zval *val, bool *free_cert) +static X509 *php_openssl_x509_from_zval( + zval *val, bool *free_cert, uint32_t arg_num, bool is_from_array, const char *option_name) { if (Z_TYPE_P(val) == IS_OBJECT && Z_OBJCE_P(val) == php_openssl_certificate_ce) { *free_cert = 0; @@ -1469,7 +1565,7 @@ static X509 *php_openssl_x509_from_zval(zval *val, bool *free_cert) return NULL; } - return php_openssl_x509_from_str(Z_STR_P(val)); + return php_openssl_x509_from_str(Z_STR_P(val), arg_num, is_from_array, option_name); } /* }}} */ @@ -1482,7 +1578,7 @@ PHP_FUNCTION(openssl_x509_export_to_file) bool notext = 1; BIO * bio_out; - char * filename; + char * filename, file_path[MAXPATHLEN]; size_t filename_len; ZEND_PARSE_PARAMETERS_START(2, 3) @@ -1494,17 +1590,17 @@ PHP_FUNCTION(openssl_x509_export_to_file) RETVAL_FALSE; - cert = php_openssl_x509_from_param(cert_obj, cert_str); + cert = php_openssl_x509_from_param(cert_obj, cert_str, 1); if (cert == NULL) { php_error_docref(NULL, E_WARNING, "X.509 Certificate cannot be retrieved"); return; } - if (php_openssl_open_base_dir_chk(filename)) { + if (!php_openssl_check_path(filename, filename_len, file_path, 2)) { return; } - bio_out = BIO_new_file(filename, PHP_OPENSSL_BIO_MODE_W(PKCS7_BINARY)); + bio_out = BIO_new_file(file_path, PHP_OPENSSL_BIO_MODE_W(PKCS7_BINARY)); if (bio_out) { if (!notext && !X509_print(bio_out, cert)) { php_openssl_store_errors(); @@ -1516,7 +1612,7 @@ PHP_FUNCTION(openssl_x509_export_to_file) RETVAL_TRUE; } else { php_openssl_store_errors(); - php_error_docref(NULL, E_WARNING, "Error opening file %s", filename); + php_error_docref(NULL, E_WARNING, "Error opening file %s", file_path); } if (cert_str) { @@ -1551,7 +1647,7 @@ PHP_FUNCTION(openssl_spki_new) PHP_OPENSSL_CHECK_SIZE_T_TO_INT(challenge_len, challenge, 2); - pkey = php_openssl_pkey_from_zval(zpkey, 0, challenge, challenge_len); + pkey = php_openssl_pkey_from_zval(zpkey, 0, challenge, challenge_len, 1); if (pkey == NULL) { if (!EG(exception)) { php_error_docref(NULL, E_WARNING, "Unable to use supplied private key"); @@ -1802,7 +1898,7 @@ PHP_FUNCTION(openssl_x509_export) RETVAL_FALSE; - cert = php_openssl_x509_from_param(cert_obj, cert_str); + cert = php_openssl_x509_from_param(cert_obj, cert_str, 1); if (cert == NULL) { php_error_docref(NULL, E_WARNING, "X.509 Certificate cannot be retrieved"); return; @@ -1880,7 +1976,7 @@ PHP_FUNCTION(openssl_x509_fingerprint) Z_PARAM_BOOL(raw_output) ZEND_PARSE_PARAMETERS_END(); - cert = php_openssl_x509_from_param(cert_obj, cert_str); + cert = php_openssl_x509_from_param(cert_obj, cert_str, 1); if (cert == NULL) { php_error_docref(NULL, E_WARNING, "X.509 Certificate cannot be retrieved"); RETURN_FALSE; @@ -1912,14 +2008,14 @@ PHP_FUNCTION(openssl_x509_check_private_key) Z_PARAM_ZVAL(zkey) ZEND_PARSE_PARAMETERS_END(); - cert = php_openssl_x509_from_param(cert_obj, cert_str); + cert = php_openssl_x509_from_param(cert_obj, cert_str, 1); if (cert == NULL) { RETURN_FALSE; } RETVAL_FALSE; - key = php_openssl_pkey_from_zval(zkey, 0, "", 0); + key = php_openssl_pkey_from_zval(zkey, 0, "", 0, 2); if (key) { RETVAL_BOOL(X509_check_private_key(cert, key)); EVP_PKEY_free(key); @@ -1946,12 +2042,12 @@ PHP_FUNCTION(openssl_x509_verify) Z_PARAM_ZVAL(zkey) ZEND_PARSE_PARAMETERS_END(); - cert = php_openssl_x509_from_param(cert_obj, cert_str); + cert = php_openssl_x509_from_param(cert_obj, cert_str, 1); if (cert == NULL) { RETURN_LONG(err); } - key = php_openssl_pkey_from_zval(zkey, 1, NULL, 0); + key = php_openssl_pkey_from_zval(zkey, 1, NULL, 0, 2); if (key != NULL) { err = X509_verify(cert, key); if (err < 0) { @@ -2068,7 +2164,7 @@ PHP_FUNCTION(openssl_x509_parse) Z_PARAM_BOOL(useshortnames) ZEND_PARSE_PARAMETERS_END(); - cert = php_openssl_x509_from_param(cert_obj, cert_str); + cert = php_openssl_x509_from_param(cert_obj, cert_str, 1); if (cert == NULL) { // TODO Add Warning? RETURN_FALSE; @@ -2208,12 +2304,14 @@ PHP_FUNCTION(openssl_x509_parse) /* }}} */ /* {{{ php_openssl_load_all_certs_from_file */ -static STACK_OF(X509) *php_openssl_load_all_certs_from_file(char *certfile) +static STACK_OF(X509) *php_openssl_load_all_certs_from_file( + char *cert_file, size_t cert_file_len, uint32_t arg_num) { STACK_OF(X509_INFO) *sk=NULL; STACK_OF(X509) *stack=NULL, *ret=NULL; BIO *in=NULL; X509_INFO *xi; + char cert_path[MAXPATHLEN]; if(!(stack = sk_X509_new_null())) { php_openssl_store_errors(); @@ -2221,22 +2319,22 @@ static STACK_OF(X509) *php_openssl_load_all_certs_from_file(char *certfile) goto end; } - if (php_openssl_open_base_dir_chk(certfile)) { + if (!php_openssl_check_path(cert_file, cert_file_len, cert_path, arg_num)) { sk_X509_free(stack); goto end; } - if (!(in=BIO_new_file(certfile, PHP_OPENSSL_BIO_MODE_R(PKCS7_BINARY)))) { + if (!(in = BIO_new_file(cert_path, PHP_OPENSSL_BIO_MODE_R(PKCS7_BINARY)))) { php_openssl_store_errors(); - php_error_docref(NULL, E_WARNING, "Error opening the file, %s", certfile); + php_error_docref(NULL, E_WARNING, "Error opening the file, %s", cert_path); sk_X509_free(stack); goto end; } /* This loads from a file, a stack of x509/crl/pkey sets */ - if (!(sk=PEM_X509_INFO_read_bio(in, NULL, NULL, NULL))) { + if (!(sk = PEM_X509_INFO_read_bio(in, NULL, NULL, NULL))) { php_openssl_store_errors(); - php_error_docref(NULL, E_WARNING, "Error reading the file, %s", certfile); + php_error_docref(NULL, E_WARNING, "Error reading the file, %s", cert_path); sk_X509_free(stack); goto end; } @@ -2251,7 +2349,7 @@ static STACK_OF(X509) *php_openssl_load_all_certs_from_file(char *certfile) X509_INFO_free(xi); } if (!sk_X509_num(stack)) { - php_error_docref(NULL, E_WARNING, "No certificates in file, %s", certfile); + php_error_docref(NULL, E_WARNING, "No certificates in file, %s", cert_path); sk_X509_free(stack); goto end; } @@ -2319,17 +2417,17 @@ PHP_FUNCTION(openssl_x509_checkpurpose) RETVAL_LONG(-1); if (untrusted) { - untrustedchain = php_openssl_load_all_certs_from_file(untrusted); + untrustedchain = php_openssl_load_all_certs_from_file(untrusted, untrusted_len, 4); if (untrustedchain == NULL) { goto clean_exit; } } - cainfo = php_openssl_setup_verify(zcainfo); + cainfo = php_openssl_setup_verify(zcainfo, 3); if (cainfo == NULL) { goto clean_exit; } - cert = php_openssl_x509_from_param(cert_obj, cert_str); + cert = php_openssl_x509_from_param(cert_obj, cert_str, 1); if (cert == NULL) { // TODO Add Warning? goto clean_exit; @@ -2358,13 +2456,14 @@ PHP_FUNCTION(openssl_x509_checkpurpose) * calist is an array containing file and directory names. create a * certificate store and add those certs to it for use in verification. */ -static X509_STORE *php_openssl_setup_verify(zval *calist) +static X509_STORE *php_openssl_setup_verify(zval *calist, uint32_t arg_num) { X509_STORE *store; X509_LOOKUP * dir_lookup, * file_lookup; int ndirs = 0, nfiles = 0; zval * item; zend_stat_t sb; + char file_path[MAXPATHLEN]; store = X509_STORE_new(); @@ -2380,32 +2479,36 @@ static X509_STORE *php_openssl_setup_verify(zval *calist) return NULL; } - if (VCWD_STAT(ZSTR_VAL(str), &sb) == -1) { - php_error_docref(NULL, E_WARNING, "Unable to stat %s", ZSTR_VAL(str)); + if (!php_openssl_check_path_str_ex(str, file_path, arg_num, false, true, NULL)) { zend_string_release(str); continue; } + zend_string_release(str); + + if (VCWD_STAT(file_path, &sb) == -1) { + php_error_docref(NULL, E_WARNING, "Unable to stat %s", file_path); + continue; + } if ((sb.st_mode & S_IFREG) == S_IFREG) { file_lookup = X509_STORE_add_lookup(store, X509_LOOKUP_file()); - if (file_lookup == NULL || !X509_LOOKUP_load_file(file_lookup, ZSTR_VAL(str), X509_FILETYPE_PEM)) { + if (file_lookup == NULL || !X509_LOOKUP_load_file(file_lookup, file_path, X509_FILETYPE_PEM)) { php_openssl_store_errors(); - php_error_docref(NULL, E_WARNING, "Error loading file %s", ZSTR_VAL(str)); + php_error_docref(NULL, E_WARNING, "Error loading file %s", file_path); } else { nfiles++; } file_lookup = NULL; } else { dir_lookup = X509_STORE_add_lookup(store, X509_LOOKUP_hash_dir()); - if (dir_lookup == NULL || !X509_LOOKUP_add_dir(dir_lookup, ZSTR_VAL(str), X509_FILETYPE_PEM)) { + if (dir_lookup == NULL || !X509_LOOKUP_add_dir(dir_lookup, file_path, X509_FILETYPE_PEM)) { php_openssl_store_errors(); - php_error_docref(NULL, E_WARNING, "Error loading directory %s", ZSTR_VAL(str)); + php_error_docref(NULL, E_WARNING, "Error loading directory %s", file_path); } else { ndirs++; } dir_lookup = NULL; } - zend_string_release(str); } ZEND_HASH_FOREACH_END(); } if (nfiles == 0) { @@ -2436,7 +2539,7 @@ PHP_FUNCTION(openssl_x509_read) Z_PARAM_OBJ_OF_CLASS_OR_STR(cert_obj, php_openssl_certificate_ce, cert_str) ZEND_PARSE_PARAMETERS_END(); - cert = php_openssl_x509_from_param(cert_obj, cert_str); + cert = php_openssl_x509_from_param(cert_obj, cert_str, 1); if (cert == NULL) { php_error_docref(NULL, E_WARNING, "X.509 Certificate cannot be retrieved"); RETURN_FALSE; @@ -2473,7 +2576,7 @@ static void php_sk_X509_free(STACK_OF(X509) * sk) /* {{{ */ } /* }}} */ -static STACK_OF(X509) * php_array_to_X509_sk(zval * zcerts) /* {{{ */ +static STACK_OF(X509) *php_array_to_X509_sk(zval * zcerts, uint32_t arg_num, const char *option_name) /* {{{ */ { zval * zcertval; STACK_OF(X509) * sk = NULL; @@ -2485,7 +2588,7 @@ static STACK_OF(X509) * php_array_to_X509_sk(zval * zcerts) /* {{{ */ /* get certs */ if (Z_TYPE_P(zcerts) == IS_ARRAY) { ZEND_HASH_FOREACH_VAL(Z_ARRVAL_P(zcerts), zcertval) { - cert = php_openssl_x509_from_zval(zcertval, &free_cert); + cert = php_openssl_x509_from_zval(zcertval, &free_cert, arg_num, true, option_name); if (cert == NULL) { // TODO Add Warning? goto clean_exit; @@ -2504,7 +2607,7 @@ static STACK_OF(X509) * php_array_to_X509_sk(zval * zcerts) /* {{{ */ } ZEND_HASH_FOREACH_END(); } else { /* a single certificate */ - cert = php_openssl_x509_from_zval(zcerts, &free_cert); + cert = php_openssl_x509_from_zval(zcerts, &free_cert, arg_num, false, option_name); if (cert == NULL) { // TODO Add Warning? @@ -2534,7 +2637,7 @@ PHP_FUNCTION(openssl_pkcs12_export_to_file) zend_string *cert_str; BIO * bio_out = NULL; PKCS12 * p12 = NULL; - char * filename; + char * filename, file_path[MAXPATHLEN]; char * friendly_name = NULL; size_t filename_len; char * pass; @@ -2555,13 +2658,13 @@ PHP_FUNCTION(openssl_pkcs12_export_to_file) RETVAL_FALSE; - cert = php_openssl_x509_from_param(cert_obj, cert_str); + cert = php_openssl_x509_from_param(cert_obj, cert_str, 1); if (cert == NULL) { php_error_docref(NULL, E_WARNING, "X.509 Certificate cannot be retrieved"); return; } - priv_key = php_openssl_pkey_from_zval(zpkey, 0, "", 0); + priv_key = php_openssl_pkey_from_zval(zpkey, 0, "", 0, 3); if (priv_key == NULL) { if (!EG(exception)) { php_error_docref(NULL, E_WARNING, "Cannot get private key from parameter 3"); @@ -2573,7 +2676,7 @@ PHP_FUNCTION(openssl_pkcs12_export_to_file) php_error_docref(NULL, E_WARNING, "Private key does not correspond to cert"); goto cleanup; } - if (php_openssl_open_base_dir_chk(filename)) { + if (!php_openssl_check_path(filename, filename_len, file_path, 2)) { goto cleanup; } @@ -2590,7 +2693,7 @@ PHP_FUNCTION(openssl_pkcs12_export_to_file) */ if (args && (item = zend_hash_str_find(Z_ARRVAL_P(args), "extracerts", sizeof("extracerts")-1)) != NULL) { - ca = php_array_to_X509_sk(item); + ca = php_array_to_X509_sk(item, 5, "extracerts"); } /* end parse extra config */ @@ -2599,7 +2702,7 @@ PHP_FUNCTION(openssl_pkcs12_export_to_file) p12 = PKCS12_create(pass, friendly_name, priv_key, cert, ca, 0, 0, 0, 0, 0); if (p12 != NULL) { - bio_out = BIO_new_file(filename, PHP_OPENSSL_BIO_MODE_W(PKCS7_BINARY)); + bio_out = BIO_new_file(file_path, PHP_OPENSSL_BIO_MODE_W(PKCS7_BINARY)); if (bio_out != NULL) { i2d_PKCS12_bio(bio_out, p12); @@ -2608,7 +2711,7 @@ PHP_FUNCTION(openssl_pkcs12_export_to_file) RETVAL_TRUE; } else { php_openssl_store_errors(); - php_error_docref(NULL, E_WARNING, "Error opening file %s", filename); + php_error_docref(NULL, E_WARNING, "Error opening file %s", file_path); } PKCS12_free(p12); @@ -2654,13 +2757,13 @@ PHP_FUNCTION(openssl_pkcs12_export) RETVAL_FALSE; - cert = php_openssl_x509_from_param(cert_obj, cert_str); + cert = php_openssl_x509_from_param(cert_obj, cert_str, 1); if (cert == NULL) { php_error_docref(NULL, E_WARNING, "X.509 Certificate cannot be retrieved"); return; } - priv_key = php_openssl_pkey_from_zval(zpkey, 0, "", 0); + priv_key = php_openssl_pkey_from_zval(zpkey, 0, "", 0, 3); if (priv_key == NULL) { if (!EG(exception)) { php_error_docref(NULL, E_WARNING, "Cannot get private key from parameter 3"); @@ -2681,7 +2784,7 @@ PHP_FUNCTION(openssl_pkcs12_export) } if (args && (item = zend_hash_str_find(Z_ARRVAL_P(args), "extracerts", sizeof("extracerts")-1)) != NULL) { - ca = php_array_to_X509_sk(item); + ca = php_array_to_X509_sk(item, 5, "extracerts"); } /* end parse extra config */ @@ -2991,21 +3094,17 @@ static int php_openssl_make_REQ(struct php_x509_request * req, X509_REQ * csr, z /* }}} */ -static X509_REQ *php_openssl_csr_from_str(zend_string *csr_str) +static X509_REQ *php_openssl_csr_from_str(zend_string *csr_str, uint32_t arg_num) { X509_REQ * csr = NULL; - char * filename = NULL; + char file_path[MAXPATHLEN]; BIO * in; if (ZSTR_LEN(csr_str) > 7 && memcmp(ZSTR_VAL(csr_str), "file://", sizeof("file://") - 1) == 0) { - filename = ZSTR_VAL(csr_str) + (sizeof("file://") - 1); - } - - if (filename) { - if (php_openssl_open_base_dir_chk(filename)) { + if (!php_openssl_check_path_str(csr_str, file_path, arg_num)) { return NULL; } - in = BIO_new_file(filename, PHP_OPENSSL_BIO_MODE_R(PKCS7_BINARY)); + in = BIO_new_file(file_path, PHP_OPENSSL_BIO_MODE_R(PKCS7_BINARY)); } else { in = BIO_new_mem_buf(ZSTR_VAL(csr_str), (int) ZSTR_LEN(csr_str)); } @@ -3025,7 +3124,8 @@ static X509_REQ *php_openssl_csr_from_str(zend_string *csr_str) return csr; } -static X509_REQ *php_openssl_csr_from_param(zend_object *csr_obj, zend_string *csr_str) +static X509_REQ *php_openssl_csr_from_param( + zend_object *csr_obj, zend_string *csr_str, uint32_t arg_num) { if (csr_obj) { return php_openssl_request_from_obj(csr_obj)->csr; @@ -3033,7 +3133,7 @@ static X509_REQ *php_openssl_csr_from_param(zend_object *csr_obj, zend_string *c ZEND_ASSERT(csr_str); - return php_openssl_csr_from_str(csr_str); + return php_openssl_csr_from_str(csr_str, arg_num); } /* {{{ Exports a CSR to file */ @@ -3045,6 +3145,7 @@ PHP_FUNCTION(openssl_csr_export_to_file) bool notext = 1; char * filename = NULL; size_t filename_len; + char file_path[MAXPATHLEN]; BIO * bio_out; ZEND_PARSE_PARAMETERS_START(2, 3) @@ -3056,23 +3157,23 @@ PHP_FUNCTION(openssl_csr_export_to_file) RETVAL_FALSE; - csr = php_openssl_csr_from_param(csr_obj, csr_str); + csr = php_openssl_csr_from_param(csr_obj, csr_str, 1); if (csr == NULL) { php_error_docref(NULL, E_WARNING, "X.509 Certificate Signing Request cannot be retrieved"); return; } - if (php_openssl_open_base_dir_chk(filename)) { + if (!php_openssl_check_path(filename, filename_len, file_path, 2)) { return; } - bio_out = BIO_new_file(filename, PHP_OPENSSL_BIO_MODE_W(PKCS7_BINARY)); + bio_out = BIO_new_file(file_path, PHP_OPENSSL_BIO_MODE_W(PKCS7_BINARY)); if (bio_out != NULL) { if (!notext && !X509_REQ_print(bio_out, csr)) { php_openssl_store_errors(); } if (!PEM_write_bio_X509_REQ(bio_out, csr)) { - php_error_docref(NULL, E_WARNING, "Error writing PEM to file %s", filename); + php_error_docref(NULL, E_WARNING, "Error writing PEM to file %s", file_path); php_openssl_store_errors(); } else { RETVAL_TRUE; @@ -3080,7 +3181,7 @@ PHP_FUNCTION(openssl_csr_export_to_file) BIO_free(bio_out); } else { php_openssl_store_errors(); - php_error_docref(NULL, E_WARNING, "Error opening file %s", filename); + php_error_docref(NULL, E_WARNING, "Error opening file %s", file_path); } if (csr_str) { @@ -3108,7 +3209,7 @@ PHP_FUNCTION(openssl_csr_export) RETVAL_FALSE; - csr = php_openssl_csr_from_param(csr_obj, csr_str); + csr = php_openssl_csr_from_param(csr_obj, csr_str, 1); if (csr == NULL) { php_error_docref(NULL, E_WARNING, "X.509 Certificate Signing Request cannot be retrieved"); return; @@ -3169,7 +3270,7 @@ PHP_FUNCTION(openssl_csr_sign) RETVAL_FALSE; - csr = php_openssl_csr_from_param(csr_obj, csr_str); + csr = php_openssl_csr_from_param(csr_obj, csr_str, 1); if (csr == NULL) { php_error_docref(NULL, E_WARNING, "X.509 Certificate Signing Request cannot be retrieved"); return; @@ -3178,14 +3279,14 @@ PHP_FUNCTION(openssl_csr_sign) PHP_SSL_REQ_INIT(&req); if (cert_str || cert_obj) { - cert = php_openssl_x509_from_param(cert_obj, cert_str); + cert = php_openssl_x509_from_param(cert_obj, cert_str, 2); if (cert == NULL) { php_error_docref(NULL, E_WARNING, "X.509 Certificate cannot be retrieved"); goto cleanup; } } - priv_key = php_openssl_pkey_from_zval(zpkey, 0, "", 0); + priv_key = php_openssl_pkey_from_zval(zpkey, 0, "", 0, 3); if (priv_key == NULL) { if (!EG(exception)) { php_error_docref(NULL, E_WARNING, "Cannot get private key from parameter 3"); @@ -3318,7 +3419,7 @@ PHP_FUNCTION(openssl_csr_new) /* Generate or use a private key */ if (Z_TYPE_P(out_pkey_val) != IS_NULL) { - req.priv_key = php_openssl_pkey_from_zval(out_pkey_val, 0, NULL, 0); + req.priv_key = php_openssl_pkey_from_zval(out_pkey_val, 0, NULL, 0, 2); } if (req.priv_key == NULL) { php_openssl_generate_private_key(&req); @@ -3392,7 +3493,7 @@ PHP_FUNCTION(openssl_csr_get_subject) Z_PARAM_BOOL(use_shortnames) ZEND_PARSE_PARAMETERS_END(); - csr = php_openssl_csr_from_param(csr_obj, csr_str); + csr = php_openssl_csr_from_param(csr_obj, csr_str, 1); if (csr == NULL) { RETURN_FALSE; } @@ -3435,7 +3536,7 @@ PHP_FUNCTION(openssl_csr_get_public_key) Z_PARAM_BOOL(use_shortnames) ZEND_PARSE_PARAMETERS_END(); - X509_REQ *csr = php_openssl_csr_from_param(csr_obj, csr_str); + X509_REQ *csr = php_openssl_csr_from_param(csr_obj, csr_str, 1); if (csr == NULL) { RETURN_FALSE; } @@ -3484,12 +3585,13 @@ static int php_openssl_pem_password_cb(char *buf, int size, int rwflag, void *us } /* }}} */ -static EVP_PKEY *php_openssl_pkey_from_zval(zval *val, int public_key, char *passphrase, size_t passphrase_len) +static EVP_PKEY *php_openssl_pkey_from_zval( + zval *val, int public_key, char *passphrase, size_t passphrase_len, uint32_t arg_num) { EVP_PKEY *key = NULL; X509 *cert = NULL; - bool free_cert = 0; - char * filename = NULL; + bool free_cert = false, is_file = false; + char file_path[MAXPATHLEN]; zval tmp; ZVAL_NULL(&tmp); @@ -3567,22 +3669,22 @@ static EVP_PKEY *php_openssl_pkey_from_zval(zval *val, int public_key, char *pas } if (Z_STRLEN_P(val) > 7 && memcmp(Z_STRVAL_P(val), "file://", sizeof("file://") - 1) == 0) { - filename = Z_STRVAL_P(val) + (sizeof("file://") - 1); - if (php_openssl_open_base_dir_chk(filename)) { + if (!php_openssl_check_path_str(Z_STR_P(val), file_path, arg_num)) { TMP_CLEAN; } + is_file = true; } /* it's an X509 file/cert of some kind, and we need to extract the data from that */ if (public_key) { - cert = php_openssl_x509_from_str(Z_STR_P(val)); + cert = php_openssl_x509_from_str(Z_STR_P(val), arg_num, false, NULL); if (cert) { free_cert = 1; } else { /* not a X509 certificate, try to retrieve public key */ BIO* in; - if (filename) { - in = BIO_new_file(filename, PHP_OPENSSL_BIO_MODE_R(PKCS7_BINARY)); + if (is_file) { + in = BIO_new_file(file_path, PHP_OPENSSL_BIO_MODE_R(PKCS7_BINARY)); } else { in = BIO_new_mem_buf(Z_STRVAL_P(val), (int)Z_STRLEN_P(val)); } @@ -3597,8 +3699,8 @@ static EVP_PKEY *php_openssl_pkey_from_zval(zval *val, int public_key, char *pas /* we want the private key */ BIO *in; - if (filename) { - in = BIO_new_file(filename, PHP_OPENSSL_BIO_MODE_R(PKCS7_BINARY)); + if (is_file) { + in = BIO_new_file(file_path, PHP_OPENSSL_BIO_MODE_R(PKCS7_BINARY)); } else { in = BIO_new_mem_buf(Z_STRVAL_P(val), (int)Z_STRLEN_P(val)); } @@ -4523,7 +4625,7 @@ PHP_FUNCTION(openssl_pkey_export_to_file) zval * zpkey, * args = NULL; char * passphrase = NULL; size_t passphrase_len = 0; - char * filename = NULL; + char * filename = NULL, file_path[MAXPATHLEN]; size_t filename_len = 0; int pem_write = 0; EVP_PKEY * key; @@ -4537,7 +4639,7 @@ PHP_FUNCTION(openssl_pkey_export_to_file) PHP_OPENSSL_CHECK_SIZE_T_TO_INT(passphrase_len, passphrase, 3); - key = php_openssl_pkey_from_zval(zpkey, 0, passphrase, passphrase_len); + key = php_openssl_pkey_from_zval(zpkey, 0, passphrase, passphrase_len, 1); if (key == NULL) { if (!EG(exception)) { php_error_docref(NULL, E_WARNING, "Cannot get key from parameter 1"); @@ -4545,14 +4647,14 @@ PHP_FUNCTION(openssl_pkey_export_to_file) RETURN_FALSE; } - if (php_openssl_open_base_dir_chk(filename)) { + if (!php_openssl_check_path(filename, filename_len, file_path, 2)) { RETURN_FALSE; } PHP_SSL_REQ_INIT(&req); if (PHP_SSL_REQ_PARSE(&req, args) == SUCCESS) { - bio_out = BIO_new_file(filename, PHP_OPENSSL_BIO_MODE_W(PKCS7_BINARY)); + bio_out = BIO_new_file(file_path, PHP_OPENSSL_BIO_MODE_W(PKCS7_BINARY)); if (bio_out == NULL) { php_openssl_store_errors(); goto clean_exit; @@ -4605,7 +4707,7 @@ PHP_FUNCTION(openssl_pkey_export) PHP_OPENSSL_CHECK_SIZE_T_TO_INT(passphrase_len, passphrase, 3); - key = php_openssl_pkey_from_zval(zpkey, 0, passphrase, passphrase_len); + key = php_openssl_pkey_from_zval(zpkey, 0, passphrase, passphrase_len, 1); if (key == NULL) { if (!EG(exception)) { php_error_docref(NULL, E_WARNING, "Cannot get key from parameter 1"); @@ -4660,7 +4762,7 @@ PHP_FUNCTION(openssl_pkey_get_public) if (zend_parse_parameters(ZEND_NUM_ARGS(), "z", &cert) == FAILURE) { RETURN_THROWS(); } - pkey = php_openssl_pkey_from_zval(cert, 1, NULL, 0); + pkey = php_openssl_pkey_from_zval(cert, 1, NULL, 0, 1); if (pkey == NULL) { RETURN_FALSE; } @@ -4696,7 +4798,7 @@ PHP_FUNCTION(openssl_pkey_get_private) PHP_OPENSSL_CHECK_SIZE_T_TO_INT(passphrase_len, passphrase, 2); } - pkey = php_openssl_pkey_from_zval(cert, 0, passphrase, passphrase_len); + pkey = php_openssl_pkey_from_zval(cert, 0, passphrase, passphrase_len, 1); if (pkey == NULL) { RETURN_FALSE; } @@ -5075,12 +5177,12 @@ PHP_FUNCTION(openssl_pkey_derive) RETURN_THROWS(); } - EVP_PKEY *pkey = php_openssl_pkey_from_zval(priv_key, 0, "", 0); + EVP_PKEY *pkey = php_openssl_pkey_from_zval(priv_key, 0, "", 0, 2); if (!pkey) { RETURN_FALSE; } - EVP_PKEY *peer_key = php_openssl_pkey_from_zval(peer_pub_key, 1, NULL, 0); + EVP_PKEY *peer_key = php_openssl_pkey_from_zval(peer_pub_key, 1, NULL, 0, 1); if (!peer_key) { EVP_PKEY_free(pkey); RETURN_FALSE; @@ -5155,6 +5257,25 @@ PHP_FUNCTION(openssl_pbkdf2) } /* }}} */ +/** openssl bio new file helper */ +static BIO *php_openssl_bio_new_file( + const char *filename, size_t filename_len, uint32_t arg_num, const char *mode) { + char file_path[MAXPATHLEN]; + BIO *bio; + + if (!php_openssl_check_path(filename, filename_len, file_path, arg_num)) { + return NULL; + } + + bio = BIO_new_file(file_path, mode); + if (bio == NULL) { + php_openssl_store_errors(); + return NULL; + } + + return bio; +} + /* {{{ PKCS7 S/MIME functions */ /* {{{ Verifys that the data block is intact, the signer is who they say they are, and returns the CERTs of the signers */ @@ -5187,7 +5308,7 @@ PHP_FUNCTION(openssl_pkcs7_verify) } if (extracerts) { - others = php_openssl_load_all_certs_from_file(extracerts); + others = php_openssl_load_all_certs_from_file(extracerts, extracerts_len, 5); if (others == NULL) { goto clean_exit; } @@ -5195,20 +5316,17 @@ PHP_FUNCTION(openssl_pkcs7_verify) flags = flags & ~PKCS7_DETACHED; - store = php_openssl_setup_verify(cainfo); + store = php_openssl_setup_verify(cainfo, 4); if (!store) { goto clean_exit; } - if (php_openssl_open_base_dir_chk(filename)) { - goto clean_exit; - } - in = BIO_new_file(filename, PHP_OPENSSL_BIO_MODE_R(flags)); + in = php_openssl_bio_new_file(filename, filename_len, 1, PHP_OPENSSL_BIO_MODE_R(flags)); if (in == NULL) { - php_openssl_store_errors(); goto clean_exit; } + p7 = SMIME_read_PKCS7(in, &datain); if (p7 == NULL) { #if DEBUG_SMIME @@ -5218,23 +5336,16 @@ PHP_FUNCTION(openssl_pkcs7_verify) goto clean_exit; } if (datafilename) { - if (php_openssl_open_base_dir_chk(datafilename)) { - goto clean_exit; - } - dataout = BIO_new_file(datafilename, PHP_OPENSSL_BIO_MODE_W(PKCS7_BINARY)); + dataout = php_openssl_bio_new_file( + datafilename, datafilename_len, 6, PHP_OPENSSL_BIO_MODE_W(PKCS7_BINARY)); if (dataout == NULL) { - php_openssl_store_errors(); goto clean_exit; } } if (p7bfilename) { - if (php_openssl_open_base_dir_chk(p7bfilename)) { - goto clean_exit; - } - - p7bout = BIO_new_file(p7bfilename, PHP_OPENSSL_BIO_MODE_W(PKCS7_BINARY)); + p7bout = php_openssl_bio_new_file( + p7bfilename, p7bfilename_len, 7, PHP_OPENSSL_BIO_MODE_W(PKCS7_BINARY)); if (p7bout == NULL) { - php_openssl_store_errors(); goto clean_exit; } } @@ -5249,11 +5360,8 @@ PHP_FUNCTION(openssl_pkcs7_verify) if (signersfilename) { BIO *certout; - if (php_openssl_open_base_dir_chk(signersfilename)) { - goto clean_exit; - } - - certout = BIO_new_file(signersfilename, PHP_OPENSSL_BIO_MODE_W(PKCS7_BINARY)); + certout = php_openssl_bio_new_file( + signersfilename, signersfilename_len, 3, PHP_OPENSSL_BIO_MODE_W(PKCS7_BINARY)); if (certout) { int i; signers = PKCS7_get0_signers(p7, NULL, (int)flags); @@ -5275,7 +5383,6 @@ PHP_FUNCTION(openssl_pkcs7_verify) BIO_free(certout); } else { - php_openssl_store_errors(); php_error_docref(NULL, E_WARNING, "Signature OK, but cannot open %s for writing", signersfilename); RETVAL_LONG(-1); } @@ -5326,19 +5433,13 @@ PHP_FUNCTION(openssl_pkcs7_encrypt) RETURN_THROWS(); } - if (php_openssl_open_base_dir_chk(infilename) || php_openssl_open_base_dir_chk(outfilename)) { - return; - } - - infile = BIO_new_file(infilename, PHP_OPENSSL_BIO_MODE_R(flags)); + infile = php_openssl_bio_new_file(infilename, infilename_len, 1, PHP_OPENSSL_BIO_MODE_R(flags)); if (infile == NULL) { - php_openssl_store_errors(); goto clean_exit; } - outfile = BIO_new_file(outfilename, PHP_OPENSSL_BIO_MODE_W(flags)); + outfile = php_openssl_bio_new_file(outfilename, outfilename_len, 2, PHP_OPENSSL_BIO_MODE_W(flags)); if (outfile == NULL) { - php_openssl_store_errors(); goto clean_exit; } @@ -5349,7 +5450,7 @@ PHP_FUNCTION(openssl_pkcs7_encrypt) ZEND_HASH_FOREACH_VAL(Z_ARRVAL_P(zrecipcerts), zcertval) { bool free_cert; - cert = php_openssl_x509_from_zval(zcertval, &free_cert); + cert = php_openssl_x509_from_zval(zcertval, &free_cert, 3, true, NULL); if (cert == NULL) { // TODO Add warning? goto clean_exit; @@ -5370,7 +5471,7 @@ PHP_FUNCTION(openssl_pkcs7_encrypt) /* a single certificate */ bool free_cert; - cert = php_openssl_x509_from_zval(zrecipcerts, &free_cert); + cert = php_openssl_x509_from_zval(zrecipcerts, &free_cert, 3, false, NULL); if (cert == NULL) { // TODO Add warning? goto clean_exit; @@ -5575,13 +5676,14 @@ PHP_FUNCTION(openssl_pkcs7_sign) RETVAL_FALSE; if (extracertsfilename) { - others = php_openssl_load_all_certs_from_file(extracertsfilename); + others = php_openssl_load_all_certs_from_file( + extracertsfilename, extracertsfilename_len, 7); if (others == NULL) { goto clean_exit; } } - privkey = php_openssl_pkey_from_zval(zprivkey, 0, "", 0); + privkey = php_openssl_pkey_from_zval(zprivkey, 0, "", 0, 4); if (privkey == NULL) { if (!EG(exception)) { php_error_docref(NULL, E_WARNING, "Error getting private key"); @@ -5589,26 +5691,20 @@ PHP_FUNCTION(openssl_pkcs7_sign) goto clean_exit; } - cert = php_openssl_x509_from_param(cert_obj, cert_str); + cert = php_openssl_x509_from_param(cert_obj, cert_str, 3); if (cert == NULL) { php_error_docref(NULL, E_WARNING, "X.509 Certificate cannot be retrieved"); goto clean_exit; } - if (php_openssl_open_base_dir_chk(infilename) || php_openssl_open_base_dir_chk(outfilename)) { - goto clean_exit; - } - - infile = BIO_new_file(infilename, PHP_OPENSSL_BIO_MODE_R(flags)); + infile = php_openssl_bio_new_file(infilename, infilename_len, 1, PHP_OPENSSL_BIO_MODE_R(flags)); if (infile == NULL) { - php_openssl_store_errors(); php_error_docref(NULL, E_WARNING, "Error opening input file %s!", infilename); goto clean_exit; } - outfile = BIO_new_file(outfilename, PHP_OPENSSL_BIO_MODE_W(PKCS7_BINARY)); + outfile = php_openssl_bio_new_file(outfilename, outfilename_len, 2, PHP_OPENSSL_BIO_MODE_W(PKCS7_BINARY)); if (outfile == NULL) { - php_openssl_store_errors(); php_error_docref(NULL, E_WARNING, "Error opening output file %s!", outfilename); goto clean_exit; } @@ -5689,13 +5785,13 @@ PHP_FUNCTION(openssl_pkcs7_decrypt) RETVAL_FALSE; - cert = php_openssl_x509_from_zval(recipcert, &free_recipcert); + cert = php_openssl_x509_from_zval(recipcert, &free_recipcert, 3, false, NULL); if (cert == NULL) { php_error_docref(NULL, E_WARNING, "X.509 Certificate cannot be retrieved"); goto clean_exit; } - key = php_openssl_pkey_from_zval(recipkey ? recipkey : recipcert, 0, "", 0); + key = php_openssl_pkey_from_zval(recipkey ? recipkey : recipcert, 0, "", 0, 4); if (key == NULL) { if (!EG(exception)) { php_error_docref(NULL, E_WARNING, "Unable to get private key"); @@ -5703,18 +5799,15 @@ PHP_FUNCTION(openssl_pkcs7_decrypt) goto clean_exit; } - if (php_openssl_open_base_dir_chk(infilename) || php_openssl_open_base_dir_chk(outfilename)) { - goto clean_exit; - } - - in = BIO_new_file(infilename, PHP_OPENSSL_BIO_MODE_R(PKCS7_BINARY)); + in = php_openssl_bio_new_file( + infilename, infilename_len, 1, PHP_OPENSSL_BIO_MODE_R(PKCS7_BINARY)); if (in == NULL) { - php_openssl_store_errors(); goto clean_exit; } - out = BIO_new_file(outfilename, PHP_OPENSSL_BIO_MODE_W(PKCS7_BINARY)); + + out = php_openssl_bio_new_file( + outfilename, outfilename_len, 2, PHP_OPENSSL_BIO_MODE_W(PKCS7_BINARY)); if (out == NULL) { - php_openssl_store_errors(); goto clean_exit; } @@ -5780,16 +5873,12 @@ PHP_FUNCTION(openssl_cms_verify) RETURN_THROWS(); } - if (php_openssl_open_base_dir_chk(filename)) { - goto clean_exit; - } - in = BIO_new_file(filename, PHP_OPENSSL_BIO_MODE_R(flags)); + in = php_openssl_bio_new_file(filename, filename_len, 1, PHP_OPENSSL_BIO_MODE_R(flags)); if (in == NULL) { - php_openssl_store_errors(); goto clean_exit; } if (sigfile && (flags & CMS_DETACHED)) { - sigbio = BIO_new_file(sigfile, PHP_OPENSSL_BIO_MODE_R(flags)); + sigbio = php_openssl_bio_new_file(sigfile, sigfile_len, 1, PHP_OPENSSL_BIO_MODE_R(flags)); if (encoding == ENCODING_SMIME) { php_error_docref(NULL, E_WARNING, "Detached signatures not possible with S/MIME encoding"); @@ -5824,40 +5913,30 @@ PHP_FUNCTION(openssl_cms_verify) } if (extracerts) { - others = php_openssl_load_all_certs_from_file(extracerts); + others = php_openssl_load_all_certs_from_file(extracerts, extracerts_len, 5); if (others == NULL) { goto clean_exit; } } - store = php_openssl_setup_verify(cainfo); + store = php_openssl_setup_verify(cainfo, 4); if (!store) { goto clean_exit; } if (datafilename) { - - if (php_openssl_open_base_dir_chk(datafilename)) { - goto clean_exit; - } - - dataout = BIO_new_file(datafilename, PHP_OPENSSL_BIO_MODE_W(CMS_BINARY)); + dataout = php_openssl_bio_new_file( + datafilename, datafilename_len, 6, PHP_OPENSSL_BIO_MODE_W(CMS_BINARY)); if (dataout == NULL) { - php_openssl_store_errors(); goto clean_exit; } } if (p7bfilename) { - - if (php_openssl_open_base_dir_chk(p7bfilename)) { - goto clean_exit; - } - - p7bout = BIO_new_file(p7bfilename, PHP_OPENSSL_BIO_MODE_W(CMS_BINARY)); + p7bout = php_openssl_bio_new_file( + p7bfilename, p7bfilename_len, 7, PHP_OPENSSL_BIO_MODE_W(CMS_BINARY)); if (p7bout == NULL) { - php_openssl_store_errors(); goto clean_exit; } } @@ -5868,11 +5947,8 @@ PHP_FUNCTION(openssl_cms_verify) RETVAL_TRUE; if (signersfilename) { - if (php_openssl_open_base_dir_chk(signersfilename)) { - goto clean_exit; - } - - certout = BIO_new_file(signersfilename, PHP_OPENSSL_BIO_MODE_W(CMS_BINARY)); + certout = php_openssl_bio_new_file( + signersfilename, signersfilename_len, 3, PHP_OPENSSL_BIO_MODE_W(CMS_BINARY)); if (certout) { int i; signers = CMS_get0_signers(cms); @@ -5892,7 +5968,6 @@ PHP_FUNCTION(openssl_cms_verify) php_openssl_store_errors(); } } else { - php_openssl_store_errors(); php_error_docref(NULL, E_WARNING, "Signature OK, but cannot open %s for writing", signersfilename); RETVAL_FALSE; } @@ -5956,19 +6031,15 @@ PHP_FUNCTION(openssl_cms_encrypt) } - if (php_openssl_open_base_dir_chk(infilename) || php_openssl_open_base_dir_chk(outfilename)) { - return; - } - - infile = BIO_new_file(infilename, PHP_OPENSSL_BIO_MODE_R(flags)); + infile = php_openssl_bio_new_file( + infilename, infilename_len, 1, PHP_OPENSSL_BIO_MODE_R(flags)); if (infile == NULL) { - php_openssl_store_errors(); goto clean_exit; } - outfile = BIO_new_file(outfilename, PHP_OPENSSL_BIO_MODE_W(flags)); + outfile = php_openssl_bio_new_file( + outfilename, outfilename_len, 2, PHP_OPENSSL_BIO_MODE_W(flags)); if (outfile == NULL) { - php_openssl_store_errors(); goto clean_exit; } @@ -5979,7 +6050,7 @@ PHP_FUNCTION(openssl_cms_encrypt) ZEND_HASH_FOREACH_VAL(Z_ARRVAL_P(zrecipcerts), zcertval) { bool free_cert; - cert = php_openssl_x509_from_zval(zcertval, &free_cert); + cert = php_openssl_x509_from_zval(zcertval, &free_cert, 3, true, NULL); if (cert == NULL) { goto clean_exit; } @@ -5999,7 +6070,7 @@ PHP_FUNCTION(openssl_cms_encrypt) /* a single certificate */ bool free_cert; - cert = php_openssl_x509_from_zval(zrecipcerts, &free_cert); + cert = php_openssl_x509_from_zval(zrecipcerts, &free_cert, 3, false, NULL); if (cert == NULL) { goto clean_exit; } @@ -6247,13 +6318,14 @@ PHP_FUNCTION(openssl_cms_sign) RETVAL_FALSE; if (extracertsfilename) { - others = php_openssl_load_all_certs_from_file(extracertsfilename); + others = php_openssl_load_all_certs_from_file( + extracertsfilename, extracertsfilename_len, 8); if (others == NULL) { goto clean_exit; } } - privkey = php_openssl_pkey_from_zval(zprivkey, 0, "", 0); + privkey = php_openssl_pkey_from_zval(zprivkey, 0, "", 0, 4); if (privkey == NULL) { if (!EG(exception)) { php_error_docref(NULL, E_WARNING, "Error getting private key"); @@ -6261,16 +6333,12 @@ PHP_FUNCTION(openssl_cms_sign) goto clean_exit; } - cert = php_openssl_x509_from_param(cert_obj, cert_str); + cert = php_openssl_x509_from_param(cert_obj, cert_str, 3); if (cert == NULL) { php_error_docref(NULL, E_WARNING, "X.509 Certificate cannot be retrieved"); goto clean_exit; } - if (php_openssl_open_base_dir_chk(infilename) || php_openssl_open_base_dir_chk(outfilename)) { - goto clean_exit; - } - if ((encoding & ENCODING_SMIME) && (flags & CMS_DETACHED)) { php_error_docref(NULL, E_WARNING, "Detached signatures not possible with S/MIME encoding"); @@ -6288,16 +6356,16 @@ PHP_FUNCTION(openssl_cms_sign) need_final=1; } - infile = BIO_new_file(infilename, PHP_OPENSSL_BIO_MODE_R(flags)); + infile = php_openssl_bio_new_file( + infilename, infilename_len, 1, PHP_OPENSSL_BIO_MODE_R(flags)); if (infile == NULL) { - php_openssl_store_errors(); php_error_docref(NULL, E_WARNING, "Error opening input file %s!", infilename); goto clean_exit; } - outfile = BIO_new_file(outfilename, PHP_OPENSSL_BIO_MODE_W(CMS_BINARY)); + outfile = php_openssl_bio_new_file( + outfilename, outfilename_len, 2, PHP_OPENSSL_BIO_MODE_W(CMS_BINARY)); if (outfile == NULL) { - php_openssl_store_errors(); php_error_docref(NULL, E_WARNING, "Error opening output file %s!", outfilename); goto clean_exit; } @@ -6421,13 +6489,13 @@ PHP_FUNCTION(openssl_cms_decrypt) RETVAL_FALSE; - cert = php_openssl_x509_from_zval(recipcert, &free_recipcert); + cert = php_openssl_x509_from_zval(recipcert, &free_recipcert, 3, false, NULL); if (cert == NULL) { php_error_docref(NULL, E_WARNING, "X.509 Certificate cannot be retrieved"); goto clean_exit; } - key = php_openssl_pkey_from_zval(recipkey ? recipkey : recipcert, 0, "", 0); + key = php_openssl_pkey_from_zval(recipkey ? recipkey : recipcert, 0, "", 0, recipkey ? 4 : 3); if (key == NULL) { if (!EG(exception)) { php_error_docref(NULL, E_WARNING, "Unable to get private key"); @@ -6435,18 +6503,15 @@ PHP_FUNCTION(openssl_cms_decrypt) goto clean_exit; } - if (php_openssl_open_base_dir_chk(infilename) || php_openssl_open_base_dir_chk(outfilename)) { - goto clean_exit; - } - - in = BIO_new_file(infilename, PHP_OPENSSL_BIO_MODE_R(CMS_BINARY)); + in = php_openssl_bio_new_file( + infilename, infilename_len, 1, PHP_OPENSSL_BIO_MODE_R(CMS_BINARY)); if (in == NULL) { - php_openssl_store_errors(); goto clean_exit; } - out = BIO_new_file(outfilename, PHP_OPENSSL_BIO_MODE_W(CMS_BINARY)); + + out = php_openssl_bio_new_file( + outfilename, outfilename_len, 2, PHP_OPENSSL_BIO_MODE_W(CMS_BINARY)); if (out == NULL) { - php_openssl_store_errors(); goto clean_exit; } @@ -6504,7 +6569,7 @@ PHP_FUNCTION(openssl_private_encrypt) RETURN_THROWS(); } - EVP_PKEY *pkey = php_openssl_pkey_from_zval(key, 0, "", 0); + EVP_PKEY *pkey = php_openssl_pkey_from_zval(key, 0, "", 0, 3); if (pkey == NULL) { if (!EG(exception)) { php_error_docref(NULL, E_WARNING, "key param is not a valid private key"); @@ -6553,7 +6618,7 @@ PHP_FUNCTION(openssl_private_decrypt) RETURN_THROWS(); } - EVP_PKEY *pkey = php_openssl_pkey_from_zval(key, 0, "", 0); + EVP_PKEY *pkey = php_openssl_pkey_from_zval(key, 0, "", 0, 3); if (pkey == NULL) { if (!EG(exception)) { php_error_docref(NULL, E_WARNING, "key parameter is not a valid private key"); @@ -6603,7 +6668,7 @@ PHP_FUNCTION(openssl_public_encrypt) RETURN_THROWS(); } - EVP_PKEY *pkey = php_openssl_pkey_from_zval(key, 1, NULL, 0); + EVP_PKEY *pkey = php_openssl_pkey_from_zval(key, 1, NULL, 0, 3); if (pkey == NULL) { if (!EG(exception)) { php_error_docref(NULL, E_WARNING, "key parameter is not a valid public key"); @@ -6652,7 +6717,7 @@ PHP_FUNCTION(openssl_public_decrypt) RETURN_THROWS(); } - EVP_PKEY *pkey = php_openssl_pkey_from_zval(key, 1, NULL, 0); + EVP_PKEY *pkey = php_openssl_pkey_from_zval(key, 1, NULL, 0, 3); if (pkey == NULL) { if (!EG(exception)) { php_error_docref(NULL, E_WARNING, "key parameter is not a valid public key"); @@ -6740,7 +6805,7 @@ PHP_FUNCTION(openssl_sign) Z_PARAM_STR_OR_LONG(method_str, method_long) ZEND_PARSE_PARAMETERS_END(); - pkey = php_openssl_pkey_from_zval(key, 0, "", 0); + pkey = php_openssl_pkey_from_zval(key, 0, "", 0, 3); if (pkey == NULL) { if (!EG(exception)) { php_error_docref(NULL, E_WARNING, "Supplied key param cannot be coerced into a private key"); @@ -6815,7 +6880,7 @@ PHP_FUNCTION(openssl_verify) RETURN_FALSE; } - pkey = php_openssl_pkey_from_zval(key, 1, NULL, 0); + pkey = php_openssl_pkey_from_zval(key, 1, NULL, 0, 3); if (pkey == NULL) { if (!EG(exception)) { php_error_docref(NULL, E_WARNING, "Supplied key param cannot be coerced into a public key"); @@ -6886,7 +6951,7 @@ PHP_FUNCTION(openssl_seal) /* get the public keys we are using to seal this data */ i = 0; ZEND_HASH_FOREACH_VAL(pubkeysht, pubkey) { - pkeys[i] = php_openssl_pkey_from_zval(pubkey, 1, NULL, 0); + pkeys[i] = php_openssl_pkey_from_zval(pubkey, 1, NULL, 0, 4); if (pkeys[i] == NULL) { if (!EG(exception)) { php_error_docref(NULL, E_WARNING, "Not a public key (%dth member of pubkeys)", i+1); @@ -6985,7 +7050,7 @@ PHP_FUNCTION(openssl_open) PHP_OPENSSL_CHECK_SIZE_T_TO_INT(data_len, data, 1); PHP_OPENSSL_CHECK_SIZE_T_TO_INT(ekey_len, ekey, 3); - pkey = php_openssl_pkey_from_zval(privkey, 0, "", 0); + pkey = php_openssl_pkey_from_zval(privkey, 0, "", 0, 4); if (pkey == NULL) { if (!EG(exception)) { diff --git a/ext/openssl/tests/bug41033.phpt b/ext/openssl/tests/bug41033.phpt index ff30d8b266d0b..73cca19506af3 100644 --- a/ext/openssl/tests/bug41033.phpt +++ b/ext/openssl/tests/bug41033.phpt @@ -10,11 +10,11 @@ $pub = 'file://' . __DIR__ . '/' . 'bug41033pub.pem'; $prkeyid = openssl_get_privatekey($prv, "1234"); $ct = "Hello I am some text!"; -openssl_sign($ct, $signature, $prkeyid, OPENSSL_ALGO_SHA1); +openssl_sign($ct, $signature, $prkeyid, OPENSSL_ALGO_SHA256); echo "Signature: ".base64_encode($signature) . "\n"; $pukeyid = openssl_get_publickey($pub); -$valid = openssl_verify($ct, $signature, $pukeyid, OPENSSL_ALGO_SHA1); +$valid = openssl_verify($ct, $signature, $pukeyid, OPENSSL_ALGO_SHA256); echo "Signature validity: " . $valid . "\n"; diff --git a/ext/openssl/tests/bug50293.phpt b/ext/openssl/tests/bug50293.phpt new file mode 100644 index 0000000000000..8eae2914bd195 --- /dev/null +++ b/ext/openssl/tests/bug50293.phpt @@ -0,0 +1,53 @@ +--TEST-- +Bug #50293 (Several openssl functions ignore the VCWD) +--SKIPIF-- + +--FILE-- + "GB", + "stateOrProvinceName" => "Berkshire", + "localityName" => "Newbury", + "organizationName" => "My Company Ltd", + "commonName" => "Demo Cert", +]; + +$args = array( + "digest_alg" => "sha256", + "private_key_bits" => 2048, + "private_key_type" => OPENSSL_KEYTYPE_RSA, + "encrypt_key" => true, + "config" => $config +); + +mkdir(__DIR__ . "/bug50293"); +chdir(__DIR__ . "/bug50293"); + +$privkey = openssl_pkey_get_private('file://' . __DIR__ . '/private_ec.key'); +$csr = openssl_csr_new($dn, $privkey, $args); +$sscert = openssl_csr_sign($csr, null, $privkey, 365, $args); +openssl_csr_export($csr, $csrout);; +openssl_x509_export($sscert, $certout); +openssl_x509_export_to_file($sscert , "bug50293.crt", false); +openssl_pkey_export_to_file($privkey, "bug50293.pem", null, $args); + +var_dump( + file_exists("bug50293.crt"), + file_exists("bug50293.pem") +); +?> +--CLEAN-- + +--EXPECT-- +bool(true) +bool(true) diff --git a/ext/openssl/tests/bug61930.phpt b/ext/openssl/tests/bug61930.phpt index 862c6a07bfd0d..d97f4990173af 100644 --- a/ext/openssl/tests/bug61930.phpt +++ b/ext/openssl/tests/bug61930.phpt @@ -4,19 +4,20 @@ Bug #61930: openssl corrupts ssl key resource when using openssl_get_publickey() openssl --FILE-- --EXPECTF-- object(OpenSSLAsymmetricKey)#%d (0) { diff --git a/ext/openssl/tests/bug66501.phpt b/ext/openssl/tests/bug66501.phpt index 4a7bfbf1361b2..56d391032f7e3 100644 --- a/ext/openssl/tests/bug66501.phpt +++ b/ext/openssl/tests/bug66501.phpt @@ -18,7 +18,7 @@ AwEHoUQDQgAEPq4hbIWHvB51rdWr8ejrjWo4qVNWVugYFtPg/xLQw0mHkIPZ4DvK sqOTOnMoezkbSmVVMuwz9flvnqHGmQvmug== -----END EC PRIVATE KEY-----'; $key = openssl_pkey_get_private($pkey); -$res = openssl_sign($data ='alpha', $sign, $key, 'SHA1'); +$res = openssl_sign($data ='alpha', $sign, $key, 'SHA256'); var_dump($res); ?> --EXPECT-- diff --git a/ext/openssl/tests/bug81713.phpt b/ext/openssl/tests/bug81713.phpt new file mode 100644 index 0000000000000..94715681d51ff --- /dev/null +++ b/ext/openssl/tests/bug81713.phpt @@ -0,0 +1,237 @@ +--TEST-- +Bug #81713 (OpenSSL functions null byte injection) +--SKIPIF-- + +--FILE-- + $config); + +$dn = [ + "countryName" => "BR", + "stateOrProvinceName" => "Rio Grande do Sul", + "localityName" => "Porto Alegre", + "commonName" => "Henrique do N. Angelo", + "emailAddress" => "hnangelo@php.net" +]; + +$csr_args = [ + "digest_alg" => "sha256", + "private_key_bits" => 2048, + "private_key_type" => OPENSSL_KEYTYPE_DSA, + "encrypt_key" => true, + "config" => $config, +]; + +$tests = [ + ["openssl_pkey_get_public", $crt_file], + ["openssl_pkey_get_public", $crt_file_null], + ["openssl_pkey_get_private", $crt_file_null], + ["openssl_pkey_export_to_file", $priv_key_file_null, $outfile], + ["openssl_pkey_export_to_file", $priv_key_file, $outfile_null], + ["openssl_pkey_export", $priv_key_file_null, &$out], + ["openssl_pkey_derive", $priv_key_file_null, $priv_key_file], + ["openssl_pkey_derive", $priv_key_file, $priv_key_file_null], + ["openssl_private_encrypt", "test", &$out, $priv_key_file_null], + ["openssl_private_decrypt", "test", &$out, $priv_key_file_null], + ["openssl_public_encrypt", "test", &$out, $priv_key_file_null], + ["openssl_public_decrypt", "test", &$out, $priv_key_file_null], + ["openssl_sign", "test", &$out, $priv_key_file_null], + ["openssl_verify", "test", "sig", $priv_key_file_null], + ["openssl_seal", "test", &$sealed, &$ekeys, [$priv_key_file_null], "AES-128-CBC", &$iv], + ["openssl_open", "test", &$open, "aaa", $priv_key_file_null, "AES-128-CBC", &$iv], + ["openssl_csr_new", $dn, &$priv_key_file_null, $csr_args], + ["openssl_csr_get_subject", $csr_file_null], + ["openssl_csr_get_public_key", $csr_file_null], + ["openssl_x509_fingerprint", $crt_file_null], + ["openssl_x509_export_to_file", $crt_file_null, $outfile], + ["openssl_x509_export_to_file", $crt_file, $outfile_null], + ["openssl_x509_export", $crt_file_null, &$out], + ["openssl_x509_checkpurpose", $crt_file_null, X509_PURPOSE_SSL_CLIENT], + ["openssl_x509_checkpurpose", $crt_file, X509_PURPOSE_SSL_CLIENT, $cainfo_null], + ["openssl_x509_check_private_key", $crt_file_null, $priv_key_file], + ["openssl_x509_check_private_key", $crt_file, $priv_key_file_null], + ["openssl_x509_verify", $crt_file_null, $priv_key_file], + ["openssl_x509_verify", $crt_file, $priv_key_file_null], + ["openssl_x509_parse", $crt_file_null], + ["openssl_x509_read", $crt_file_null], + ["openssl_cms_encrypt", $infile_null, $outfile, $crt_file, $headers], + ["openssl_cms_encrypt", $infile, $outfile_null, $crt_file, $headers], + ["openssl_cms_encrypt", $infile, $outfile, $crt_file_null, $headers], + ["openssl_cms_encrypt", $infile, $outfile, $cainfo_null, $headers], + ["openssl_cms_decrypt", $infile_null, $outfile, $crt_file, $priv_key_file], + ["openssl_cms_decrypt", $infile, $outfile_null, $crt_file, $priv_key_file], + ["openssl_cms_decrypt", $infile, $outfile, $crt_file_null, $priv_key_file], + ["openssl_cms_decrypt", $infile, $outfile, $crt_file, $priv_key_file_null], + ["openssl_cms_sign", $infile_null, "$outfile", $crt_file, $priv_key_file, $headers], + ["openssl_cms_sign", $infile, $outfile_null, $crt_file, $priv_key_file, $headers], + ["openssl_cms_sign", $infile, $outfile, $crt_file_null, $priv_key_file, $headers], + ["openssl_cms_sign", $infile, $outfile, $crt_file, $crt_file_null, $headers], + ["openssl_cms_sign", $infile, $outfile, $crt_file, $crt_file, $headers, 0, OPENSSL_ENCODING_DER, $crt_file_null], + ["openssl_cms_verify", $eml_null, OPENSSL_CMS_NOVERIFY, $outfile, $cainfo, $outfile, $outfile, $outfile], + ["openssl_cms_verify", $eml, OPENSSL_CMS_NOVERIFY, $outfile_null, $cainfo, $outfile, $outfile, $outfile], + ["openssl_cms_verify", $eml, OPENSSL_CMS_NOVERIFY, $outfile, $cainfo_null], + ["openssl_cms_verify", $eml, OPENSSL_CMS_NOVERIFY, $outfile, $cainfo, $outfile_null, $outfile, $outfile], + ["openssl_cms_verify", $eml, OPENSSL_CMS_NOVERIFY, $outfile, $cainfo, $outfile, $outfile_null, $outfile], + ["openssl_cms_verify", $eml, OPENSSL_CMS_NOVERIFY, $outfile, $cainfo, $outfile, $outfile, $outfile_null], + ["openssl_pkcs7_encrypt", $infile_null, $outfile, $crt_file, $headers], + ["openssl_pkcs7_encrypt", $infile, $outfile_null, $crt_file, $headers], + ["openssl_pkcs7_encrypt", $infile, $outfile, $crt_file_null, $headers], + ["openssl_pkcs7_encrypt", $infile, $outfile, $cainfo_null, $headers], + ["openssl_pkcs7_decrypt", $infile_null, $outfile, $crt_file, $priv_key_file], + ["openssl_pkcs7_decrypt", $infile, $outfile_null, $crt_file, $priv_key_file], + ["openssl_pkcs7_decrypt", $infile, $outfile, $crt_file_null, $priv_key_file], + ["openssl_pkcs7_decrypt", $infile, $outfile, $crt_file, $priv_key_file_null], + ["openssl_pkcs7_sign", $infile_null, "$outfile", $crt_file, $priv_key_file, $headers], + ["openssl_pkcs7_sign", $infile, $outfile_null, $crt_file, $priv_key_file, $headers], + ["openssl_pkcs7_sign", $infile, $outfile, $crt_file_null, $priv_key_file, $headers], + ["openssl_pkcs7_sign", $infile, $outfile, $crt_file, $crt_file_null, $headers], + ["openssl_pkcs7_sign", $infile, $outfile, $crt_file, $crt_file, $headers, 0, $crt_file_null], + ["openssl_pkcs7_verify", $eml_null, 0, $outfile, $cainfo, $outfile, $outfile, $outfile], + ["openssl_pkcs7_verify", $eml, 0, $outfile_null, $cainfo, $outfile, $outfile, $outfile], + ["openssl_pkcs7_verify", $eml, 0, $outfile, $cainfo_null], + ["openssl_pkcs7_verify", $eml, 0, $outfile, $cainfo, $outfile_null, $outfile, $outfile], + ["openssl_pkcs7_verify", $eml, 0, $outfile, $cainfo, $outfile, $outfile_null, $outfile], + ["openssl_pkcs7_verify", $eml, 0, $outfile, $cainfo, $outfile, $outfile, $outfile_null], + ["openssl_pkcs12_export", $crt_file_null, &$out, $priv_key_file, "pwd"], + ["openssl_pkcs12_export", $crt_file, &$out, $priv_key_file_null, "pwd"], + ["openssl_pkcs12_export", $crt_file, &$out, $priv_key_file, "pwd", ["extracerts" => [$crt_file_null]]], + ["openssl_pkcs12_export_to_file", $crt_file_null, $outfile, $priv_key_file, "pwd"], + ["openssl_pkcs12_export_to_file", $crt_file, $outfile_null, $priv_key_file_null, "pwd"], + ["openssl_pkcs12_export_to_file", $crt_file, $outfile, $priv_key_file_null, "pwd"], + ["openssl_pkcs12_export_to_file", $crt_file, $outfile, $priv_key_file, "pwd", ["extracerts" => [$crt_file_null]]], +]; +foreach ($tests as $test) { + try { + $key = call_user_func_array($test[0], array_slice($test, 1)); + var_dump($key); + } + catch (ValueError $e) { + echo $e->getMessage() . PHP_EOL; + } +} +?> +--CLEAN-- + +--EXPECTF-- +object(OpenSSLAsymmetricKey)#1 (0) { +} +openssl_pkey_get_public(): Argument #1 ($public_key) must not contain any null bytes +openssl_pkey_get_private(): Argument #1 ($private_key) must not contain any null bytes +openssl_pkey_export_to_file(): Argument #1 ($key) must not contain any null bytes +openssl_pkey_export_to_file(): Argument #2 ($output_filename) must not contain any null bytes +openssl_pkey_export(): Argument #1 ($key) must not contain any null bytes +openssl_pkey_derive(): Argument #1 ($public_key) must not contain any null bytes +openssl_pkey_derive(): Argument #2 ($private_key) must not contain any null bytes +openssl_private_encrypt(): Argument #3 ($private_key) must not contain any null bytes +openssl_private_decrypt(): Argument #3 ($private_key) must not contain any null bytes +openssl_public_encrypt(): Argument #3 ($public_key) must not contain any null bytes +openssl_public_decrypt(): Argument #3 ($public_key) must not contain any null bytes +openssl_sign(): Argument #3 ($private_key) must not contain any null bytes +openssl_verify(): Argument #3 ($public_key) must not contain any null bytes +openssl_seal(): Argument #4 ($public_key) must not contain any null bytes +openssl_open(): Argument #4 ($private_key) must not contain any null bytes +openssl_csr_new(): Argument #2 ($private_key) must not contain any null bytes +openssl_csr_get_subject(): Argument #1 ($csr) must not contain any null bytes +openssl_csr_get_public_key(): Argument #1 ($csr) must not contain any null bytes + +Warning: openssl_x509_fingerprint(): X.509 Certificate cannot be retrieved in %s on line %d +openssl_x509_fingerprint(): Argument #1 ($certificate) must not contain any null bytes + +Warning: openssl_x509_export_to_file(): X.509 Certificate cannot be retrieved in %s on line %d +openssl_x509_export_to_file(): Argument #1 ($certificate) must not contain any null bytes +openssl_x509_export_to_file(): Argument #2 ($output_filename) must not contain any null bytes + +Warning: openssl_x509_export(): X.509 Certificate cannot be retrieved in %s on line %d +openssl_x509_export(): Argument #1 ($certificate) must not contain any null bytes +openssl_x509_checkpurpose(): Argument #1 ($certificate) must not contain any null bytes +openssl_x509_checkpurpose(): Argument #3 ($ca_info) array item must not contain any null bytes +openssl_x509_check_private_key(): Argument #1 ($certificate) must not contain any null bytes +openssl_x509_check_private_key(): Argument #2 ($private_key) must not contain any null bytes +openssl_x509_verify(): Argument #1 ($certificate) must not contain any null bytes +openssl_x509_verify(): Argument #2 ($public_key) must not contain any null bytes +openssl_x509_parse(): Argument #1 ($certificate) must not contain any null bytes + +Warning: openssl_x509_read(): X.509 Certificate cannot be retrieved in %s on line %d +openssl_x509_read(): Argument #1 ($certificate) must not contain any null bytes +openssl_cms_encrypt(): Argument #1 ($input_filename) must not contain any null bytes +openssl_cms_encrypt(): Argument #2 ($output_filename) must not contain any null bytes +openssl_cms_encrypt(): Argument #3 ($certificate) must not contain any null bytes +openssl_cms_encrypt(): Argument #3 ($certificate) array item must not contain any null bytes +openssl_cms_decrypt(): Argument #1 ($input_filename) must not contain any null bytes +openssl_cms_decrypt(): Argument #2 ($output_filename) must not contain any null bytes + +Warning: openssl_cms_decrypt(): X.509 Certificate cannot be retrieved in %s on line %d +openssl_cms_decrypt(): Argument #3 ($certificate) must not contain any null bytes +openssl_cms_decrypt(): Argument #4 ($private_key) must not contain any null bytes +openssl_cms_sign(): Argument #1 ($input_filename) must not contain any null bytes +openssl_cms_sign(): Argument #2 ($output_filename) must not contain any null bytes + +Warning: openssl_cms_sign(): X.509 Certificate cannot be retrieved in %s on line %d +openssl_cms_sign(): Argument #3 ($certificate) must not contain any null bytes +openssl_cms_sign(): Argument #4 ($private_key) must not contain any null bytes +openssl_cms_sign(): Argument #8 ($untrusted_certificates_filename) must not contain any null bytes +openssl_cms_verify(): Argument #1 ($input_filename) must not contain any null bytes +openssl_cms_verify(): Argument #3 ($certificates) must not contain any null bytes +openssl_cms_verify(): Argument #4 ($ca_info) array item must not contain any null bytes +openssl_cms_verify(): Argument #5 ($untrusted_certificates_filename) must not contain any null bytes +openssl_cms_verify(): Argument #6 ($content) must not contain any null bytes +openssl_cms_verify(): Argument #7 ($pk7) must not contain any null bytes +openssl_pkcs7_encrypt(): Argument #1 ($input_filename) must not contain any null bytes +openssl_pkcs7_encrypt(): Argument #2 ($output_filename) must not contain any null bytes +openssl_pkcs7_encrypt(): Argument #3 ($certificate) must not contain any null bytes +openssl_pkcs7_encrypt(): Argument #3 ($certificate) array item must not contain any null bytes +openssl_pkcs7_decrypt(): Argument #1 ($input_filename) must not contain any null bytes +openssl_pkcs7_decrypt(): Argument #2 ($output_filename) must not contain any null bytes + +Warning: openssl_pkcs7_decrypt(): X.509 Certificate cannot be retrieved in %s on line %d +openssl_pkcs7_decrypt(): Argument #3 ($certificate) must not contain any null bytes +openssl_pkcs7_decrypt(): Argument #4 ($private_key) must not contain any null bytes +openssl_pkcs7_sign(): Argument #1 ($input_filename) must not contain any null bytes +openssl_pkcs7_sign(): Argument #2 ($output_filename) must not contain any null bytes + +Warning: openssl_pkcs7_sign(): X.509 Certificate cannot be retrieved in %s on line %d +openssl_pkcs7_sign(): Argument #3 ($certificate) must not contain any null bytes +openssl_pkcs7_sign(): Argument #4 ($private_key) must not contain any null bytes +openssl_pkcs7_sign(): Argument #7 ($untrusted_certificates_filename) must not contain any null bytes +openssl_pkcs7_verify(): Argument #1 ($input_filename) must not contain any null bytes +openssl_pkcs7_verify(): Argument #3 ($signers_certificates_filename) must not contain any null bytes +openssl_pkcs7_verify(): Argument #4 ($ca_info) array item must not contain any null bytes +openssl_pkcs7_verify(): Argument #5 ($untrusted_certificates_filename) must not contain any null bytes +openssl_pkcs7_verify(): Argument #6 ($content) must not contain any null bytes +openssl_pkcs7_verify(): Argument #7 ($output_filename) must not contain any null bytes + +Warning: openssl_pkcs12_export(): X.509 Certificate cannot be retrieved in %s on line %d +openssl_pkcs12_export(): Argument #1 ($certificate) must not contain any null bytes +openssl_pkcs12_export(): Argument #3 ($private_key) must not contain any null bytes +openssl_pkcs12_export(): Argument #5 ($options) option extracerts array item must not contain any null bytes + +Warning: openssl_pkcs12_export_to_file(): X.509 Certificate cannot be retrieved in %s on line %d +openssl_pkcs12_export_to_file(): Argument #1 ($certificate) must not contain any null bytes +openssl_pkcs12_export_to_file(): Argument #2 ($output_filename) must not contain any null bytes +openssl_pkcs12_export_to_file(): Argument #3 ($private_key) must not contain any null bytes +openssl_pkcs12_export_to_file(): Argument #5 ($options) option extracerts array item must not contain any null bytes diff --git a/ext/openssl/tests/ecc.phpt b/ext/openssl/tests/ecc.phpt index a18651dc5e4b0..297af1dccd0ce 100644 --- a/ext/openssl/tests/ecc.phpt +++ b/ext/openssl/tests/ecc.phpt @@ -64,7 +64,7 @@ $csr = openssl_csr_new($dn, $keyGenerate, $args); var_dump($keyGenerate); -$args["digest_alg"] = "sha1"; +$args["digest_alg"] = "sha256"; echo "Testing openssl_csr_new with existing ecc key\n"; $csr = openssl_csr_new($dn, $key1, $args); var_dump($csr); diff --git a/ext/openssl/tests/openssl.cnf b/ext/openssl/tests/openssl.cnf index f3025aeb5caac..6146b93142cc1 100644 --- a/ext/openssl/tests/openssl.cnf +++ b/ext/openssl/tests/openssl.cnf @@ -7,6 +7,7 @@ tsa_policy2 = 1.2.3.4.5.6 [ req ] default_bits = 1024 +default_md = sha256 default_keyfile = privkey.pem distinguished_name = req_distinguished_name attributes = req_attributes diff --git a/ext/openssl/tests/openssl_csr_export_basic.phpt b/ext/openssl/tests/openssl_csr_export_basic.phpt index 559befe23c922..95bf741e9ec18 100644 --- a/ext/openssl/tests/openssl_csr_export_basic.phpt +++ b/ext/openssl/tests/openssl_csr_export_basic.phpt @@ -17,7 +17,7 @@ $dn = array( ); $args = array( - "digest_alg" => "sha1", + "digest_alg" => "sha256", "private_key_bits" => 2048, "private_key_type" => OPENSSL_KEYTYPE_DSA, "encrypt_key" => true, diff --git a/ext/openssl/tests/openssl_csr_export_to_file_basic.phpt b/ext/openssl/tests/openssl_csr_export_to_file_basic.phpt index dfa533b729cbc..5b09208881638 100644 --- a/ext/openssl/tests/openssl_csr_export_to_file_basic.phpt +++ b/ext/openssl/tests/openssl_csr_export_to_file_basic.phpt @@ -25,7 +25,7 @@ $dn = array( ); $args = array( - "digest_alg" => "sha1", + "digest_alg" => "sha256", "private_key_bits" => 2048, "private_key_type" => OPENSSL_KEYTYPE_DSA, "encrypt_key" => true, @@ -66,12 +66,12 @@ BggTncBh9ozkVQGS/P1m0zn/SKSgDO+6DdeLHLMjpUASaoYfsay4PJLAdnTqLOeM g6qNE6u0ebZXVfmpSmV1pSZ6kQnxbsb6rX1iOZxkwHnVWYb40Hy0EILo31x6BVqB m159m7s38ChiRHqlj20DmRfxXjiT5YDgYYQ29wQBTVQrTN5O9UW5Y+eKTXd8r6te dsbIBXdKN7NeX7ksGYHq1I3hLsP8EyvZO78qfjKyEB0Jj3UCAwEAAaAAMA0GCSqG -SIb3DQEBBQUAA4IBAQCamzVmIbElkiDQKzQpkfU5tHjrWPrHDSB186NI0sQ8i6GQ -1YT6yPAXBPTQ1aER/6uAZJL5HfWEX8V1rKbe8GkPAPCHHQzmHyWlaO2EHS57zJhk -sRrhqkhhkSNiDg4OrsguhRtbB2VMGeDbqHGI89uGqqGHUiZc/Bh8N7WFXZkUU/A0 -sfBgVeqg0P4SWez5fHXqBNcjMdMI5f0bikcDZSIfTHS8FX+PMurLBC8UPB0YNIOl -1r2Lvo+6YUHOziG1OwQd3K0xxu/JzzOE+lMB73ynz4V6DY5Qv3qVno1GpupvgmQA -JViHkCA9x6m8RJXAFvqmgLlWlUzbDv/cRrDfjWjR +SIb3DQEBCwUAA4IBAQCNtCIfMHBDRvNqHmrDfR/+A7ZJ+n/XzA2uQhvjEq91DeT8 +IE7gjUtmj2sqKmHGIDO4uN4F9ZHYzcNk23n6CMljYqJLbB2dHC0V6vkDB7qod1TH +/SK39Yj0ji2AT45LD5rLH3vd1bjxdwwhyPyGhshKOIdnmBv4mwTRANIsiISMQV4Y +ZPAXJ5DTKkgdsY14hqhyWct1bWMPpj2MCLQGjKxK8vmbiKaNL1XxAS7chTXoy7un +NvBKc82Wy3XEuC9AkNFEytD6kA9gu8nFydvYTOvvhaQrf9RzwSitgi9Vj3mbujsN +f1JMPX0/eHrKvG9wBZu28FdS54xoWGeD1NGraW24 -----END CERTIFICATE REQUEST----- " diff --git a/ext/openssl/tests/openssl_csr_get_public_key_basic.phpt b/ext/openssl/tests/openssl_csr_get_public_key_basic.phpt index 7faaf2f234542..9f128c200bea8 100644 --- a/ext/openssl/tests/openssl_csr_get_public_key_basic.phpt +++ b/ext/openssl/tests/openssl_csr_get_public_key_basic.phpt @@ -23,7 +23,7 @@ $dn = array( ); $args = array( - "digest_alg" => "sha1", + "digest_alg" => "sha256", "private_key_bits" => 2048, "private_key_type" => OPENSSL_KEYTYPE_DSA, "encrypt_key" => true, diff --git a/ext/openssl/tests/openssl_csr_get_subject_basic.phpt b/ext/openssl/tests/openssl_csr_get_subject_basic.phpt index 6fe63e971775c..79baeb65b8a5f 100644 --- a/ext/openssl/tests/openssl_csr_get_subject_basic.phpt +++ b/ext/openssl/tests/openssl_csr_get_subject_basic.phpt @@ -23,7 +23,7 @@ $dn = array( ); $args = array( - "digest_alg" => "sha1", + "digest_alg" => "sha256", "private_key_bits" => 2048, "private_key_type" => OPENSSL_KEYTYPE_DSA, "encrypt_key" => true, diff --git a/ext/openssl/tests/openssl_csr_sign_basic.phpt b/ext/openssl/tests/openssl_csr_sign_basic.phpt index a7030b3921454..0cf678cc29445 100644 --- a/ext/openssl/tests/openssl_csr_sign_basic.phpt +++ b/ext/openssl/tests/openssl_csr_sign_basic.phpt @@ -20,7 +20,7 @@ $dn = array( ); $args = array( - "digest_alg" => "sha1", + "digest_alg" => "sha256", "private_key_bits" => 2048, "private_key_type" => OPENSSL_KEYTYPE_DSA, "encrypt_key" => true, diff --git a/ext/openssl/tests/openssl_pkcs12_export_to_file_error.phpt b/ext/openssl/tests/openssl_pkcs12_export_to_file_error.phpt index 34f5ad8133d22..d98f6d15fef1e 100644 --- a/ext/openssl/tests/openssl_pkcs12_export_to_file_error.phpt +++ b/ext/openssl/tests/openssl_pkcs12_export_to_file_error.phpt @@ -33,5 +33,5 @@ bool(false) Warning: openssl_pkcs12_export_to_file(): Private key does not correspond to cert in %s on line %d bool(false) -Warning: openssl_pkcs12_export_to_file(): Error opening file . in %s on line %d +Warning: openssl_pkcs12_export_to_file(): Error opening file %s in %s on line %d bool(false) diff --git a/ext/openssl/tests/openssl_sign_basic.phpt b/ext/openssl/tests/openssl_sign_basic.phpt index 48deac9337c1c..047028101893c 100644 --- a/ext/openssl/tests/openssl_sign_basic.phpt +++ b/ext/openssl/tests/openssl_sign_basic.phpt @@ -8,7 +8,7 @@ $data = "Testing openssl_sign()"; $privkey = "file://" . __DIR__ . "/private_rsa_1024.key"; $wrong = "wrong"; -var_dump(openssl_sign($data, $sign, $privkey)); // no output +var_dump(openssl_sign($data, $sign, $privkey, OPENSSL_ALGO_SHA256)); // no output var_dump(openssl_sign($data, $sign, $wrong)); ?> --EXPECTF-- diff --git a/ext/openssl/tests/openssl_spki_export_challenge_basic.phpt b/ext/openssl/tests/openssl_spki_export_challenge_basic.phpt index ab9076791be43..2fadc30e68105 100644 --- a/ext/openssl/tests/openssl_spki_export_challenge_basic.phpt +++ b/ext/openssl/tests/openssl_spki_export_challenge_basic.phpt @@ -22,8 +22,6 @@ foreach ($key_sizes as $key_size) { /* array of available hashings to test */ $algo = array( - OPENSSL_ALGO_MD5, - OPENSSL_ALGO_SHA1, OPENSSL_ALGO_SHA224, OPENSSL_ALGO_SHA256, OPENSSL_ALGO_SHA384, @@ -76,15 +74,3 @@ string\(36\) \"[0-9a-f]{8}\-([0-9a-f]{4}\-){3}[0-9a-f]{12}\" bool\(false\) string\(36\) \"[0-9a-f]{8}\-([0-9a-f]{4}\-){3}[0-9a-f]{12}\" bool\(false\) -string\(36\) \"[0-9a-f]{8}\-([0-9a-f]{4}\-){3}[0-9a-f]{12}\" -bool\(false\) -string\(36\) \"[0-9a-f]{8}\-([0-9a-f]{4}\-){3}[0-9a-f]{12}\" -bool\(false\) -string\(36\) \"[0-9a-f]{8}\-([0-9a-f]{4}\-){3}[0-9a-f]{12}\" -bool\(false\) -string\(36\) \"[0-9a-f]{8}\-([0-9a-f]{4}\-){3}[0-9a-f]{12}\" -bool\(false\) -string\(36\) \"[0-9a-f]{8}\-([0-9a-f]{4}\-){3}[0-9a-f]{12}\" -bool\(false\) -string\(36\) \"[0-9a-f]{8}\-([0-9a-f]{4}\-){3}[0-9a-f]{12}\" -bool\(false\) diff --git a/ext/openssl/tests/openssl_spki_new_basic.phpt b/ext/openssl/tests/openssl_spki_new_basic.phpt index 1d29fe05bd81d..6b661afde36f0 100644 --- a/ext/openssl/tests/openssl_spki_new_basic.phpt +++ b/ext/openssl/tests/openssl_spki_new_basic.phpt @@ -16,8 +16,6 @@ foreach ($key_sizes as $key_size) { /* array of available hashings to test */ $algo = array( - OPENSSL_ALGO_MD5, - OPENSSL_ALGO_SHA1, OPENSSL_ALGO_SHA224, OPENSSL_ALGO_SHA256, OPENSSL_ALGO_SHA384, @@ -47,16 +45,10 @@ string(478) "%s" string(478) "%s" string(478) "%s" string(478) "%s" -string(478) "%s" -string(478) "%s" -string(830) "%s" string(830) "%s" string(830) "%s" string(830) "%s" string(830) "%s" -string(830) "%s" -string(1510) "%s" -string(1510) "%s" string(1510) "%s" string(1510) "%s" string(1510) "%s" diff --git a/ext/openssl/tests/openssl_spki_verify_basic.phpt b/ext/openssl/tests/openssl_spki_verify_basic.phpt index 9b624a7a5f721..19704b4a4fa88 100644 --- a/ext/openssl/tests/openssl_spki_verify_basic.phpt +++ b/ext/openssl/tests/openssl_spki_verify_basic.phpt @@ -18,8 +18,6 @@ foreach ($key_sizes as $key_size) { /* array of available hashings to test */ $algo = array( - OPENSSL_ALGO_SHA1, - OPENSSL_ALGO_SHA224, OPENSSL_ALGO_SHA256, OPENSSL_ALGO_SHA384, OPENSSL_ALGO_SHA512, @@ -65,15 +63,3 @@ bool(true) bool(false) bool(true) bool(false) -bool(true) -bool(false) -bool(true) -bool(false) -bool(true) -bool(false) -bool(true) -bool(false) -bool(true) -bool(false) -bool(true) -bool(false) diff --git a/ext/openssl/tests/openssl_verify_basic.phpt b/ext/openssl/tests/openssl_verify_basic.phpt index 0e93a21319d97..674a3c58a9ea3 100644 --- a/ext/openssl/tests/openssl_verify_basic.phpt +++ b/ext/openssl/tests/openssl_verify_basic.phpt @@ -9,12 +9,12 @@ $privkey = "file://" . __DIR__ . "/private_rsa_1024.key"; $pubkey = "file://" . __DIR__ . "/public.key"; $wrong = "wrong"; -openssl_sign($data, $sign, $privkey); -var_dump(openssl_verify($data, $sign, $pubkey)); -var_dump(openssl_verify($data, $sign, $privkey)); -var_dump(openssl_verify($data, $sign, $wrong)); -var_dump(openssl_verify($data, $wrong, $pubkey)); -var_dump(openssl_verify($wrong, $sign, $pubkey)); +openssl_sign($data, $sign, $privkey, OPENSSL_ALGO_SHA256); +var_dump(openssl_verify($data, $sign, $pubkey, OPENSSL_ALGO_SHA256)); +var_dump(openssl_verify($data, $sign, $privkey, OPENSSL_ALGO_SHA256)); +var_dump(openssl_verify($data, $sign, $wrong, OPENSSL_ALGO_SHA256)); +var_dump(openssl_verify($data, $wrong, $pubkey, OPENSSL_ALGO_SHA256)); +var_dump(openssl_verify($wrong, $sign, $pubkey, OPENSSL_ALGO_SHA256)); ?> --EXPECTF-- int(1) diff --git a/ext/pdo/pdo_stmt.c b/ext/pdo/pdo_stmt.c index 5320d50cf9c9f..c3c466fbdd241 100644 --- a/ext/pdo/pdo_stmt.c +++ b/ext/pdo/pdo_stmt.c @@ -1551,8 +1551,10 @@ PHP_METHOD(PDOStatement, errorInfo) array_init(return_value); add_next_index_string(return_value, stmt->error_code); - if (stmt->dbh->methods->fetch_err) { - stmt->dbh->methods->fetch_err(stmt->dbh, stmt, return_value); + if (strncmp(stmt->error_code, PDO_ERR_NONE, sizeof(PDO_ERR_NONE))) { + if (stmt->dbh->methods->fetch_err) { + stmt->dbh->methods->fetch_err(stmt->dbh, stmt, return_value); + } } error_count = zend_hash_num_elements(Z_ARRVAL_P(return_value)); diff --git a/ext/pdo/tests/bug_43663.phpt b/ext/pdo/tests/bug_43663.phpt index 96ac1b69d0ec1..dddf87748957f 100644 --- a/ext/pdo/tests/bug_43663.phpt +++ b/ext/pdo/tests/bug_43663.phpt @@ -2,7 +2,6 @@ PDO Common: Bug #43663 (__call on classes derived from PDO) --EXTENSIONS-- pdo -pdo_sqlite --SKIPIF-- foo(); $a->bar(); ?> diff --git a/ext/pdo/tests/gh8626.phpt b/ext/pdo/tests/gh8626.phpt new file mode 100644 index 0000000000000..a77b06a22e12b --- /dev/null +++ b/ext/pdo/tests/gh8626.phpt @@ -0,0 +1,58 @@ +--TEST-- +GH-8626: PDOStatement->execute() failed, then execute successfully, errorInfo() information is incorrect +--SKIPIF-- + +--FILE-- +setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_SILENT); + +$db->exec('DROP TABLE test'); +$db->exec('CREATE TABLE test (x int NOT NULL)'); + +$stmt = $db->prepare('INSERT INTO test VALUES(?)'); + +// fail +var_dump($stmt->execute([null]), $stmt->errorCode()); +$errorInfo = $stmt->errorInfo(); +var_dump(array_slice($errorInfo, 0, 3)); // odbc, dblib + +$stmt->closeCursor(); // sqlite + +// success +var_dump($stmt->execute([1]), $stmt->errorCode()); +$errorInfo = $stmt->errorInfo(); +var_dump(array_slice($errorInfo, 0, 3)); // odbc, dblib +?> +===DONE=== +--EXPECTF-- +bool(false) +string(%d) "%s" +array(3) { + [0]=> + string(%d) "%s" + [1]=> + int(%d) + [2]=> + string(%d) "%s%w%S" +} +bool(true) +string(5) "00000" +array(3) { + [0]=> + string(5) "00000" + [1]=> + NULL + [2]=> + NULL +} +===DONE=== diff --git a/ext/pdo_firebird/firebird_statement.c b/ext/pdo_firebird/firebird_statement.c index ad49147f0256f..d2b0a720b62fe 100644 --- a/ext/pdo_firebird/firebird_statement.c +++ b/ext/pdo_firebird/firebird_statement.c @@ -305,7 +305,15 @@ static int firebird_fetch_blob(pdo_stmt_t *stmt, int colno, zval *result, ISC_QU zend_ulong cur_len; unsigned short seg_len; ISC_STATUS stat; - zend_string *str = zend_string_alloc(len, 0); + zend_string *str; + + /* prevent overflow */ + if (len > ZSTR_MAX_LEN) { + result = 0; + goto fetch_blob_end; + } + + str = zend_string_alloc(len, 0); for (cur_len = stat = 0; (!stat || stat == isc_segment) && cur_len < len; cur_len += seg_len) { diff --git a/ext/pdo_firebird/tests/bug_76452.phpt b/ext/pdo_firebird/tests/bug_76452.phpt index ae953b70b59b2..5c60c759b3358 100644 --- a/ext/pdo_firebird/tests/bug_76452.phpt +++ b/ext/pdo_firebird/tests/bug_76452.phpt @@ -1,5 +1,7 @@ --TEST-- Bug ##76452 (Crash while parsing blob data in firebird_fetch_blob) +--EXTENSIONS-- +pdo_firebird --SKIPIF-- --FILE-- diff --git a/ext/pdo_odbc/odbc_driver.c b/ext/pdo_odbc/odbc_driver.c index 4f59913937af2..42a95c5707cf8 100644 --- a/ext/pdo_odbc/odbc_driver.c +++ b/ext/pdo_odbc/odbc_driver.c @@ -478,7 +478,8 @@ static int pdo_odbc_handle_factory(pdo_dbh_t *dbh, zval *driver_options) /* {{{ goto fail; } - if (strchr(dbh->data_source, ';')) { + /* a connection string may have = but not ; - i.e. "DSN=PHP" */ + if (strchr(dbh->data_source, '=')) { SQLCHAR dsnbuf[1024]; SQLSMALLINT dsnbuflen; diff --git a/ext/pdo_pgsql/tests/bug62498-32bit.phpt b/ext/pdo_pgsql/tests/bug62498-32bit.phpt index 876ea3b48f789..53562ec34cef9 100644 --- a/ext/pdo_pgsql/tests/bug62498-32bit.phpt +++ b/ext/pdo_pgsql/tests/bug62498-32bit.phpt @@ -58,14 +58,14 @@ array(9) { string(13) "bugtest_62498" ["native_type"]=> string(4) "int2" + ["pdo_type"]=> + int(1) ["name"]=> string(7) "int2col" ["len"]=> int(2) ["precision"]=> int(-1) - ["pdo_type"]=> - int(1) } [1]=> array(8) { @@ -77,14 +77,14 @@ array(9) { string(13) "bugtest_62498" ["native_type"]=> string(4) "int4" + ["pdo_type"]=> + int(1) ["name"]=> string(7) "int4col" ["len"]=> int(4) ["precision"]=> int(-1) - ["pdo_type"]=> - int(1) } [2]=> array(8) { @@ -96,14 +96,14 @@ array(9) { string(13) "bugtest_62498" ["native_type"]=> string(4) "int8" + ["pdo_type"]=> + int(1) ["name"]=> string(7) "int8col" ["len"]=> int(8) ["precision"]=> int(-1) - ["pdo_type"]=> - int(2) } [3]=> array(8) { @@ -115,14 +115,14 @@ array(9) { string(13) "bugtest_62498" ["native_type"]=> string(7) "varchar" + ["pdo_type"]=> + int(2) ["name"]=> string(9) "stringcol" ["len"]=> int(-1) ["precision"]=> int(259) - ["pdo_type"]=> - int(2) } [4]=> array(8) { @@ -134,14 +134,14 @@ array(9) { string(13) "bugtest_62498" ["native_type"]=> string(4) "bool" + ["pdo_type"]=> + int(5) ["name"]=> string(7) "boolcol" ["len"]=> int(1) ["precision"]=> int(-1) - ["pdo_type"]=> - int(5) } [5]=> array(8) { @@ -153,14 +153,14 @@ array(9) { string(13) "bugtest_62498" ["native_type"]=> string(4) "date" + ["pdo_type"]=> + int(2) ["name"]=> string(7) "datecol" ["len"]=> int(4) ["precision"]=> int(-1) - ["pdo_type"]=> - int(2) } [6]=> array(8) { @@ -172,14 +172,14 @@ array(9) { string(13) "bugtest_62498" ["native_type"]=> string(4) "text" + ["pdo_type"]=> + int(2) ["name"]=> string(7) "textcol" ["len"]=> int(-1) ["precision"]=> int(-1) - ["pdo_type"]=> - int(2) } [7]=> array(8) { @@ -191,14 +191,14 @@ array(9) { string(13) "bugtest_62498" ["native_type"]=> string(9) "timestamp" + ["pdo_type"]=> + int(2) ["name"]=> string(5) "tscol" ["len"]=> int(8) ["precision"]=> int(-1) - ["pdo_type"]=> - int(2) } [8]=> array(8) { @@ -210,14 +210,14 @@ array(9) { string(13) "bugtest_62498" ["native_type"]=> string(5) "bytea" + ["pdo_type"]=> + int(3) ["name"]=> string(8) "byteacol" ["len"]=> int(-1) ["precision"]=> int(-1) - ["pdo_type"]=> - int(3) } } Done diff --git a/ext/pdo_pgsql/tests/bug62593.phpt b/ext/pdo_pgsql/tests/bug62593.phpt index a82d48999a8be..ce4e5eae2e128 100644 --- a/ext/pdo_pgsql/tests/bug62593.phpt +++ b/ext/pdo_pgsql/tests/bug62593.phpt @@ -54,7 +54,7 @@ $expect = 'No errors found'; foreach ($errors as $error) { - if (strpos('Invalid text representation', $error[2]) !== false) + if (null !== $error[2] && strpos('Invalid text representation', $error[2]) !== false) { $expect = 'Invalid boolean found'; } diff --git a/ext/pgsql/pgsql.c b/ext/pgsql/pgsql.c index 4cc2b7a0857df..4422e4259a532 100644 --- a/ext/pgsql/pgsql.c +++ b/ext/pgsql/pgsql.c @@ -1201,7 +1201,7 @@ PHP_FUNCTION(pg_query_params) } else { zend_string *param_str = zval_try_get_string(tmp); if (!param_str) { - _php_pgsql_free_params(params, num_params); + _php_pgsql_free_params(params, i); RETURN_THROWS(); } params[i] = estrndup(ZSTR_VAL(param_str), ZSTR_LEN(param_str)); @@ -3918,8 +3918,8 @@ PHP_FUNCTION(pg_send_execute) params[i] = NULL; } else { zend_string *tmp_str = zval_try_get_string(tmp); - if (UNEXPECTED(!tmp)) { - _php_pgsql_free_params(params, num_params); + if (UNEXPECTED(!tmp_str)) { + _php_pgsql_free_params(params, i); return; } params[i] = estrndup(ZSTR_VAL(tmp_str), ZSTR_LEN(tmp_str)); diff --git a/ext/pgsql/tests/bug81720.phpt b/ext/pgsql/tests/bug81720.phpt new file mode 100644 index 0000000000000..defae96790caa --- /dev/null +++ b/ext/pgsql/tests/bug81720.phpt @@ -0,0 +1,29 @@ +--TEST-- +Bug #81720 (Uninitialized array in pg_query_params() leading to RCE) +--EXTENSIONS-- +pgsql +--SKIPIF-- + +--FILE-- +getMessage(), PHP_EOL; +} + +try { + pg_send_prepare($conn, "my_query", 'SELECT $1, $2'); + pg_get_result($conn); + pg_send_execute($conn, "my_query", [1, new stdClass()]); +} catch (Throwable $ex) { + echo $ex->getMessage(), PHP_EOL; +} +?> +--EXPECT-- +Object of class stdClass could not be converted to string +Object of class stdClass could not be converted to string diff --git a/ext/reflection/php_reflection.c b/ext/reflection/php_reflection.c index 3ccd43d89e99b..bf408136cc5f9 100644 --- a/ext/reflection/php_reflection.c +++ b/ext/reflection/php_reflection.c @@ -4377,17 +4377,19 @@ ZEND_METHOD(ReflectionClass, getMethod) /* }}} */ /* {{{ _addmethod */ -static void _addmethod(zend_function *mptr, zend_class_entry *ce, HashTable *ht, zend_long filter) +static bool _addmethod(zend_function *mptr, zend_class_entry *ce, HashTable *ht, zend_long filter) { if ((mptr->common.fn_flags & ZEND_ACC_PRIVATE) && mptr->common.scope != ce) { - return; + return 0; } if (mptr->common.fn_flags & filter) { zval method; reflection_method_factory(ce, mptr, NULL, &method); zend_hash_next_index_insert_new(ht, &method); + return 1; } + return 0; } /* }}} */ @@ -4427,7 +4429,9 @@ ZEND_METHOD(ReflectionClass, getMethods) } zend_function *closure = zend_get_closure_invoke_method(obj); if (closure) { - _addmethod(closure, ce, Z_ARRVAL_P(return_value), filter); + if (!_addmethod(closure, ce, Z_ARRVAL_P(return_value), filter)) { + _free_function(closure); + } } if (!has_obj) { zval_ptr_dtor(&obj_tmp); diff --git a/ext/reflection/tests/ReflectionClass_getMethods_004.phpt b/ext/reflection/tests/ReflectionClass_getMethods_004.phpt new file mode 100644 index 0000000000000..418caa37c33f6 --- /dev/null +++ b/ext/reflection/tests/ReflectionClass_getMethods_004.phpt @@ -0,0 +1,11 @@ +--TEST-- +ReflectionClass::getMethods() +--FILE-- +getMethods(2); +?> +DONE +--EXPECT-- +DONE diff --git a/ext/sockets/sendrecvmsg.c b/ext/sockets/sendrecvmsg.c index 01cb773acb1da..d973deb562c06 100644 --- a/ext/sockets/sendrecvmsg.c +++ b/ext/sockets/sendrecvmsg.c @@ -72,7 +72,7 @@ inline ssize_t sendmsg(int sockfd, const struct msghdr *msg, int flags) #define LONG_CHECK_VALID_INT(l, arg_pos) \ do { \ - if ((l) < INT_MIN && (l) > INT_MAX) { \ + if ((l) < INT_MIN || (l) > INT_MAX) { \ zend_argument_value_error((arg_pos), "must be between %d and %d", INT_MIN, INT_MAX); \ RETURN_THROWS(); \ } \ diff --git a/ext/spl/tests/SplFileObject_fgetcsv_basic.phpt b/ext/spl/tests/SplFileObject_fgetcsv_basic.phpt index 9b68d9015cc96..2580021426fd3 100644 --- a/ext/spl/tests/SplFileObject_fgetcsv_basic.phpt +++ b/ext/spl/tests/SplFileObject_fgetcsv_basic.phpt @@ -13,8 +13,6 @@ fclose($fp); $fo = new SplFileObject('SplFileObject__fgetcsv1.csv'); var_dump($fo->fgetcsv()); -var_dump($fo->fgetcsv()); -var_dump($fo->fgetcsv()); ?> --CLEAN-- string(1) "5" } -array(1) { - [0]=> - NULL -} -bool(false) diff --git a/ext/spl/tests/SplFileObject_key_fgets_and seek.phpt b/ext/spl/tests/SplFileObject_key_fgets_and_seek.phpt similarity index 100% rename from ext/spl/tests/SplFileObject_key_fgets_and seek.phpt rename to ext/spl/tests/SplFileObject_key_fgets_and_seek.phpt diff --git a/ext/standard/syslog.c b/ext/standard/syslog.c index d2cfcab9deda0..70fa8e241abdd 100644 --- a/ext/standard/syslog.c +++ b/ext/standard/syslog.c @@ -120,11 +120,6 @@ PHP_MSHUTDOWN_FUNCTION(syslog) return SUCCESS; } -void php_openlog(const char *ident, int option, int facility) -{ - openlog(ident, option, facility); - PG(have_called_openlog) = 1; -} /* {{{ Open connection to system logger */ /* @@ -161,7 +156,7 @@ PHP_FUNCTION(closelog) { ZEND_PARSE_PARAMETERS_NONE(); - closelog(); + php_closelog(); if (BG(syslog_device)) { free(BG(syslog_device)); BG(syslog_device)=NULL; diff --git a/ext/standard/tests/streams/user_streams_context_001.phpt b/ext/standard/tests/streams/user_streams_context_001.phpt new file mode 100644 index 0000000000000..c59905cf4bd8a --- /dev/null +++ b/ext/standard/tests/streams/user_streams_context_001.phpt @@ -0,0 +1,15 @@ +--TEST-- +User streams and incrrectly typed context +--FILE-- + +--EXPECTF-- +Fatal error: Uncaught TypeError: Cannot assign resource to property Wrapper::$context of type Foo in %suser_streams_context_001.php:5 +Stack trace: +#0 %suser_streams_context_001.php(5): dir('foo://') +#1 {main} + thrown in %suser_streams_context_001.php on line 5 diff --git a/ext/zend_test/php_test.h b/ext/zend_test/php_test.h index a08c080ee3730..e51854699caa2 100644 --- a/ext/zend_test/php_test.h +++ b/ext/zend_test/php_test.h @@ -51,7 +51,6 @@ ZEND_BEGIN_MODULE_GLOBALS(zend_test) HashTable global_weakmap; int replace_zend_execute_ex; int register_passes; - bool print_stderr_mshutdown; zend_test_fiber *active_fiber; ZEND_END_MODULE_GLOBALS(zend_test) diff --git a/ext/zend_test/test.c b/ext/zend_test/test.c index 69ffb52aabdc9..6c5bc119ab31b 100644 --- a/ext/zend_test/test.c +++ b/ext/zend_test/test.c @@ -26,6 +26,7 @@ #include "fiber.h" #include "zend_attributes.h" #include "zend_enum.h" +#include "zend_interfaces.h" #include "zend_weakrefs.h" #include "Zend/Optimizer/zend_optimizer.h" #include "test_arginfo.h" @@ -277,6 +278,25 @@ static ZEND_FUNCTION(zend_iterable) ZEND_PARSE_PARAMETERS_END(); } +/* Call a method on a class or object using zend_call_method() */ +static ZEND_FUNCTION(zend_call_method) +{ + zend_class_entry *ce = NULL; + zend_string *method_name = NULL; + zval *arg1 = NULL, *arg2 = NULL; + int argc = ZEND_NUM_ARGS(); + + ZEND_PARSE_PARAMETERS_START(2, 4) + Z_PARAM_CLASS(ce) + Z_PARAM_STR(method_name) + Z_PARAM_OPTIONAL + Z_PARAM_ZVAL(arg1) + Z_PARAM_ZVAL(arg2) + ZEND_PARSE_PARAMETERS_END(); + + zend_call_method(NULL, ce, NULL, ZSTR_VAL(method_name), ZSTR_LEN(method_name), return_value, argc - 2, arg1, arg2); +} + static ZEND_FUNCTION(zend_get_unit_enum) { ZEND_PARSE_PARAMETERS_NONE(); @@ -460,7 +480,6 @@ static ZEND_METHOD(ZendTestChildClassWithMethodWithParameterAttribute, override) PHP_INI_BEGIN() STD_PHP_INI_BOOLEAN("zend_test.replace_zend_execute_ex", "0", PHP_INI_SYSTEM, OnUpdateBool, replace_zend_execute_ex, zend_zend_test_globals, zend_test_globals) STD_PHP_INI_BOOLEAN("zend_test.register_passes", "0", PHP_INI_SYSTEM, OnUpdateBool, register_passes, zend_zend_test_globals, zend_test_globals) - STD_PHP_INI_BOOLEAN("zend_test.print_stderr_mshutdown", "0", PHP_INI_SYSTEM, OnUpdateBool, print_stderr_mshutdown, zend_zend_test_globals, zend_test_globals) PHP_INI_END() void (*old_zend_execute_ex)(zend_execute_data *execute_data); @@ -586,10 +605,6 @@ PHP_MSHUTDOWN_FUNCTION(zend_test) zend_test_observer_shutdown(SHUTDOWN_FUNC_ARGS_PASSTHRU); - if (ZT_G(print_stderr_mshutdown)) { - fprintf(stderr, "[zend-test] MSHUTDOWN\n"); - } - return SUCCESS; } diff --git a/ext/zend_test/test.stub.php b/ext/zend_test/test.stub.php index ef8467c0f59cc..9a49d31fa97d8 100644 --- a/ext/zend_test/test.stub.php +++ b/ext/zend_test/test.stub.php @@ -72,6 +72,7 @@ enum ZendTestStringEnum: string { case Foo = "Test1"; case Bar = "Test2"; case Baz = "Test2\\a"; + case FortyTwo = "42"; } function zend_test_array_return(): array {} @@ -112,6 +113,8 @@ function zend_get_unit_enum(): ZendTestUnitEnum {} function zend_test_parameter_with_attribute(string $parameter): int {} function zend_get_current_func_name(): string {} + + function zend_call_method(string $class, string $method, mixed $arg1 = UNKNOWN, mixed $arg2 = UNKNOWN): mixed {} } namespace ZendTestNS { diff --git a/ext/zend_test/test_arginfo.h b/ext/zend_test/test_arginfo.h index 704a34aa403e2..ebc4076daca82 100644 --- a/ext/zend_test/test_arginfo.h +++ b/ext/zend_test/test_arginfo.h @@ -1,5 +1,5 @@ /* This is a generated file, edit the .stub.php file instead. - * Stub hash: 7b0abebae0b0eeea0f45dccb04759fceec1096e3 */ + * Stub hash: 27df6a7b48574b5c6c9a54c618fce300c7a8bd13 */ ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_zend_test_array_return, 0, 0, IS_ARRAY, 0) ZEND_END_ARG_INFO() @@ -72,6 +72,13 @@ ZEND_END_ARG_INFO() ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_zend_get_current_func_name, 0, 0, IS_STRING, 0) ZEND_END_ARG_INFO() +ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_zend_call_method, 0, 2, IS_MIXED, 0) + ZEND_ARG_TYPE_INFO(0, class, IS_STRING, 0) + ZEND_ARG_TYPE_INFO(0, method, IS_STRING, 0) + ZEND_ARG_TYPE_INFO(0, arg1, IS_MIXED, 0) + ZEND_ARG_TYPE_INFO(0, arg2, IS_MIXED, 0) +ZEND_END_ARG_INFO() + ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_ZendTestNS2_ZendSubNS_namespaced_func, 0, 0, _IS_BOOL, 0) ZEND_END_ARG_INFO() @@ -128,6 +135,7 @@ static ZEND_FUNCTION(zend_weakmap_dump); static ZEND_FUNCTION(zend_get_unit_enum); static ZEND_FUNCTION(zend_test_parameter_with_attribute); static ZEND_FUNCTION(zend_get_current_func_name); +static ZEND_FUNCTION(zend_call_method); static ZEND_FUNCTION(namespaced_func); static ZEND_METHOD(_ZendTestClass, is_object); static ZEND_METHOD(_ZendTestClass, __toString); @@ -164,6 +172,7 @@ static const zend_function_entry ext_functions[] = { ZEND_FE(zend_get_unit_enum, arginfo_zend_get_unit_enum) ZEND_FE(zend_test_parameter_with_attribute, arginfo_zend_test_parameter_with_attribute) ZEND_FE(zend_get_current_func_name, arginfo_zend_get_current_func_name) + ZEND_FE(zend_call_method, arginfo_zend_call_method) ZEND_NS_FE("ZendTestNS2\\ZendSubNS", namespaced_func, arginfo_ZendTestNS2_ZendSubNS_namespaced_func) ZEND_FE_END }; @@ -417,6 +426,11 @@ static zend_class_entry *register_class_ZendTestStringEnum(void) ZVAL_STR(&enum_case_Baz_value, enum_case_Baz_value_str); zend_enum_add_case_cstr(class_entry, "Baz", &enum_case_Baz_value); + zval enum_case_FortyTwo_value; + zend_string *enum_case_FortyTwo_value_str = zend_string_init("42", sizeof("42") - 1, 1); + ZVAL_STR(&enum_case_FortyTwo_value, enum_case_FortyTwo_value_str); + zend_enum_add_case_cstr(class_entry, "FortyTwo", &enum_case_FortyTwo_value); + return class_entry; } diff --git a/ext/zend_test/tests/gh8575.phpt b/ext/zend_test/tests/gh8575.phpt deleted file mode 100644 index 9830547479f49..0000000000000 --- a/ext/zend_test/tests/gh8575.phpt +++ /dev/null @@ -1,13 +0,0 @@ ---TEST-- -CLI: stderr is available in mshutdown ---SKIPIF-- - ---EXTENSIONS-- -zend_test ---INI-- -zend_test.print_stderr_mshutdown=1 ---FILE-- -==DONE== ---EXPECTF-- -==DONE== -[zend-test] MSHUTDOWN diff --git a/ext/zend_test/tests/internal-call-internal-static-return.phpt b/ext/zend_test/tests/internal-call-internal-static-return.phpt new file mode 100644 index 0000000000000..bb44bcd48a691 --- /dev/null +++ b/ext/zend_test/tests/internal-call-internal-static-return.phpt @@ -0,0 +1,32 @@ +--TEST-- +Calling a builtin function with 'static' return type from internal code +--EXTENSIONS-- +zend_test +--FILE-- +err_sys = 0; } + /* clear cache as empty zip are not created but deleted */ + php_clear_stat_cache(1, ze_obj->filename, ze_obj->filename_len); + efree(ze_obj->filename); ze_obj->filename = NULL; ze_obj->filename_len = 0; diff --git a/ext/zip/tests/bug_gh8781.phpt b/ext/zip/tests/bug_gh8781.phpt new file mode 100644 index 0000000000000..25eadb70575df --- /dev/null +++ b/ext/zip/tests/bug_gh8781.phpt @@ -0,0 +1,21 @@ +--TEST-- +Bug GH-8781 (ZipArchive deletes zip file with no contents) +--SKIPIF-- + +--FILE-- +open($file, ZipArchive::CREATE | ZipArchive::OVERWRITE); +$zip->close(); + +var_dump(is_file($file)); +?> +--EXPECT-- +bool(true) +bool(false) + diff --git a/main/main.c b/main/main.c index 8c16f01b11382..2f6ef27e49de6 100644 --- a/main/main.c +++ b/main/main.c @@ -348,15 +348,15 @@ static void php_binary_init(void) { char *binary_location = NULL; #ifdef PHP_WIN32 - binary_location = (char *)malloc(MAXPATHLEN); - if (binary_location && GetModuleFileName(0, binary_location, MAXPATHLEN) == 0) { - free(binary_location); - PG(php_binary) = NULL; + binary_location = (char *)pemalloc(MAXPATHLEN, 1); + if (GetModuleFileName(0, binary_location, MAXPATHLEN) == 0) { + pefree(binary_location, 1); + binary_location = NULL; } #else if (sapi_module.executable_location) { - binary_location = (char *)malloc(MAXPATHLEN); - if (binary_location && !strchr(sapi_module.executable_location, '/')) { + binary_location = (char *)pemalloc(MAXPATHLEN, 1); + if (!strchr(sapi_module.executable_location, '/')) { char *envpath, *path; int found = 0; @@ -379,11 +379,11 @@ static void php_binary_init(void) efree(path); } if (!found) { - free(binary_location); + pefree(binary_location, 1); binary_location = NULL; } } else if (!VCWD_REALPATH(sapi_module.executable_location, binary_location) || VCWD_ACCESS(binary_location, X_OK)) { - free(binary_location); + pefree(binary_location, 1); binary_location = NULL; } } diff --git a/main/php_syslog.c b/main/php_syslog.c index 54d871c6acac9..fa71a86313466 100644 --- a/main/php_syslog.c +++ b/main/php_syslog.c @@ -71,6 +71,18 @@ PHPAPI void php_syslog_str(int priority, const zend_string* message) smart_string_free(&sbuf); } +void php_openlog(const char *ident, int option, int facility) +{ + openlog(ident, option, facility); + PG(have_called_openlog) = 1; +} + +void php_closelog(void) +{ + closelog(); + PG(have_called_openlog) = 0; +} + #ifdef PHP_WIN32 PHPAPI void php_syslog(int priority, const char *format, ...) /* {{{ */ { diff --git a/main/php_syslog.h b/main/php_syslog.h index 2005a03ef9e8f..f2682d74f2382 100644 --- a/main/php_syslog.h +++ b/main/php_syslog.h @@ -38,6 +38,7 @@ BEGIN_EXTERN_C() PHPAPI void php_syslog_str(int priority, const zend_string* message); PHPAPI void php_syslog(int, const char *format, ...); PHPAPI void php_openlog(const char *, int, int); +PHPAPI void php_closelog(void); END_EXTERN_C() #endif diff --git a/main/php_version.h b/main/php_version.h index f027619e22e83..4c4802ed300cc 100644 --- a/main/php_version.h +++ b/main/php_version.h @@ -2,7 +2,7 @@ /* edit configure.ac to change version number */ #define PHP_MAJOR_VERSION 8 #define PHP_MINOR_VERSION 1 -#define PHP_RELEASE_VERSION 7 -#define PHP_EXTRA_VERSION "-dev" -#define PHP_VERSION "8.1.7-dev" -#define PHP_VERSION_ID 80107 +#define PHP_RELEASE_VERSION 8 +#define PHP_EXTRA_VERSION "" +#define PHP_VERSION "8.1.8" +#define PHP_VERSION_ID 80108 diff --git a/main/streams/userspace.c b/main/streams/userspace.c index 0a24dd31185c1..f29791295c55d 100644 --- a/main/streams/userspace.c +++ b/main/streams/userspace.c @@ -289,8 +289,8 @@ static void user_stream_create_object(struct php_user_stream_wrapper *uwrap, php } if (context) { - add_property_resource(object, "context", context->res); GC_ADDREF(context->res); + add_property_resource(object, "context", context->res); } else { add_property_null(object, "context"); } diff --git a/run-tests.php b/run-tests.php index 639eff583c1c6..ae988abdc09df 100755 --- a/run-tests.php +++ b/run-tests.php @@ -2093,11 +2093,19 @@ function run_test(string $php, $file, array $env): string $ini_settings = $workerID ? ['opcache.cache_id' => "worker$workerID"] : []; // Additional required extensions + $extensions = []; if ($test->hasSection('EXTENSIONS')) { + $extensions = preg_split("/[\n\r]+/", trim($test->getSection('EXTENSIONS'))); + } + if (is_array($IN_REDIRECT) && $IN_REDIRECT['EXTENSIONS'] != []) { + $extensions = array_merge($extensions, $IN_REDIRECT['EXTENSIONS']); + } + + /* Load required extensions */ + if ($extensions != []) { $ext_params = []; settings2array($ini_overwrites, $ext_params); $ext_params = settings2params($ext_params); - $extensions = preg_split("/[\n\r]+/", trim($test->getSection('EXTENSIONS'))); [$ext_dir, $loaded] = $skipCache->getExtensions("$orig_php $pass_options $extra_options $ext_params $no_file_cache"); $ext_prefix = IS_WINDOWS ? "php_" : ""; $missing = []; @@ -2249,6 +2257,7 @@ function run_test(string $php, $file, array $env): string $IN_REDIRECT['via'] = "via [$shortname]\n\t"; $IN_REDIRECT['dir'] = realpath(dirname($file)); $IN_REDIRECT['prefix'] = $tested; + $IN_REDIRECT['EXTENSIONS'] = $extensions; if (!empty($IN_REDIRECT['TESTS'])) { if (is_array($org_file)) { @@ -3403,6 +3412,9 @@ class JUnit 'execution_time' => 0, ]; + /** + * @throws Exception + */ public function __construct(array $env, int $workerID) { // Check whether a junit log is wanted. @@ -3620,6 +3632,9 @@ public function initSuite(string $suite_name): void $this->suites[$suite_name] = self::EMPTY_SUITE + ['name' => $suite_name]; } + /** + * @throws Exception + */ public function stopTimer(string $file_name): void { if (!$this->enabled) { @@ -3819,6 +3834,9 @@ class TestFile 'CREDITS', 'DESCRIPTION', 'CONFLICTS', 'WHITESPACE_SENSITIVE', ]; + /** + * @throws BorkageException + */ public function __construct(string $fileName, bool $inRedirect) { $this->fileName = $fileName; @@ -3859,6 +3877,9 @@ public function sectionNotEmpty(string $name): bool return !empty($this->sections[$name]); } + /** + * @throws Exception + */ public function getSection(string $name): string { if (!isset($this->sections[$name])) { @@ -3895,6 +3916,7 @@ public function setSection(string $name, string $value): void /** * Load the sections of the test file + * @throws BorkageException */ private function readFile(): void { @@ -3957,6 +3979,9 @@ private function readFile(): void fclose($fp); } + /** + * @throws BorkageException + */ private function validateAndProcess(bool $inRedirect): void { // the redirect section allows a set of tests to be reused outside of diff --git a/sapi/cli/php_cli.c b/sapi/cli/php_cli.c index c2de8bd5230ef..47241f8af4e04 100644 --- a/sapi/cli/php_cli.c +++ b/sapi/cli/php_cli.c @@ -542,11 +542,9 @@ static void cli_register_file_handles(bool no_close) /* {{{ */ * extensions which write to stderr or company during mshutdown/gshutdown * won't have the expected functionality. */ - if (no_close) { - if (s_in) s_in->flags |= PHP_STREAM_FLAG_NO_CLOSE; - if (s_out) s_out->flags |= PHP_STREAM_FLAG_NO_CLOSE; - if (s_err) s_err->flags |= PHP_STREAM_FLAG_NO_CLOSE; - } + if (s_in) s_in->flags |= PHP_STREAM_FLAG_NO_CLOSE; + if (s_out) s_out->flags |= PHP_STREAM_FLAG_NO_CLOSE; + if (s_err) s_err->flags |= PHP_STREAM_FLAG_NO_CLOSE; if (s_in==NULL || s_out==NULL || s_err==NULL) { if (s_in) php_stream_close(s_in); @@ -960,7 +958,7 @@ static int do_cli(int argc, char **argv) /* {{{ */ switch (behavior) { case PHP_MODE_STANDARD: if (script_file) { - cli_register_file_handles(/* no_close */ true); + cli_register_file_handles(/* no_close */ PHP_DEBUG || num_repeats > 1); } if (interactive) { @@ -995,7 +993,7 @@ static int do_cli(int argc, char **argv) /* {{{ */ } break; case PHP_MODE_CLI_DIRECT: - cli_register_file_handles(/* no_close */ true); + cli_register_file_handles(/* no_close */ PHP_DEBUG || num_repeats > 1); zend_eval_string_ex(exec_direct, NULL, "Command line code", 1); break; @@ -1010,7 +1008,7 @@ static int do_cli(int argc, char **argv) /* {{{ */ file_handle.filename = NULL; } - cli_register_file_handles(/* no_close */ true); + cli_register_file_handles(/* no_close */ PHP_DEBUG || num_repeats > 1); if (exec_begin) { zend_eval_string_ex(exec_begin, NULL, "Command line begin code", 1); diff --git a/sapi/fpm/fpm/fpm_conf.c b/sapi/fpm/fpm/fpm_conf.c index 0464a36f16801..e507c00d76693 100644 --- a/sapi/fpm/fpm/fpm_conf.c +++ b/sapi/fpm/fpm/fpm_conf.c @@ -769,8 +769,8 @@ static int fpm_evaluate_full_path(char **path, struct fpm_worker_pool_s *wp, cha } if (strlen(*path) > strlen("$prefix")) { - free(*path); tmp = strdup((*path) + strlen("$prefix")); + free(*path); *path = tmp; } else { free(*path); diff --git a/sapi/fpm/fpm/fpm_stdio.c b/sapi/fpm/fpm/fpm_stdio.c index 81ec632fb250f..e920923b009bc 100644 --- a/sapi/fpm/fpm/fpm_stdio.c +++ b/sapi/fpm/fpm/fpm_stdio.c @@ -89,7 +89,7 @@ int fpm_stdio_init_child(struct fpm_worker_pool_s *wp) /* {{{ */ { #ifdef HAVE_SYSLOG_H if (fpm_globals.error_log_fd == ZLOG_SYSLOG) { - closelog(); /* ensure to close syslog not to interrupt with PHP syslog code */ + php_closelog(); /* ensure to close syslog not to interrupt with PHP syslog code */ } else #endif