Skip to content

Commit 7eec5f5

Browse files
committed
Merge tag 'php-8.1.21' into was-8.1.x
Tag for php 8.1.21
2 parents a66ae7e + badfe4f commit 7eec5f5

File tree

135 files changed

+4145
-620
lines changed

Some content is hidden

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

135 files changed

+4145
-620
lines changed

.cirrus.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,7 @@ arm_task:
6262
libgmp-dev
6363
libicu-dev
6464
libtidy-dev
65-
libenchant-dev
65+
libenchant-2-dev
6666
libaspell-dev
6767
libpspell-dev
6868
libsasl2-dev

.github/actions/setup-x64/action.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ runs:
1717
docker exec sql1 /opt/mssql-tools/bin/sqlcmd -S 127.0.0.1 -U SA -P "<YourStrong@Passw0rd>" -Q "create login pdo_test with password='password', check_policy=off; create user pdo_test for login pdo_test; grant alter, control to pdo_test;"
1818
sudo locale-gen de_DE
1919
20-
./.github/scripts/setup-slapd.sh &>/dev/null
20+
./.github/scripts/setup-slapd.sh
2121
2222
sudo cp ext/snmp/tests/snmpd.conf /etc/snmp
2323
sudo cp ext/snmp/tests/bigtest /etc/snmp

.github/workflows/nightly.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -632,7 +632,7 @@ jobs:
632632
with:
633633
# FIXME: There are new warnings
634634
# configurationParameters: --enable-werror
635-
libmysql: mysql-8.0.30-linux-glibc2.12-x86_64.tar.xz
635+
libmysql: mysql-8.0.33-linux-glibc2.12-x86_64.tar.xz
636636
withMysqli: ${{ matrix.branch.ref == 'PHP-8.1' }}
637637
- name: Test mysql-8.0
638638
uses: ./.github/actions/test-libmysqlclient

NEWS

Lines changed: 133 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,138 @@
11
PHP NEWS
22
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
3+
06 Jun 2023, PHP 8.1.21
4+
5+
- CLI:
6+
. Fixed bug GH-11246 (cli/get_set_process_title fails on MacOS).
7+
(James Lucas)
8+
9+
- Core:
10+
. Fixed build for the riscv64 architecture/GCC 12. (Daniil Gentili)
11+
12+
- Curl:
13+
. Fixed bug GH-11433 (Unable to set CURLOPT_ACCEPT_ENCODING to NULL).
14+
(nielsdos)
15+
16+
- DOM:
17+
. Fixed bugs GH-11288 and GH-11289 and GH-11290 and GH-9142 (DOMExceptions
18+
and segfaults with replaceWith). (nielsdos)
19+
. Fixed bug GH-10234 (Setting DOMAttr::textContent results in an empty
20+
attribute value). (nielsdos)
21+
. Fix return value in stub file for DOMNodeList::item. (divinity76)
22+
. Fix spec compliance error with '*' namespace for
23+
DOMDocument::getElementsByTagNameNS. (nielsdos)
24+
. Fix DOMElement::append() and DOMElement::prepend() hierarchy checks.
25+
(nielsdos)
26+
. Fixed bug GH-11347 (Memory leak when calling a static method inside an
27+
xpath query). (nielsdos)
28+
. Fixed bug #67440 (append_node of a DOMDocumentFragment does not reconcile
29+
namespaces). (nielsdos)
30+
. Fixed bug #81642 (DOMChildNode::replaceWith() bug when replacing a node
31+
with itself). (nielsdos)
32+
. Fixed bug #77686 (Removed elements are still returned by getElementById).
33+
(nielsdos)
34+
. Fixed bug #70359 (print_r() on DOMAttr causes Segfault in
35+
php_libxml_node_free_list()). (nielsdos)
36+
. Fixed bug #78577 (Crash in DOMNameSpace debug info handlers). (nielsdos)
37+
. Fix lifetime issue with getAttributeNodeNS(). (nielsdos)
38+
. Fix "invalid state error" with cloned namespace declarations. (nielsdos)
39+
. Fixed bug #55294 and #47530 and #47847 (various namespace reconciliation
40+
issues). (nielsdos)
41+
. Fixed bug #80332 (Completely broken array access functionality with
42+
DOMNamedNodeMap). (nielsdos)
43+
44+
- Opcache:
45+
. Fix allocation loop in zend_shared_alloc_startup(). (nielsdos)
46+
. Access violation on smm_shared_globals with ALLOC_FALLBACK. (KoudelkaB)
47+
. Fixed bug GH-11336 (php still tries to unlock the shared memory ZendSem
48+
with opcache.file_cache_only=1 but it was never locked). (nielsdos)
49+
50+
- OpenSSL:
51+
. Fixed bug GH-9356 Incomplete validation of IPv6 Address fields in
52+
subjectAltNames (James Lucas, Jakub Zelenka).
53+
54+
- PGSQL:
55+
. Fixed intermittent segfault with pg_trace. (David Carlier)
56+
57+
- Phar:
58+
. Fix cross-compilation check in phar generation for FreeBSD. (peter279k)
59+
60+
- SPL:
61+
. Fixed bug GH-11338 (SplFileInfo empty getBasename with more than one
62+
slash). (nielsdos)
63+
64+
- Standard:
65+
. Fix access on NULL pointer in array_merge_recursive(). (ilutov)
66+
. Fix exception handling in array_multisort(). (ilutov)
67+
68+
08 Jun 2023, PHP 8.1.20
69+
70+
- Core:
71+
. Fixed bug GH-9068 (Conditional jump or move depends on uninitialised
72+
value(s)). (nielsdos)
73+
. Fixed bug GH-11189 (Exceeding memory limit in zend_hash_do_resize leaves
74+
the array in an invalid state). (Bob)
75+
. Fixed bug GH-11222 (foreach by-ref may jump over keys during a rehash).
76+
(Bob)
77+
78+
- Date:
79+
. Fixed bug GH-11281 (DateTimeZone::getName() does not include seconds in
80+
offset). (nielsdos)
81+
82+
- Exif:
83+
. Fixed bug GH-10834 (exif_read_data() cannot read smaller stream wrapper
84+
chunk sizes). (nielsdos)
85+
86+
- FPM:
87+
. Fixed bug GH-10461 (PHP-FPM segfault due to after free usage of
88+
child->ev_std(out|err)). (Jakub Zelenka)
89+
. Fixed bug #64539 (FPM status page: query_string not properly JSON encoded).
90+
(Jakub Zelenka)
91+
. Fixed memory leak for invalid primary script file handle. (Jakub Zelenka)
92+
93+
- Hash:
94+
. Fixed bug GH-11180 (hash_file() appears to be restricted to 3 arguments).
95+
(nielsdos)
96+
97+
- LibXML:
98+
. Fixed bug GH-11160 (Few tests failed building with new libxml 2.11.0).
99+
(nielsdos)
100+
101+
- Opcache:
102+
. Fixed bug GH-11134 (Incorrect match default branch optimization). (ilutov)
103+
. Fixed too wide OR and AND range inference. (nielsdos)
104+
. Fixed bug GH-11245 (In some specific cases SWITCH with one default
105+
statement will cause segfault). (nielsdos)
106+
107+
- PGSQL:
108+
. Fixed parameter parsing of pg_lo_export(). (kocsismate)
109+
110+
- Phar:
111+
. Fixed bug GH-11099 (Generating phar.php during cross-compile can't be
112+
done). (peter279k)
113+
114+
- Soap:
115+
. Fixed bug GHSA-76gg-c692-v2mw (Missing error check and insufficient random
116+
bytes in HTTP Digest authentication for SOAP). (nielsdos, timwolla)
117+
. Fixed bug GH-8426 (make test fail while soap extension build). (nielsdos)
118+
119+
- SPL:
120+
. Fixed bug GH-11178 (Segmentation fault in spl_array_it_get_current_data
121+
(PHP 8.1.18)). (nielsdos)
122+
123+
- Standard:
124+
. Fixed bug GH-11138 (move_uploaded_file() emits open_basedir warning for
125+
source file). (ilutov)
126+
. Fixed bug GH-11274 (POST/PATCH request switches to GET after a HTTP 308
127+
redirect). (nielsdos)
128+
129+
- Streams:
130+
. Fixed bug GH-10031 ([Stream] STREAM_NOTIFY_PROGRESS over HTTP emitted
131+
irregularly for last chunk of data). (nielsdos)
132+
. Fixed bug GH-11175 (Stream Socket Timeout). (nielsdos)
133+
. Fixed bug GH-11177 (ASAN UndefinedBehaviorSanitizer when timeout = -1
134+
passed to stream_socket_accept/stream_socket_client). (nielsdos)
135+
3136
11 May 2023, PHP 8.1.19
4137

5138
- Core:

Zend/Optimizer/block_pass.c

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -257,6 +257,10 @@ static void zend_optimize_block(zend_basic_block *block, zend_op_array *op_array
257257
break;
258258

259259
case ZEND_FREE:
260+
/* Note: Only remove the source if the source is local to this block.
261+
* If it's not local, then the other blocks successors must also eventually either FREE or consume the temporary,
262+
* hence removing the temporary is not safe in the general case, especially when other consumers are not FREE.
263+
* A FREE may not be removed without also removing the source's result, because otherwise that would cause a memory leak. */
260264
if (opline->op1_type == IS_TMP_VAR) {
261265
src = VAR_SOURCE(opline->op1);
262266
if (src) {
@@ -265,6 +269,7 @@ static void zend_optimize_block(zend_basic_block *block, zend_op_array *op_array
265269
case ZEND_BOOL_NOT:
266270
/* T = BOOL(X), FREE(T) => T = BOOL(X) */
267271
/* The remaining BOOL is removed by a separate optimization */
272+
/* The source is a bool, no source removals take place, so this may be done non-locally. */
268273
VAR_SOURCE(opline->op1) = NULL;
269274
MAKE_NOP(opline);
270275
++(*opt_count);
@@ -283,6 +288,9 @@ static void zend_optimize_block(zend_basic_block *block, zend_op_array *op_array
283288
case ZEND_PRE_DEC_OBJ:
284289
case ZEND_PRE_INC_STATIC_PROP:
285290
case ZEND_PRE_DEC_STATIC_PROP:
291+
if (src < op_array->opcodes + block->start) {
292+
break;
293+
}
286294
src->result_type = IS_UNUSED;
287295
VAR_SOURCE(opline->op1) = NULL;
288296
MAKE_NOP(opline);
@@ -295,7 +303,7 @@ static void zend_optimize_block(zend_basic_block *block, zend_op_array *op_array
295303
} else if (opline->op1_type == IS_VAR) {
296304
src = VAR_SOURCE(opline->op1);
297305
/* V = OP, FREE(V) => OP. NOP */
298-
if (src &&
306+
if (src >= op_array->opcodes + block->start &&
299307
src->opcode != ZEND_FETCH_R &&
300308
src->opcode != ZEND_FETCH_STATIC_PROP_R &&
301309
src->opcode != ZEND_FETCH_DIM_R &&

Zend/Optimizer/dfa_pass.c

Lines changed: 19 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1000,32 +1000,41 @@ static int zend_dfa_optimize_jmps(zend_op_array *op_array, zend_ssa *ssa)
10001000
|| (opline->opcode == ZEND_SWITCH_STRING && type == IS_STRING)
10011001
|| (opline->opcode == ZEND_MATCH && (type == IS_LONG || type == IS_STRING));
10021002

1003-
if (!correct_type) {
1003+
/* Switch statements have a fallback chain for loose comparison. In those
1004+
* cases the SWITCH_* instruction is a NOP. Match does strict comparison and
1005+
* thus jumps to the default branch on mismatched types, so we need to
1006+
* convert MATCH to a jmp. */
1007+
if (!correct_type && opline->opcode != ZEND_MATCH) {
10041008
removed_ops++;
10051009
MAKE_NOP(opline);
10061010
opline->extended_value = 0;
10071011
take_successor_ex(ssa, block_num, block, block->successors[block->successors_count - 1]);
10081012
goto optimize_nop;
1009-
} else {
1013+
}
1014+
1015+
uint32_t target;
1016+
if (correct_type) {
10101017
HashTable *jmptable = Z_ARRVAL_P(CT_CONSTANT_EX(op_array, opline->op2.constant));
10111018
zval *jmp_zv = type == IS_LONG
10121019
? zend_hash_index_find(jmptable, Z_LVAL_P(zv))
10131020
: zend_hash_find(jmptable, Z_STR_P(zv));
10141021

1015-
uint32_t target;
10161022
if (jmp_zv) {
10171023
target = ZEND_OFFSET_TO_OPLINE_NUM(op_array, opline, Z_LVAL_P(jmp_zv));
10181024
} else {
10191025
target = ZEND_OFFSET_TO_OPLINE_NUM(op_array, opline, opline->extended_value);
10201026
}
1021-
opline->opcode = ZEND_JMP;
1022-
opline->extended_value = 0;
1023-
SET_UNUSED(opline->op1);
1024-
ZEND_SET_OP_JMP_ADDR(opline, opline->op1, op_array->opcodes + target);
1025-
SET_UNUSED(opline->op2);
1026-
take_successor_ex(ssa, block_num, block, ssa->cfg.map[target]);
1027-
goto optimize_jmp;
1027+
} else {
1028+
ZEND_ASSERT(opline->opcode == ZEND_MATCH);
1029+
target = ZEND_OFFSET_TO_OPLINE_NUM(op_array, opline, opline->extended_value);
10281030
}
1031+
opline->opcode = ZEND_JMP;
1032+
opline->extended_value = 0;
1033+
SET_UNUSED(opline->op1);
1034+
ZEND_SET_OP_JMP_ADDR(opline, opline->op1, op_array->opcodes + target);
1035+
SET_UNUSED(opline->op2);
1036+
take_successor_ex(ssa, block_num, block, ssa->cfg.map[target]);
1037+
goto optimize_jmp;
10291038
}
10301039
break;
10311040
case ZEND_NOP:

Zend/Optimizer/zend_inference.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -436,7 +436,7 @@ static void zend_ssa_range_or(zend_long a, zend_long b, zend_long c, zend_long d
436436
int x = ((a < 0) ? 8 : 0) |
437437
((b < 0) ? 4 : 0) |
438438
((c < 0) ? 2 : 0) |
439-
((d < 0) ? 2 : 0);
439+
((d < 0) ? 1 : 0);
440440
switch (x) {
441441
case 0x0:
442442
case 0x3:
@@ -484,7 +484,7 @@ static void zend_ssa_range_and(zend_long a, zend_long b, zend_long c, zend_long
484484
int x = ((a < 0) ? 8 : 0) |
485485
((b < 0) ? 4 : 0) |
486486
((c < 0) ? 2 : 0) |
487-
((d < 0) ? 2 : 0);
487+
((d < 0) ? 1 : 0);
488488
switch (x) {
489489
case 0x0:
490490
case 0x3:
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
--TEST--
2+
Access on NULL pointer in array_merge_recursive()
3+
--FILE--
4+
<?php
5+
try {
6+
array_merge_recursive(
7+
['' => [PHP_INT_MAX => null]],
8+
['' => [null]],
9+
);
10+
} catch (Throwable $e) {
11+
echo $e->getMessage(), "\n";
12+
}
13+
14+
try {
15+
array_merge_recursive(
16+
['foo' => [PHP_INT_MAX => null]],
17+
['foo' => str_repeat('a', 2)],
18+
);
19+
} catch (Throwable $e) {
20+
echo $e->getMessage(), "\n";
21+
}
22+
?>
23+
--EXPECT--
24+
Cannot add element to the array as the next element is already occupied
25+
Cannot add element to the array as the next element is already occupied
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
--TEST--
2+
Exception handling in array_multisort()
3+
--FILE--
4+
<?php
5+
$array = [1 => new DateTime(), 0 => new DateTime()];
6+
array_multisort($array, SORT_STRING);
7+
?>
8+
--EXPECTF--
9+
Fatal error: Uncaught Error: Object of class DateTime could not be converted to string in %s:%d
10+
Stack trace:
11+
#0 %s(%d): array_multisort(Array, 2)
12+
#1 {main}
13+
thrown in %s on line %d

Zend/tests/gh11138.phpt

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
--TEST--
2+
move_uploaded_file() emits open_basedir warning for source file
3+
--POST_RAW--
4+
Content-type: multipart/form-data, boundary=AaB03x
5+
6+
--AaB03x
7+
content-disposition: form-data; name="file"; filename="file.txt"
8+
Content-Type: text/plain
9+
10+
foo
11+
--AaB03x--
12+
--FILE--
13+
<?php
14+
15+
ini_set('open_basedir', __DIR__);
16+
17+
$destination = __DIR__ . '/gh11138.tmp';
18+
var_dump(move_uploaded_file($_FILES['file']['tmp_name'], $destination));
19+
echo file_get_contents($destination), "\n";
20+
21+
?>
22+
--CLEAN--
23+
<?php
24+
@unlink(__DIR__ . '/gh11138.tmp');
25+
?>
26+
--EXPECT--
27+
bool(true)
28+
foo

0 commit comments

Comments
 (0)