Skip to content

Commit c32b7ea

Browse files
committed
Merge remote-tracking branch 'origin/master' into opcache/file_cache_read_only
2 parents 2e614ae + 55e8ebe commit c32b7ea

19 files changed

+224
-44
lines changed

.github/CODEOWNERS

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@
4545
/ext/random @TimWolla @zeriyoshi
4646
/ext/session @Girgias
4747
/ext/simplexml @nielsdos
48+
/ext/soap @nielsdos
4849
/ext/sockets @devnexen
4950
/ext/spl @Girgias
5051
/ext/standard @bukka

EXTENSIONS

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -184,7 +184,8 @@ SINCE: 5.0
184184
-------------------------------------------------------------------------------
185185
EXTENSION: soap
186186
PRIMARY MAINTAINER: Dmitry Stogov <[email protected]> (2004 - 2018)
187-
MAINTENANCE: Maintained
187+
Niels Dossche <[email protected]> (2024 - 2024)
188+
MAINTENANCE: Odd fixes
188189
STATUS: Working
189190
-------------------------------------------------------------------------------
190191
EXTENSION: xml

Zend/tests/gh16508.phpt

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
--TEST--
2+
GH-16508: Missing lineno in inheritance errors of delayed early bound classes
3+
--EXTENSIONS--
4+
opcache
5+
--INI--
6+
opcache.enable_cli=1
7+
--FILE--
8+
<?php
9+
10+
new Test2;
11+
12+
class Test2 extends Test {}
13+
14+
abstract class Test {
15+
abstract function foo();
16+
}
17+
18+
?>
19+
--EXPECTF--
20+
Fatal error: Class Test2 contains 1 abstract method and must therefore be declared abstract or implement the remaining method (Test::foo) in %s on line 5

Zend/tests/gh16509.inc

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
<?php
2+
3+
function test() {
4+
5+
6+
echo 'foo';
7+
}

Zend/tests/gh16509.phpt

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
--TEST--
2+
GH-16509: Incorrect lineno reported for function redeclaration
3+
--FILE--
4+
<?php
5+
6+
include __DIR__ . '/gh16509.inc';
7+
include __DIR__ . '/gh16509.inc';
8+
9+
?>
10+
--EXPECTF--
11+
Fatal error: Cannot redeclare function test() (previously declared in %sgh16509.inc:3) in %sgh16509.inc on line 3

Zend/tests/gh16515.phpt

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
--TEST--
2+
GH-16515: Incorrect propagation of ZEND_ACC_RETURN_REFERENCE for call trampoline
3+
--FILE--
4+
<?php
5+
6+
namespace Foo;
7+
8+
class Foo {
9+
public function &__call($method, $args) {}
10+
}
11+
12+
call_user_func((new Foo)->bar(...));
13+
14+
?>
15+
--EXPECTF--
16+
Notice: Only variable references should be returned by reference in %s on line %d

Zend/zend_closures.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -871,7 +871,7 @@ void zend_closure_from_frame(zval *return_value, zend_execute_data *call) { /* {
871871

872872
memset(&trampoline, 0, sizeof(zend_internal_function));
873873
trampoline.type = ZEND_INTERNAL_FUNCTION;
874-
trampoline.fn_flags = mptr->common.fn_flags & (ZEND_ACC_STATIC | ZEND_ACC_VARIADIC);
874+
trampoline.fn_flags = mptr->common.fn_flags & (ZEND_ACC_STATIC | ZEND_ACC_VARIADIC | ZEND_ACC_RETURN_REFERENCE);
875875
trampoline.handler = zend_closure_call_magic;
876876
trampoline.function_name = mptr->common.function_name;
877877
trampoline.scope = mptr->common.scope;

Zend/zend_compile.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1278,7 +1278,7 @@ static zend_never_inline ZEND_COLD ZEND_NORETURN void do_bind_function_error(zen
12781278
zend_error_noreturn(error_level, "Cannot redeclare function %s() (previously declared in %s:%d)",
12791279
op_array ? ZSTR_VAL(op_array->function_name) : ZSTR_VAL(old_function->common.function_name),
12801280
ZSTR_VAL(old_function->op_array.filename),
1281-
old_function->op_array.opcodes[0].lineno);
1281+
old_function->op_array.line_start);
12821282
} else {
12831283
zend_error_noreturn(error_level, "Cannot redeclare function %s()",
12841284
op_array ? ZSTR_VAL(op_array->function_name) : ZSTR_VAL(old_function->common.function_name));
@@ -8362,6 +8362,7 @@ static zend_op_array *zend_compile_func_decl_ex(
83628362
} else if (toplevel) {
83638363
/* Only register the function after a successful compile */
83648364
if (UNEXPECTED(zend_hash_add_ptr(CG(function_table), lcname, op_array) == NULL)) {
8365+
CG(zend_lineno) = decl->start_lineno;
83658366
do_bind_function_error(lcname, op_array, true);
83668367
}
83678368
}

Zend/zend_inheritance.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3849,6 +3849,8 @@ ZEND_API zend_class_entry *zend_try_early_bind(zend_class_entry *ce, zend_class_
38493849
CG(current_linking_class) = is_cacheable ? ce : NULL;
38503850

38513851
zend_try{
3852+
CG(zend_lineno) = ce->info.user.line_start;
3853+
38523854
if (is_cacheable) {
38533855
zend_begin_record_errors();
38543856
}

Zend/zend_object_handlers.c

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1614,7 +1614,10 @@ ZEND_API zend_function *zend_get_call_trampoline_func(const zend_class_entry *ce
16141614
func->arg_flags[0] = 0;
16151615
func->arg_flags[1] = 0;
16161616
func->arg_flags[2] = 0;
1617-
func->fn_flags = ZEND_ACC_CALL_VIA_TRAMPOLINE | ZEND_ACC_PUBLIC | ZEND_ACC_VARIADIC;
1617+
func->fn_flags = ZEND_ACC_CALL_VIA_TRAMPOLINE
1618+
| ZEND_ACC_PUBLIC
1619+
| ZEND_ACC_VARIADIC
1620+
| (fbc->common.fn_flags & ZEND_ACC_RETURN_REFERENCE);
16181621
if (is_static) {
16191622
func->fn_flags |= ZEND_ACC_STATIC;
16201623
}

build/gen_stub.php

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1686,7 +1686,7 @@ public function getMethodSynopsisDocument(array $funcMap, array $aliasMap): ?str
16861686
$undocumentedEntity = $doc->createEntityReference('warn.undocumented.func');
16871687
$descriptionRefSec->appendChild($undocumentedEntity);
16881688
$descriptionRefSec->appendChild(new DOMText("\n "));
1689-
$returnDescriptionPara = $doc->createElement('para');
1689+
$returnDescriptionPara = $doc->createElement('simpara');
16901690
$returnDescriptionPara->appendChild(new DOMText("\n Description.\n "));
16911691
$descriptionRefSec->appendChild($returnDescriptionPara);
16921692

@@ -1709,7 +1709,7 @@ public function getMethodSynopsisDocument(array $funcMap, array $aliasMap): ?str
17091709
$errorsDescriptionParaConstantTag->append('E_*');
17101710
$errorsDescriptionParaExceptionTag = $doc->createElement('exceptionname');
17111711
$errorsDescriptionParaExceptionTag->append('Exception');
1712-
$errorsDescriptionPara = $doc->createElement('para');
1712+
$errorsDescriptionPara = $doc->createElement('simpara');
17131713
$errorsDescriptionPara->append(
17141714
"\n When does this function issue ",
17151715
$errorsDescriptionParaConstantTag,
@@ -1813,7 +1813,7 @@ private function getParameterSection(DOMDocument $doc): DOMElement {
18131813
$parametersRefSec->appendChild($noParamEntity);
18141814
return $parametersRefSec;
18151815
} else {
1816-
$parametersPara = $doc->createElement('para');
1816+
$parametersPara = $doc->createElement('simpara');
18171817
$parametersRefSec->appendChild($parametersPara);
18181818

18191819
$parametersPara->appendChild(new DOMText("\n "));
@@ -1824,9 +1824,9 @@ private function getParameterSection(DOMDocument $doc): DOMElement {
18241824
<varlistentry>
18251825
<term><parameter>name</parameter></term>
18261826
<listitem>
1827-
<para>
1827+
<simpara>
18281828
Description.
1829-
</para>
1829+
</simpara>
18301830
</listitem>
18311831
</varlistentry>
18321832
*/
@@ -1835,7 +1835,7 @@ private function getParameterSection(DOMDocument $doc): DOMElement {
18351835
$parameterTerm = $doc->createElement('term');
18361836
$parameterTerm->appendChild($parameter);
18371837

1838-
$listItemPara = $doc->createElement('para');
1838+
$listItemPara = $doc->createElement('simpara');
18391839
$listItemPara->append(
18401840
"\n ",
18411841
"Description.",
@@ -1871,7 +1871,7 @@ private function getParameterSection(DOMDocument $doc): DOMElement {
18711871
private function getReturnValueSection(DOMDocument $doc): DOMElement {
18721872
$returnRefSec = $this->generateRefSect1($doc, 'returnvalues');
18731873

1874-
$returnDescriptionPara = $doc->createElement('para');
1874+
$returnDescriptionPara = $doc->createElement('simpara');
18751875
$returnDescriptionPara->appendChild(new DOMText("\n "));
18761876

18771877
$returnType = $this->return->getMethodSynopsisType();
@@ -2010,7 +2010,7 @@ private function getExampleSection(DOMDocument $doc, string $id): DOMElement {
20102010

20112011
$example->append("\n ", $title);
20122012

2013-
$para = $doc->createElement('para');
2013+
$para = $doc->createElement('simpara');
20142014
$para->append("\n ", "Description.", "\n ");
20152015
$example->append("\n ", $para);
20162016

ext/opcache/zend_accelerator_util_funcs.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -175,13 +175,13 @@ static zend_always_inline void _zend_accel_function_hash_copy(HashTable *target,
175175
function2 = Z_PTR_P(t);
176176
CG(in_compilation) = 1;
177177
zend_set_compiled_filename(function1->op_array.filename);
178-
CG(zend_lineno) = function1->op_array.opcodes[0].lineno;
178+
CG(zend_lineno) = function1->op_array.line_start;
179179
if (function2->type == ZEND_USER_FUNCTION
180180
&& function2->op_array.last > 0) {
181181
zend_error_noreturn(E_ERROR, "Cannot redeclare function %s() (previously declared in %s:%d)",
182182
ZSTR_VAL(function1->common.function_name),
183183
ZSTR_VAL(function2->op_array.filename),
184-
(int)function2->op_array.opcodes[0].lineno);
184+
(int)function2->op_array.line_start);
185185
} else {
186186
zend_error_noreturn(E_ERROR, "Cannot redeclare function %s()", ZSTR_VAL(function1->common.function_name));
187187
}

ext/pdo/pdo_dbh.c

Lines changed: 52 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -219,7 +219,7 @@ static char *dsn_from_uri(char *uri, char *buf, size_t buflen) /* {{{ */
219219
}
220220
/* }}} */
221221

222-
static bool create_driver_specific_pdo_object(pdo_driver_t *driver, zend_class_entry *called_scope, zval *new_object)
222+
static bool create_driver_specific_pdo_object(pdo_driver_t *driver, zend_class_entry *called_scope, zval *new_zval_object)
223223
{
224224
zend_class_entry *ce;
225225
zend_class_entry *ce_based_on_driver_name = NULL, *ce_based_on_called_object = NULL;
@@ -235,47 +235,70 @@ static bool create_driver_specific_pdo_object(pdo_driver_t *driver, zend_class_e
235235

236236
if (ce_based_on_called_object) {
237237
if (ce_based_on_driver_name) {
238-
if (instanceof_function(ce_based_on_called_object, ce_based_on_driver_name) == false) {
238+
if (!instanceof_function(ce_based_on_called_object, ce_based_on_driver_name)) {
239239
zend_throw_exception_ex(pdo_exception_ce, 0,
240-
"%s::connect() cannot be called when connecting to the \"%s\" driver, "
241-
"either %s::connect() or PDO::connect() must be called instead",
242-
ZSTR_VAL(called_scope->name), driver->driver_name, ZSTR_VAL(ce_based_on_driver_name->name));
240+
"%s::%s() cannot be used for connecting to the \"%s\" driver, "
241+
"either call %s::%s() or PDO::%s() instead",
242+
ZSTR_VAL(called_scope->name),
243+
new_zval_object ? "connect" : "__construct",
244+
driver->driver_name,
245+
ZSTR_VAL(ce_based_on_driver_name->name),
246+
new_zval_object ? "connect" : "__construct",
247+
new_zval_object ? "connect" : "__construct"
248+
);
243249
return false;
244250
}
245251

246-
/* A driver-specific implementation was instantiated via the connect() method of the appropriate driver class */
247-
object_init_ex(new_object, ce_based_on_called_object);
252+
/* A driver-specific implementation is instantiated with the appropriate driver class */
253+
if (new_zval_object) {
254+
object_init_ex(new_zval_object, called_scope);
255+
}
248256
return true;
249257
} else {
250258
zend_throw_exception_ex(pdo_exception_ce, 0,
251-
"%s::connect() cannot be called when connecting to an unknown driver, "
252-
"PDO::connect() must be called instead",
253-
ZSTR_VAL(called_scope->name));
259+
"%s::%s() cannot be used for connecting to an unknown driver, "
260+
"call PDO::%s() instead",
261+
ZSTR_VAL(called_scope->name),
262+
new_zval_object ? "connect" : "__construct",
263+
new_zval_object ? "connect" : "__construct"
264+
);
254265
return false;
255266
}
256267
}
257268

269+
/* A non-driver specific PDO subclass is instantiated via the constructor. This results in the legacy behavior. */
270+
if (called_scope != pdo_dbh_ce && new_zval_object == NULL) {
271+
return true;
272+
}
273+
258274
if (ce_based_on_driver_name) {
259275
if (called_scope != pdo_dbh_ce) {
260-
/* A driver-specific implementation was instantiated via the connect method of a wrong driver class */
276+
/* A driver-specific implementation is instantiated with a wrong driver class */
261277
zend_throw_exception_ex(pdo_exception_ce, 0,
262-
"%s::connect() cannot be called when connecting to the \"%s\" driver, "
263-
"either %s::connect() or PDO::connect() must be called instead",
264-
ZSTR_VAL(called_scope->name), driver->driver_name, ZSTR_VAL(ce_based_on_driver_name->name));
278+
"%s::%s() cannot be used for connecting to the \"%s\" driver, "
279+
"either call %s::%s() or PDO::%s() instead",
280+
ZSTR_VAL(called_scope->name),
281+
new_zval_object ? "connect" : "__construct",
282+
driver->driver_name,
283+
ZSTR_VAL(ce_based_on_driver_name->name),
284+
new_zval_object ? "connect" : "__construct",
285+
new_zval_object ? "connect" : "__construct"
286+
);
265287
return false;
266288
}
267289

268-
/* A driver-specific implementation was instantiated via PDO::__construct() */
269-
object_init_ex(new_object, ce_based_on_driver_name);
270-
} else {
290+
if (new_zval_object) {
291+
object_init_ex(new_zval_object, ce_based_on_driver_name);
292+
}
293+
} else if (new_zval_object) {
271294
/* No driver-specific implementation found */
272-
object_init_ex(new_object, called_scope);
295+
object_init_ex(new_zval_object, called_scope);
273296
}
274297

275298
return true;
276299
}
277300

278-
static void internal_construct(INTERNAL_FUNCTION_PARAMETERS, zend_object *object, zend_class_entry *current_scope, zval *new_zval_object)
301+
PDO_API void php_pdo_internal_construct_driver(INTERNAL_FUNCTION_PARAMETERS, zend_object *current_object, zend_class_entry *called_scope, zval *new_zval_object)
279302
{
280303
pdo_dbh_t *dbh = NULL;
281304
bool is_persistent = 0;
@@ -343,15 +366,16 @@ static void internal_construct(INTERNAL_FUNCTION_PARAMETERS, zend_object *object
343366
RETURN_THROWS();
344367
}
345368

346-
if (new_zval_object != NULL) {
347-
ZEND_ASSERT((driver->driver_name != NULL) && "PDO driver name is null");
348-
if (!create_driver_specific_pdo_object(driver, current_scope, new_zval_object)) {
349-
RETURN_THROWS();
350-
}
369+
ZEND_ASSERT((driver->driver_name != NULL) && "PDO driver name is null");
370+
371+
if (!create_driver_specific_pdo_object(driver, called_scope, new_zval_object)) {
372+
RETURN_THROWS();
373+
}
351374

375+
if (new_zval_object) {
352376
dbh = Z_PDO_DBH_P(new_zval_object);
353377
} else {
354-
dbh = php_pdo_dbh_fetch_inner(object);
378+
dbh = php_pdo_dbh_fetch_inner(current_object);
355379
}
356380

357381
/* is this supposed to be a persistent connection ? */
@@ -413,7 +437,7 @@ static void internal_construct(INTERNAL_FUNCTION_PARAMETERS, zend_object *object
413437
if (pdbh) {
414438
efree(dbh);
415439
/* switch over to the persistent one */
416-
php_pdo_dbh_fetch_object(object)->inner = pdbh;
440+
php_pdo_dbh_fetch_object(current_object)->inner = pdbh;
417441
pdbh->refcount++;
418442
dbh = pdbh;
419443
}
@@ -497,14 +521,14 @@ static void internal_construct(INTERNAL_FUNCTION_PARAMETERS, zend_object *object
497521
/* {{{ */
498522
PHP_METHOD(PDO, __construct)
499523
{
500-
internal_construct(INTERNAL_FUNCTION_PARAM_PASSTHRU, Z_OBJ(EX(This)), EX(This).value.ce, NULL);
524+
php_pdo_internal_construct_driver(INTERNAL_FUNCTION_PARAM_PASSTHRU, Z_OBJ_P(ZEND_THIS), Z_OBJCE_P(ZEND_THIS), NULL);
501525
}
502526
/* }}} */
503527

504528
/* {{{ */
505529
PHP_METHOD(PDO, connect)
506530
{
507-
internal_construct(INTERNAL_FUNCTION_PARAM_PASSTHRU, Z_OBJ(EX(This)), EX(This).value.ce, return_value);
531+
php_pdo_internal_construct_driver(INTERNAL_FUNCTION_PARAM_PASSTHRU, NULL, Z_CE_P(ZEND_THIS), return_value);
508532
}
509533
/* }}} */
510534

ext/pdo/php_pdo_driver.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -694,6 +694,8 @@ PDO_API void php_pdo_dbh_delref(pdo_dbh_t *dbh);
694694
PDO_API void php_pdo_free_statement(pdo_stmt_t *stmt);
695695
PDO_API void php_pdo_stmt_set_column_count(pdo_stmt_t *stmt, int new_count);
696696

697+
PDO_API void php_pdo_internal_construct_driver(INTERNAL_FUNCTION_PARAMETERS, zend_object *current_object, zend_class_entry *called_scope, zval *new_zval_object);
698+
697699
/* Normalization for fetching long param for driver attributes */
698700
PDO_API bool pdo_get_long_param(zend_long *lval, zval *value);
699701
PDO_API bool pdo_get_bool_param(bool *bval, zval *value);
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
--TEST--
2+
Test calling a PDO sub-class constructor with a different DSN
3+
--EXTENSIONS--
4+
pdo_pgsql
5+
pdo_sqlite
6+
--FILE--
7+
<?php
8+
9+
try {
10+
new Pdo\Pgsql('sqlite::memory:');
11+
} catch (PDOException $e) {
12+
echo $e->getMessage() . "\n";
13+
}
14+
15+
class MyPgsql extends Pdo\Pgsql
16+
{
17+
}
18+
19+
try {
20+
new MyPgsql('sqlite::memory:');
21+
} catch (PDOException $e) {
22+
echo $e->getMessage() . "\n";
23+
}
24+
25+
?>
26+
--EXPECT--
27+
Pdo\Pgsql::__construct() cannot be used for connecting to the "sqlite" driver, either call Pdo\Sqlite::__construct() or PDO::__construct() instead
28+
MyPgsql::__construct() cannot be used for connecting to the "sqlite" driver, either call Pdo\Sqlite::__construct() or PDO::__construct() instead

ext/pdo_sqlite/tests/subclasses/pdosqlite_005.phpt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,4 +14,4 @@ try {
1414

1515
?>
1616
--EXPECT--
17-
Pdo\Pgsql::connect() cannot be called when connecting to the "sqlite" driver, either Pdo\Sqlite::connect() or PDO::connect() must be called instead
17+
Pdo\Pgsql::connect() cannot be used for connecting to the "sqlite" driver, either call Pdo\Sqlite::connect() or PDO::connect() instead

0 commit comments

Comments
 (0)