Skip to content

Commit a89b322

Browse files
authored
Merge branch 'php:master' into true-async
2 parents 67c001f + a22dc67 commit a89b322

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

52 files changed

+785
-588
lines changed

NEWS

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,20 @@
11
PHP NEWS
22
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
3-
?? ??? ????, PHP 8.5.0alpha2
3+
?? ??? ????, PHP 8.5.0alpha3
4+
5+
- Sockets:
6+
. socket_set_option for multicast context throws a ValueError
7+
when the socket family is not of AF_INET/AF_INET6 family. (David Carlier)
8+
9+
17 Jul 2025, PHP 8.5.0alpha2
410

511
- Core:
612
. Fix OSS-Fuzz #427814452 (pipe compilation fails with assert).
713
(nielsdos, ilutov)
814

915
- DOM:
1016
. Make cloning DOM node lists, maps, and collections fail. (nielsdos)
17+
. Added Dom\Element::getElementsByClassName(). (nielsdos)
1118

1219
- PDO_ODBC
1320
. Fetch larger block sizes and better handle SQL_NO_TOTAL when calling

UPGRADING

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -371,6 +371,8 @@ PHP 8.5 UPGRADE NOTES
371371
. socket_create/socket_bind can create AF_PACKET family sockets.
372372
. socket_getsockname gets the interface index and its string
373373
representation with AF_PACKET socket.
374+
. socket_set_option with multicast context throws a ValueError
375+
when the created socket is not of AF_INET/AF_INET6 family.
374376

375377
- Tidy:
376378
. tidy::__construct/parseFile/parseString now throws a ValueError
@@ -408,6 +410,7 @@ PHP 8.5 UPGRADE NOTES
408410
RFC: https://wiki.php.net/rfc/curl_share_persistence_improvement
409411

410412
- DOM:
413+
. Added Dom\Element::getElementsByClassName().
411414
. Added Dom\Element::insertAdjacentHTML().
412415

413416
- Enchant:

Zend/Zend.m4

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -149,6 +149,7 @@ AC_CHECK_FUNCS(m4_normalize([
149149
pthread_get_stackaddr_np
150150
pthread_getattr_np
151151
pthread_stackseg_np
152+
strnlen
152153
]))
153154
154155
AC_CHECK_DECL([clock_gettime_nsec_np],

Zend/zend_constants_arginfo.h

Lines changed: 1 addition & 4 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Zend/zend_opcode.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -709,7 +709,7 @@ static void zend_check_finally_breakout(zend_op_array *op_array, uint32_t op_num
709709
}
710710
}
711711

712-
static uint32_t zend_get_brk_cont_target(const zend_op_array *op_array, const zend_op *opline) {
712+
static uint32_t zend_get_brk_cont_target(const zend_op *opline) {
713713
int nest_levels = opline->op2.num;
714714
int array_offset = opline->op1.num;
715715
zend_brk_cont_element *jmp_to;
@@ -1120,7 +1120,7 @@ ZEND_API void pass_two(zend_op_array *op_array)
11201120
case ZEND_BRK:
11211121
case ZEND_CONT:
11221122
{
1123-
uint32_t jmp_target = zend_get_brk_cont_target(op_array, opline);
1123+
uint32_t jmp_target = zend_get_brk_cont_target(opline);
11241124

11251125
if (op_array->fn_flags & ZEND_ACC_HAS_FINALLY_BLOCK) {
11261126
zend_check_finally_breakout(op_array, opline - op_array->opcodes, jmp_target);

Zend/zend_string.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -636,6 +636,12 @@ EMPTY_SWITCH_DEFAULT_CASE()
636636
_(ZEND_STR_SINCE, "since") \
637637
_(ZEND_STR_GET, "get") \
638638
_(ZEND_STR_SET, "set") \
639+
_(ZEND_STR_8_DOT_0, "8.0") \
640+
_(ZEND_STR_8_DOT_1, "8.1") \
641+
_(ZEND_STR_8_DOT_2, "8.2") \
642+
_(ZEND_STR_8_DOT_3, "8.3") \
643+
_(ZEND_STR_8_DOT_4, "8.4") \
644+
_(ZEND_STR_8_DOT_5, "8.5") \
639645

640646

641647
typedef enum _zend_known_string_id {

build/gen_stub.php

Lines changed: 129 additions & 92 deletions
Original file line numberDiff line numberDiff line change
@@ -2955,14 +2955,7 @@ protected function addModifiersToFieldSynopsis(DOMDocument $doc, DOMElement $fie
29552955
}
29562956
}
29572957

2958-
class PropertyInfo extends VariableLike
2959-
{
2960-
private /* readonly */ int $classFlags;
2961-
public /* readonly */ PropertyName $name;
2962-
private /* readonly */ ?Expr $defaultValue;
2963-
private /* readonly */ ?string $defaultValueString;
2964-
private /* readonly */ bool $isDocReadonly;
2965-
private /* readonly */ bool $isVirtual;
2958+
class StringBuilder {
29662959

29672960
// Map possible variable names to the known string constant, see
29682961
// ZEND_KNOWN_STRINGS
@@ -3065,8 +3058,90 @@ class PropertyInfo extends VariableLike
30653058
"username" => "ZEND_STR_USERNAME",
30663059
"password" => "ZEND_STR_PASSWORD",
30673060
"clone" => "ZEND_STR_CLONE",
3061+
'8.0' => 'ZEND_STR_8_DOT_0',
3062+
'8.1' => 'ZEND_STR_8_DOT_1',
3063+
'8.2' => 'ZEND_STR_8_DOT_2',
3064+
'8.3' => 'ZEND_STR_8_DOT_3',
3065+
'8.4' => 'ZEND_STR_8_DOT_4',
3066+
'8.5' => 'ZEND_STR_8_DOT_5',
30683067
];
30693068

3069+
/**
3070+
* Get an array of three strings:
3071+
* - declaration of zend_string, if needed, or empty otherwise
3072+
* - usage of that zend_string, or usage with ZSTR_KNOWN()
3073+
* - freeing the zend_string, if needed
3074+
*
3075+
* @param string $varName
3076+
* @param string $strContent
3077+
* @param ?int $minPHPCompatibility
3078+
* @param bool $interned
3079+
* @return string[]
3080+
*/
3081+
public static function getString(
3082+
string $varName,
3083+
string $content,
3084+
?int $minPHPCompatibility,
3085+
bool $interned = false
3086+
): array {
3087+
// Generally strings will not be known
3088+
$initFn = $interned ? 'zend_string_init_interned' : 'zend_string_init';
3089+
$result = [
3090+
"\tzend_string *$varName = $initFn(\"$content\", sizeof(\"$content\") - 1, 1);\n",
3091+
$varName,
3092+
"\tzend_string_release($varName);\n"
3093+
];
3094+
// For attribute values that are not freed
3095+
if ($varName === '') {
3096+
$result[0] = "$initFn(\"$content\", sizeof(\"$content\") - 1, 1);\n";
3097+
}
3098+
// If not set, use the current latest version
3099+
$allVersions = ALL_PHP_VERSION_IDS;
3100+
$minPhp = $minPHPCompatibility ?? end($allVersions);
3101+
if ($minPhp < PHP_80_VERSION_ID) {
3102+
// No known strings in 7.0
3103+
return $result;
3104+
}
3105+
$include = self::PHP_80_KNOWN;
3106+
switch ($minPhp) {
3107+
case PHP_85_VERSION_ID:
3108+
$include = array_merge($include, self::PHP_85_KNOWN);
3109+
// Intentional fall through
3110+
3111+
case PHP_84_VERSION_ID:
3112+
$include = array_merge($include, self::PHP_84_KNOWN);
3113+
// Intentional fall through
3114+
3115+
case PHP_83_VERSION_ID:
3116+
case PHP_82_VERSION_ID:
3117+
$include = array_merge($include, self::PHP_82_KNOWN);
3118+
// Intentional fall through
3119+
3120+
case PHP_81_VERSION_ID:
3121+
$include = array_merge($include, self::PHP_81_KNOWN);
3122+
break;
3123+
}
3124+
if (array_key_exists($content, $include)) {
3125+
$knownStr = $include[$content];
3126+
return [
3127+
'',
3128+
"ZSTR_KNOWN($knownStr)",
3129+
'',
3130+
];
3131+
}
3132+
return $result;
3133+
}
3134+
}
3135+
3136+
class PropertyInfo extends VariableLike
3137+
{
3138+
private /* readonly */ int $classFlags;
3139+
public /* readonly */ PropertyName $name;
3140+
private /* readonly */ ?Expr $defaultValue;
3141+
private /* readonly */ ?string $defaultValueString;
3142+
private /* readonly */ bool $isDocReadonly;
3143+
private /* readonly */ bool $isVirtual;
3144+
30703145
/**
30713146
* @param AttributeInfo[] $attributes
30723147
*/
@@ -3147,7 +3222,11 @@ public function getDeclaration(array $allConstInfos): string {
31473222
$code .= $defaultValue->initializeZval($zvalName);
31483223
}
31493224

3150-
[$stringInit, $nameCode, $stringRelease] = $this->getString($propertyName);
3225+
[$stringInit, $nameCode, $stringRelease] = StringBuilder::getString(
3226+
"property_{$propertyName}_name",
3227+
$propertyName,
3228+
$this->phpVersionIdMinimumCompatibility
3229+
);
31513230
$code .= $stringInit;
31523231

31533232
if ($this->exposedDocComment) {
@@ -3182,60 +3261,6 @@ public function getDeclaration(array $allConstInfos): string {
31823261
return $code;
31833262
}
31843263

3185-
/**
3186-
* Get an array of three strings:
3187-
* - declaration of zend_string, if needed, or empty otherwise
3188-
* - usage of that zend_string, or usage with ZSTR_KNOWN()
3189-
* - freeing the zend_string, if needed
3190-
*
3191-
* @param string $propName
3192-
* @return string[]
3193-
*/
3194-
private function getString(string $propName): array {
3195-
// Generally strings will not be known
3196-
$nameCode = "property_{$propName}_name";
3197-
$result = [
3198-
"\tzend_string *$nameCode = zend_string_init(\"$propName\", sizeof(\"$propName\") - 1, 1);\n",
3199-
$nameCode,
3200-
"\tzend_string_release($nameCode);\n"
3201-
];
3202-
// If not set, use the current latest version
3203-
$allVersions = ALL_PHP_VERSION_IDS;
3204-
$minPhp = $this->phpVersionIdMinimumCompatibility ?? end($allVersions);
3205-
if ($minPhp < PHP_80_VERSION_ID) {
3206-
// No known strings in 7.0
3207-
return $result;
3208-
}
3209-
$include = self::PHP_80_KNOWN;
3210-
switch ($minPhp) {
3211-
case PHP_85_VERSION_ID:
3212-
$include = array_merge($include, self::PHP_85_KNOWN);
3213-
// Intentional fall through
3214-
3215-
case PHP_84_VERSION_ID:
3216-
$include = array_merge($include, self::PHP_84_KNOWN);
3217-
// Intentional fall through
3218-
3219-
case PHP_83_VERSION_ID:
3220-
case PHP_82_VERSION_ID:
3221-
$include = array_merge($include, self::PHP_82_KNOWN);
3222-
// Intentional fall through
3223-
3224-
case PHP_81_VERSION_ID:
3225-
$include = array_merge($include, self::PHP_81_KNOWN);
3226-
break;
3227-
}
3228-
if (array_key_exists($propName, $include)) {
3229-
$knownStr = $include[$propName];
3230-
return [
3231-
'',
3232-
"ZSTR_KNOWN($knownStr)",
3233-
'',
3234-
];
3235-
}
3236-
return $result;
3237-
}
3238-
32393264
/**
32403265
* @return array<int, string[]>
32413266
*/
@@ -3326,40 +3351,52 @@ public function __construct(string $class, array $args) {
33263351

33273352
/** @param array<string, ConstInfo> $allConstInfos */
33283353
public function generateCode(string $invocation, string $nameSuffix, array $allConstInfos, ?int $phpVersionIdMinimumCompatibility): string {
3329-
$php82MinimumCompatibility = $phpVersionIdMinimumCompatibility === null || $phpVersionIdMinimumCompatibility >= PHP_82_VERSION_ID;
3330-
$php84MinimumCompatibility = $phpVersionIdMinimumCompatibility === null || $phpVersionIdMinimumCompatibility >= PHP_84_VERSION_ID;
3331-
/* see ZEND_KNOWN_STRINGS in Zend/strings.h */
3332-
$knowns = [
3333-
"message" => "ZEND_STR_MESSAGE",
3334-
];
3335-
if ($php82MinimumCompatibility) {
3336-
$knowns["SensitiveParameter"] = "ZEND_STR_SENSITIVEPARAMETER";
3337-
}
3338-
if ($php84MinimumCompatibility) {
3339-
$knowns["Deprecated"] = "ZEND_STR_DEPRECATED_CAPITALIZED";
3340-
$knowns["since"] = "ZEND_STR_SINCE";
3341-
}
3342-
3343-
$code = "\n";
33443354
$escapedAttributeName = strtr($this->class, '\\', '_');
3345-
if (isset($knowns[$escapedAttributeName])) {
3346-
$code .= "\t" . ($this->args ? "zend_attribute *attribute_{$escapedAttributeName}_$nameSuffix = " : "") . "$invocation, ZSTR_KNOWN({$knowns[$escapedAttributeName]}), " . count($this->args) . ");\n";
3347-
} else {
3348-
$code .= "\tzend_string *attribute_name_{$escapedAttributeName}_$nameSuffix = zend_string_init_interned(\"" . addcslashes($this->class, "\\") . "\", sizeof(\"" . addcslashes($this->class, "\\") . "\") - 1, 1);\n";
3349-
$code .= "\t" . ($this->args ? "zend_attribute *attribute_{$escapedAttributeName}_$nameSuffix = " : "") . "$invocation, attribute_name_{$escapedAttributeName}_$nameSuffix, " . count($this->args) . ");\n";
3350-
$code .= "\tzend_string_release(attribute_name_{$escapedAttributeName}_$nameSuffix);\n";
3351-
}
3355+
[$stringInit, $nameCode, $stringRelease] = StringBuilder::getString(
3356+
"attribute_name_{$escapedAttributeName}_$nameSuffix",
3357+
addcslashes($this->class, "\\"),
3358+
$phpVersionIdMinimumCompatibility,
3359+
true
3360+
);
3361+
$code = "\n";
3362+
$code .= $stringInit;
3363+
$code .= "\t" . ($this->args ? "zend_attribute *attribute_{$escapedAttributeName}_$nameSuffix = " : "") . "$invocation, $nameCode, " . count($this->args) . ");\n";
3364+
$code .= $stringRelease;
3365+
33523366
foreach ($this->args as $i => $arg) {
3353-
$value = EvaluatedValue::createFromExpression($arg->value, null, null, $allConstInfos);
3354-
$zvalName = "attribute_{$escapedAttributeName}_{$nameSuffix}_arg$i";
3355-
$code .= $value->initializeZval($zvalName);
3356-
$code .= "\tZVAL_COPY_VALUE(&attribute_{$escapedAttributeName}_{$nameSuffix}->args[$i].value, &$zvalName);\n";
3367+
$initValue = '';
3368+
if ($arg->value instanceof Node\Scalar\String_) {
3369+
$strVal = $arg->value->value;
3370+
[$strInit, $strUse, $strRelease] = StringBuilder::getString(
3371+
'unused',
3372+
$strVal,
3373+
$phpVersionIdMinimumCompatibility
3374+
);
3375+
if ($strInit === '') {
3376+
$initValue = "\tZVAL_STR(&attribute_{$escapedAttributeName}_{$nameSuffix}->args[$i].value, $strUse);\n";
3377+
}
3378+
}
3379+
if ($initValue === '') {
3380+
$value = EvaluatedValue::createFromExpression($arg->value, null, null, $allConstInfos);
3381+
$zvalName = "attribute_{$escapedAttributeName}_{$nameSuffix}_arg$i";
3382+
$code .= $value->initializeZval($zvalName);
3383+
$code .= "\tZVAL_COPY_VALUE(&attribute_{$escapedAttributeName}_{$nameSuffix}->args[$i].value, &$zvalName);\n";
3384+
} else {
3385+
$code .= $initValue;
3386+
}
33573387
if ($arg->name) {
3358-
if (isset($knowns[$arg->name->name])) {
3359-
$code .= "\tattribute_{$escapedAttributeName}_{$nameSuffix}->args[$i].name = ZSTR_KNOWN({$knowns[$arg->name->name]});\n";
3388+
[$stringInit, $nameCode, $stringRelease] = StringBuilder::getString(
3389+
"",
3390+
$arg->name->name,
3391+
$phpVersionIdMinimumCompatibility,
3392+
true
3393+
);
3394+
if ($stringInit === '') {
3395+
$nameCode .= ";\n";
33603396
} else {
3361-
$code .= "\tattribute_{$escapedAttributeName}_{$nameSuffix}->args[$i].name = zend_string_init_interned(\"{$arg->name->name}\", sizeof(\"{$arg->name->name}\") - 1, 1);\n";
3397+
$nameCode = $stringInit;
33623398
}
3399+
$code .= "\tattribute_{$escapedAttributeName}_{$nameSuffix}->args[$i].name = $nameCode";
33633400
}
33643401
}
33653402
return $code;

configure.ac

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -577,7 +577,6 @@ AC_CHECK_FUNCS(m4_normalize([
577577
statvfs
578578
std_syslog
579579
strcasecmp
580-
strnlen
581580
strptime
582581
strtok_r
583582
symlink

ext/curl/curl_arginfo.h

Lines changed: 1 addition & 4 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)