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

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
29 changes: 29 additions & 0 deletions Zend/tests/gh20714.phpt
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
--TEST--
GH-20714: Uncatchable exception thrown in generator
--CREDITS--
Grégoire Paris (greg0ire)
--FILE--
<?php

function gen(): Generator {
try {
yield 1;
} finally {}
}

function process(): void {
$g = gen();
foreach ($g as $_) {
throw new Exception('ERROR');
}
}

try {
process();
} catch (Exception $e) {
echo "Caught\n";
}

?>
--EXPECT--
Caught
6 changes: 4 additions & 2 deletions Zend/zend_generators.c
Original file line number Diff line number Diff line change
Expand Up @@ -312,7 +312,9 @@ static void zend_generator_dtor_storage(zend_object *object) /* {{{ */
zend_object *old_exception = NULL;
const zend_op *old_opline_before_exception = NULL;
if (EG(exception)) {
if (EG(current_execute_data)) {
if (EG(current_execute_data)
&& EG(current_execute_data)->opline
&& EG(current_execute_data)->opline->opcode == ZEND_HANDLE_EXCEPTION) {
EG(current_execute_data)->opline = EG(opline_before_exception);
old_opline_before_exception = EG(opline_before_exception);
}
Expand All @@ -329,7 +331,7 @@ static void zend_generator_dtor_storage(zend_object *object) /* {{{ */
zend_generator_resume(generator);

if (old_exception) {
if (EG(current_execute_data)) {
if (old_opline_before_exception) {
EG(current_execute_data)->opline = EG(exception_op);
EG(opline_before_exception) = old_opline_before_exception;
}
Expand Down
6 changes: 6 additions & 0 deletions ext/pdo/pdo_sql_parser.re
Original file line number Diff line number Diff line change
Expand Up @@ -300,6 +300,12 @@ safe:
}

plc->quoted = stmt->dbh->methods->quoter(stmt->dbh, buf, param_type);
if (plc->quoted == NULL) {
/* bork */
ret = -1;
strncpy(stmt->error_code, stmt->dbh->error_code, 6);
goto clean_up;
}
}
}

Expand Down
28 changes: 28 additions & 0 deletions ext/pdo_pgsql/tests/ghsa-8xr5-qppj-gvwj.phpt
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
--TEST--
#GHSA-8xr5-qppj-gvwj: NULL Pointer Derefernce for failed user input quoting
--EXTENSIONS--
pdo
pdo_pgsql
--SKIPIF--
<?php
require_once dirname(__FILE__) . '/../../../ext/pdo/tests/pdo_test.inc';
require_once dirname(__FILE__) . '/config.inc';
PDOTest::skip();
?>
--FILE--
<?php
require_once dirname(__FILE__) . '/../../../ext/pdo/tests/pdo_test.inc';
require_once dirname(__FILE__) . '/config.inc';
$db = PDOTest::test_factory(dirname(__FILE__) . '/common.phpt');
$db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
$db->setAttribute(PDO::ATTR_EMULATE_PREPARES, true);

$sql = "SELECT * FROM users where username = :username";
$stmt = $db->prepare($sql);

$p1 = "alice\x99";
var_dump($stmt->execute(['username' => $p1]));

?>
--EXPECT--
bool(false)
7 changes: 6 additions & 1 deletion ext/standard/array.c
Original file line number Diff line number Diff line change
Expand Up @@ -4156,7 +4156,7 @@ static zend_always_inline void php_array_merge_wrapper(INTERNAL_FUNCTION_PARAMET
uint32_t argc, i;
zval *src_entry;
HashTable *src, *dest;
uint32_t count = 0;
uint64_t count = 0;

ZEND_PARSE_PARAMETERS_START(0, -1)
Z_PARAM_VARIADIC('+', args, argc)
Expand All @@ -4176,6 +4176,11 @@ static zend_always_inline void php_array_merge_wrapper(INTERNAL_FUNCTION_PARAMET
count += zend_hash_num_elements(Z_ARRVAL_P(arg));
}

if (UNEXPECTED(count >= HT_MAX_SIZE)) {
zend_throw_error(NULL, "The total number of elements must be lower than %u", HT_MAX_SIZE);
RETURN_THROWS();
}

if (argc == 2) {
zval *ret = NULL;

Expand Down
12 changes: 6 additions & 6 deletions ext/standard/basic_functions.c
Original file line number Diff line number Diff line change
Expand Up @@ -561,7 +561,7 @@ PHP_FUNCTION(inet_pton)
char buffer[17];

ZEND_PARSE_PARAMETERS_START(1, 1)
Z_PARAM_STRING(address, address_len)
Z_PARAM_PATH(address, address_len)
ZEND_PARSE_PARAMETERS_END();

memset(buffer, 0, sizeof(buffer));
Expand Down Expand Up @@ -593,7 +593,7 @@ PHP_FUNCTION(ip2long)
struct in_addr ip;

ZEND_PARSE_PARAMETERS_START(1, 1)
Z_PARAM_STRING(addr, addr_len)
Z_PARAM_PATH(addr, addr_len)
ZEND_PARSE_PARAMETERS_END();

if (addr_len == 0 || inet_pton(AF_INET, addr, &ip) != 1) {
Expand Down Expand Up @@ -2139,8 +2139,8 @@ PHP_FUNCTION(getservbyname)
struct servent *serv;

ZEND_PARSE_PARAMETERS_START(2, 2)
Z_PARAM_STR(name)
Z_PARAM_STRING(proto, proto_len)
Z_PARAM_PATH_STR(name)
Z_PARAM_PATH(proto, proto_len)
ZEND_PARSE_PARAMETERS_END();


Expand Down Expand Up @@ -2183,7 +2183,7 @@ PHP_FUNCTION(getservbyport)

ZEND_PARSE_PARAMETERS_START(2, 2)
Z_PARAM_LONG(port)
Z_PARAM_STRING(proto, proto_len)
Z_PARAM_PATH(proto, proto_len)
ZEND_PARSE_PARAMETERS_END();

serv = getservbyport(htons((unsigned short) port), proto);
Expand All @@ -2210,7 +2210,7 @@ PHP_FUNCTION(getprotobyname)
struct protoent *ent;

ZEND_PARSE_PARAMETERS_START(1, 1)
Z_PARAM_STRING(name, name_len)
Z_PARAM_PATH(name, name_len)
ZEND_PARSE_PARAMETERS_END();

ent = getprotobyname(name);
Expand Down
6 changes: 3 additions & 3 deletions ext/standard/dns.c
Original file line number Diff line number Diff line change
Expand Up @@ -382,7 +382,7 @@ PHP_FUNCTION(dns_check_record)
#endif

ZEND_PARSE_PARAMETERS_START(1, 2)
Z_PARAM_STRING(hostname, hostname_len)
Z_PARAM_PATH(hostname, hostname_len)
Z_PARAM_OPTIONAL
Z_PARAM_STR(rectype)
ZEND_PARSE_PARAMETERS_END();
Expand Down Expand Up @@ -829,7 +829,7 @@ PHP_FUNCTION(dns_get_record)
bool raw = 0;

ZEND_PARSE_PARAMETERS_START(1, 5)
Z_PARAM_STRING(hostname, hostname_len)
Z_PARAM_PATH(hostname, hostname_len)
Z_PARAM_OPTIONAL
Z_PARAM_LONG(type_param)
Z_PARAM_ZVAL(authns)
Expand Down Expand Up @@ -1067,7 +1067,7 @@ PHP_FUNCTION(dns_get_mx)
#endif

ZEND_PARSE_PARAMETERS_START(2, 3)
Z_PARAM_STRING(hostname, hostname_len)
Z_PARAM_PATH(hostname, hostname_len)
Z_PARAM_ZVAL(mx_list)
Z_PARAM_OPTIONAL
Z_PARAM_ZVAL(weight_list)
Expand Down
6 changes: 3 additions & 3 deletions ext/standard/dns_win32.c
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ PHP_FUNCTION(dns_get_mx) /* {{{ */
DNS_STATUS status; /* Return value of DnsQuery_A() function */
PDNS_RECORD pResult, pRec; /* Pointer to DNS_RECORD structure */

if (zend_parse_parameters(ZEND_NUM_ARGS(), "sz|z", &hostname, &hostname_len, &mx_list, &weight_list) == FAILURE) {
if (zend_parse_parameters(ZEND_NUM_ARGS(), "pz|z", &hostname, &hostname_len, &mx_list, &weight_list) == FAILURE) {
RETURN_THROWS();
}

Expand Down Expand Up @@ -86,7 +86,7 @@ PHP_FUNCTION(dns_check_record)
DNS_STATUS status; /* Return value of DnsQuery_A() function */
PDNS_RECORD pResult; /* Pointer to DNS_RECORD structure */

if (zend_parse_parameters(ZEND_NUM_ARGS(), "s|S", &hostname, &hostname_len, &rectype) == FAILURE) {
if (zend_parse_parameters(ZEND_NUM_ARGS(), "p|S", &hostname, &hostname_len, &rectype) == FAILURE) {
RETURN_THROWS();
}

Expand Down Expand Up @@ -343,7 +343,7 @@ PHP_FUNCTION(dns_get_record)
int type, type_to_fetch, first_query = 1, store_results = 1;
bool raw = false;

if (zend_parse_parameters(ZEND_NUM_ARGS(), "s|lz!z!b",
if (zend_parse_parameters(ZEND_NUM_ARGS(), "p|lz!z!b",
&hostname, &hostname_len, &type_param, &authns, &addtl, &raw) == FAILURE) {
RETURN_THROWS();
}
Expand Down
16 changes: 16 additions & 0 deletions ext/standard/tests/array/GHSA-h96m-rvf9-jgm2.phpt
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
--TEST--
GHSA-h96m-rvf9-jgm2
--FILE--
<?php

$power = 20; // Chosen to be well within a memory_limit
$arr = range(0, 2**$power);
try {
array_merge(...array_fill(0, 2**(32-$power), $arr));
} catch (Error $e) {
echo $e->getMessage(), "\n";
}

?>
--EXPECTF--
The total number of elements must be lower than %d
62 changes: 62 additions & 0 deletions ext/standard/tests/network/ghsa-www2-q4fc-65wf.phpt
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
--TEST--
GHSA-www2-q4fc-65wf
--DESCRIPTION--
This is a ZPP test but *keep* this as it is security-sensitive!
--FILE--
<?php
try {
dns_check_record("\0");
} catch (ValueError $e) {
echo $e->getMessage(), "\n";
}
try {
dns_get_mx("\0", $out);
} catch (ValueError $e) {
echo $e->getMessage(), "\n";
}
try {
dns_get_record("\0");
} catch (ValueError $e) {
echo $e->getMessage(), "\n";
}
try {
getprotobyname("\0");
} catch (ValueError $e) {
echo $e->getMessage(), "\n";
}
try {
getservbyname("\0", "tcp");
} catch (ValueError $e) {
echo $e->getMessage(), "\n";
}
try {
getservbyname("x", "tcp\0");
} catch (ValueError $e) {
echo $e->getMessage(), "\n";
}
try {
getservbyport(0, "tcp\0");
} catch (ValueError $e) {
echo $e->getMessage(), "\n";
}
try {
inet_pton("\0");
} catch (ValueError $e) {
echo $e->getMessage(), "\n";
}
try {
ip2long("\0");
} catch (ValueError $e) {
echo $e->getMessage(), "\n";
}
?>
--EXPECT--
dns_check_record(): Argument #1 ($hostname) must not contain any null bytes
dns_get_mx(): Argument #1 ($hostname) must not contain any null bytes
dns_get_record(): Argument #1 ($hostname) must not contain any null bytes
getprotobyname(): Argument #1 ($protocol) must not contain any null bytes
getservbyname(): Argument #1 ($service) must not contain any null bytes
getservbyname(): Argument #2 ($protocol) must not contain any null bytes
getservbyport(): Argument #2 ($protocol) must not contain any null bytes
inet_pton(): Argument #1 ($ip) must not contain any null bytes
ip2long(): Argument #1 ($ip) must not contain any null bytes