Skip to content

Commit a66ae7e

Browse files
committed
Merge tag 'php-8.1.19' into was-8.1.x
Tag for php 8.1.19
2 parents ec856d0 + b0c0fa7 commit a66ae7e

File tree

83 files changed

+1373
-283
lines changed

Some content is hidden

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

83 files changed

+1373
-283
lines changed

.github/actions/apt-x32/action.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ runs:
1313
apt-get install -y \
1414
autoconf \
1515
bison \
16+
curl \
1617
g++-multilib \
1718
gcc-multilib \
1819
language-pack-de \

.github/actions/brew/action.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ runs:
1212
re2c
1313
brew install \
1414
15+
curl \
1516
krb5 \
1617
bzip2 \
1718
enchant \

.github/actions/configure-macos/action.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ runs:
1111
set -x
1212
export PATH="/usr/local/opt/bison/bin:$PATH"
1313
export PKG_CONFIG_PATH="$PKG_CONFIG_PATH:/usr/local/opt/[email protected]/lib/pkgconfig"
14+
export PKG_CONFIG_PATH="$PKG_CONFIG_PATH:/usr/local/opt/curl/lib/pkgconfig"
1415
export PKG_CONFIG_PATH="$PKG_CONFIG_PATH:/usr/local/opt/krb5/lib/pkgconfig"
1516
export PKG_CONFIG_PATH="$PKG_CONFIG_PATH:/usr/local/opt/libffi/lib/pkgconfig"
1617
export PKG_CONFIG_PATH="$PKG_CONFIG_PATH:/usr/local/opt/libxml2/lib/pkgconfig"
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
name: Notify Slack
2+
inputs:
3+
token:
4+
required: true
5+
runs:
6+
using: composite
7+
steps:
8+
- shell: bash
9+
run: >-
10+
curl -X POST -H 'Content-type: application/json' --data '{"attachments": [{"text": "Job in *nightly* failed", "footer": "<https://github.com/php/php-src/actions/runs/${{ github.run_id }}|View Run>", "color": "danger", "mrkdwn_in": ["text"]}]}' ${{ inputs.token }}

.github/workflows/nightly.yml

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,11 @@ jobs:
3030
- name: Generate Matrix
3131
id: set-matrix
3232
run: php .github/nightly_matrix.php "${{ github.event_name }}" "${{ github.run_attempt }}"
33+
- name: Notify Slack
34+
if: failure()
35+
uses: ./.github/actions/notify-slack
36+
with:
37+
token: ${{ secrets.ACTION_MONITORING_SLACK }}
3338
LINUX_X64:
3439
needs: GENERATE_MATRIX
3540
if: ${{ needs.GENERATE_MATRIX.outputs.branches != '[]' }}
@@ -104,6 +109,11 @@ jobs:
104109
-d opcache.jit=1205
105110
- name: Verify generated files are up to date
106111
uses: ./.github/actions/verify-generated-files
112+
- name: Notify Slack
113+
if: failure()
114+
uses: ./.github/actions/notify-slack
115+
with:
116+
token: ${{ secrets.ACTION_MONITORING_SLACK }}
107117
LINUX_X32:
108118
needs: GENERATE_MATRIX
109119
if: ${{ needs.GENERATE_MATRIX.outputs.branches != '[]' }}
@@ -175,6 +185,11 @@ jobs:
175185
-d opcache.enable_cli=1
176186
-d opcache.jit_buffer_size=16M
177187
-d opcache.jit=1205
188+
- name: Notify Slack
189+
if: failure()
190+
uses: ./.github/actions/notify-slack
191+
with:
192+
token: ${{ secrets.ACTION_MONITORING_SLACK }}
178193
MACOS:
179194
needs: GENERATE_MATRIX
180195
if: ${{ needs.GENERATE_MATRIX.outputs.branches != '[]' }}
@@ -233,6 +248,11 @@ jobs:
233248
-d opcache.jit=1205
234249
- name: Verify generated files are up to date
235250
uses: ./.github/actions/verify-generated-files
251+
- name: Notify Slack
252+
if: failure()
253+
uses: ./.github/actions/notify-slack
254+
with:
255+
token: ${{ secrets.ACTION_MONITORING_SLACK }}
236256
COVERAGE_DEBUG_NTS:
237257
if: github.repository_owner == 'php' || github.event_name == 'workflow_dispatch'
238258
runs-on: ubuntu-20.04
@@ -267,6 +287,11 @@ jobs:
267287
- name: Upload Test Coverage to Codecov.io
268288
if: always()
269289
run: bash <(curl -s https://codecov.io/bash)
290+
- name: Notify Slack
291+
if: failure()
292+
uses: ./.github/actions/notify-slack
293+
with:
294+
token: ${{ secrets.ACTION_MONITORING_SLACK }}
270295
COMMUNITY:
271296
needs: GENERATE_MATRIX
272297
if: ${{ needs.GENERATE_MATRIX.outputs.branches != '[]' }}
@@ -382,6 +407,11 @@ jobs:
382407
if [ $EXIT_CODE -gt 128 ]; then
383408
exit 1
384409
fi
410+
- name: Notify Slack
411+
if: failure()
412+
uses: ./.github/actions/notify-slack
413+
with:
414+
token: ${{ secrets.ACTION_MONITORING_SLACK }}
385415
OPCACHE_VARIATION:
386416
needs: GENERATE_MATRIX
387417
if: ${{ needs.GENERATE_MATRIX.outputs.branches != '[]' }}
@@ -453,6 +483,11 @@ jobs:
453483
-d opcache.file_cache_only=1
454484
- name: Verify generated files are up to date
455485
uses: ./.github/actions/verify-generated-files
486+
- name: Notify Slack
487+
if: failure()
488+
uses: ./.github/actions/notify-slack
489+
with:
490+
token: ${{ secrets.ACTION_MONITORING_SLACK }}
456491
MSAN:
457492
needs: GENERATE_MATRIX
458493
if: ${{ needs.GENERATE_MATRIX.outputs.branches != '[]' }}
@@ -545,6 +580,11 @@ jobs:
545580
-d opcache.enable_cli=1
546581
- name: Verify generated files are up to date
547582
uses: ./.github/actions/verify-generated-files
583+
- name: Notify Slack
584+
if: failure()
585+
uses: ./.github/actions/notify-slack
586+
with:
587+
token: ${{ secrets.ACTION_MONITORING_SLACK }}
548588
LIBMYSQLCLIENT:
549589
needs: GENERATE_MATRIX
550590
if: ${{ needs.GENERATE_MATRIX.outputs.branches != '[]' }}
@@ -600,3 +640,8 @@ jobs:
600640
withMysqli: ${{ matrix.branch.ref == 'PHP-8.1' }}
601641
- name: Verify generated files are up to date
602642
uses: ./.github/actions/verify-generated-files
643+
- name: Notify Slack
644+
if: failure()
645+
uses: ./.github/actions/notify-slack
646+
with:
647+
token: ${{ secrets.ACTION_MONITORING_SLACK }}

NEWS

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,38 @@
11
PHP NEWS
22
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
3+
11 May 2023, PHP 8.1.19
4+
5+
- Core:
6+
. Fix inconsistent float negation in constant expressions. (ilutov)
7+
. Fixed bug GH-8841 (php-cli core dump calling a badly formed function).
8+
(nielsdos)
9+
. Fixed bug GH-10737 (PHP 8.1.16 segfaults on line 597 of
10+
sapi/apache2handler/sapi_apache2.c). (nielsdos, ElliotNB)
11+
. Fixed bug GH-11028 (Heap Buffer Overflow in zval_undefined_cv.). (nielsdos)
12+
. Fixed bug GH-11108 (Incorrect CG(memoize_mode) state after bailout in ??=).
13+
(ilutov)
14+
15+
- DOM:
16+
. Fixed bug #80602 (Segfault when using DOMChildNode::before()).
17+
(Nathan Freeman)
18+
. Fixed incorrect error handling in dom_zvals_to_fragment(). (nielsdos)
19+
20+
- Exif:
21+
. Fixed bug GH-9397 (exif read : warnings and errors : Potentially invalid
22+
endianess, Illegal IFD size and Undefined index). (nielsdos)
23+
24+
- Intl:
25+
. Fixed bug GH-11071 (TZData version not displayed anymore). (Remi)
26+
27+
- PCRE:
28+
. Fixed bug GH-10968 (Segfault in preg_replace_callback_array()). (ilutov)
29+
30+
- Standard:
31+
. Fixed bug GH-10990 (mail() throws TypeError after iterating over
32+
$additional_headers array by reference). (nielsdos)
33+
. Fixed bug GH-9775 (Duplicates returned by array_unique when using enums).
34+
(ilutov)
35+
336
13 Apr 2023, PHP 8.1.18
437

538
- Core:

TSRM/TSRM.c

Lines changed: 70 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -161,6 +161,23 @@ TSRM_API int tsrm_startup(int expected_threads, int expected_resources, int debu
161161
return 1;
162162
}/*}}}*/
163163

164+
static void ts_free_resources(tsrm_tls_entry *thread_resources)
165+
{
166+
/* Need to destroy in reverse order to respect dependencies. */
167+
for (int i = thread_resources->count - 1; i >= 0; i--) {
168+
if (!resource_types_table[i].done) {
169+
if (resource_types_table[i].dtor) {
170+
resource_types_table[i].dtor(thread_resources->storage[i]);
171+
}
172+
173+
if (!resource_types_table[i].fast_offset) {
174+
free(thread_resources->storage[i]);
175+
}
176+
}
177+
}
178+
179+
free(thread_resources->storage);
180+
}
164181

165182
/* Shutdown TSRM (call once for the entire process) */
166183
TSRM_API void tsrm_shutdown(void)
@@ -183,25 +200,13 @@ TSRM_API void tsrm_shutdown(void)
183200
tsrm_tls_entry *p = tsrm_tls_table[i], *next_p;
184201

185202
while (p) {
186-
int j;
187-
188203
next_p = p->next;
189-
for (j=0; j<p->count; j++) {
190-
if (p->storage[j]) {
191-
if (resource_types_table) {
192-
if (!resource_types_table[j].done) {
193-
if (resource_types_table[j].dtor) {
194-
resource_types_table[j].dtor(p->storage[j]);
195-
}
196-
197-
if (!resource_types_table[j].fast_offset) {
198-
free(p->storage[j]);
199-
}
200-
}
201-
}
202-
}
204+
if (resource_types_table) {
205+
/* This call will already free p->storage for us */
206+
ts_free_resources(p);
207+
} else {
208+
free(p->storage);
203209
}
204-
free(p->storage);
205210
free(p);
206211
p = next_p;
207212
}
@@ -367,7 +372,13 @@ TSRM_API ts_rsrc_id ts_allocate_fast_id(ts_rsrc_id *rsrc_id, size_t *offset, siz
367372
return *rsrc_id;
368373
}/*}}}*/
369374

375+
static void set_thread_local_storage_resource_to(tsrm_tls_entry *thread_resource)
376+
{
377+
tsrm_tls_set(thread_resource);
378+
TSRMLS_CACHE = thread_resource;
379+
}
370380

381+
/* Must be called with tsmm_mutex held */
371382
static void allocate_new_resource(tsrm_tls_entry **thread_resources_ptr, THREAD_T thread_id)
372383
{/*{{{*/
373384
int i;
@@ -383,8 +394,7 @@ static void allocate_new_resource(tsrm_tls_entry **thread_resources_ptr, THREAD_
383394
(*thread_resources_ptr)->next = NULL;
384395

385396
/* Set thread local storage to this new thread resources structure */
386-
tsrm_tls_set(*thread_resources_ptr);
387-
TSRMLS_CACHE = *thread_resources_ptr;
397+
set_thread_local_storage_resource_to(*thread_resources_ptr);
388398

389399
if (tsrm_new_thread_begin_handler) {
390400
tsrm_new_thread_begin_handler(thread_id);
@@ -407,17 +417,14 @@ static void allocate_new_resource(tsrm_tls_entry **thread_resources_ptr, THREAD_
407417
if (tsrm_new_thread_end_handler) {
408418
tsrm_new_thread_end_handler(thread_id);
409419
}
410-
411-
tsrm_mutex_unlock(tsmm_mutex);
412420
}/*}}}*/
413421

414-
415422
/* fetches the requested resource for the current thread */
416423
TSRM_API void *ts_resource_ex(ts_rsrc_id id, THREAD_T *th_id)
417424
{/*{{{*/
418425
THREAD_T thread_id;
419426
int hash_value;
420-
tsrm_tls_entry *thread_resources;
427+
tsrm_tls_entry *thread_resources, **last_thread_resources;
421428

422429
if (!th_id) {
423430
/* Fast path for looking up the resources for the current
@@ -448,25 +455,55 @@ TSRM_API void *ts_resource_ex(ts_rsrc_id id, THREAD_T *th_id)
448455

449456
if (!thread_resources) {
450457
allocate_new_resource(&tsrm_tls_table[hash_value], thread_id);
458+
tsrm_mutex_unlock(tsmm_mutex);
451459
return ts_resource_ex(id, &thread_id);
452460
} else {
453-
do {
454-
if (thread_resources->thread_id == thread_id) {
455-
break;
456-
}
461+
last_thread_resources = &tsrm_tls_table[hash_value];
462+
while (thread_resources->thread_id != thread_id) {
463+
last_thread_resources = &thread_resources->next;
457464
if (thread_resources->next) {
458465
thread_resources = thread_resources->next;
459466
} else {
460467
allocate_new_resource(&thread_resources->next, thread_id);
468+
tsrm_mutex_unlock(tsmm_mutex);
461469
return ts_resource_ex(id, &thread_id);
462-
/*
463-
* thread_resources = thread_resources->next;
464-
* break;
465-
*/
466470
}
467-
} while (thread_resources);
471+
}
472+
}
473+
474+
/* It's possible that the current thread resources are requested, and that we get here.
475+
* This means that the TSRM key pointer and cached pointer are NULL, but there is still
476+
* a thread resource associated with this ID in the hashtable. This can occur if a thread
477+
* goes away, but its resources are never cleaned up, and then that thread ID is reused.
478+
* Since we don't always have a way to know when a thread goes away, we can't clean up
479+
* the thread's resources before the new thread spawns.
480+
* To solve this issue, we'll free up the old thread resources gracefully (gracefully
481+
* because there might still be resources open like database connection which need to
482+
* be shut down cleanly). After freeing up, we'll create the new resources for this thread
483+
* as if the stale resources never existed in the first place. From that point forward,
484+
* it is as if that situation never occurred.
485+
* The fact that this situation happens isn't that bad because a child process containing
486+
* threads will eventually be respawned anyway by the SAPI, so the stale threads won't last
487+
* forever. */
488+
TSRM_ASSERT(thread_resources->thread_id == thread_id);
489+
if (thread_id == tsrm_thread_id() && !tsrm_tls_get()) {
490+
tsrm_tls_entry *next = thread_resources->next;
491+
/* In case that extensions don't use the pointer passed from the dtor, but incorrectly
492+
* use the global pointer, we need to setup the global pointer temporarily here. */
493+
set_thread_local_storage_resource_to(thread_resources);
494+
/* Free up the old resource from the old thread instance */
495+
ts_free_resources(thread_resources);
496+
free(thread_resources);
497+
/* Allocate a new resource at the same point in the linked list, and relink the next pointer */
498+
allocate_new_resource(last_thread_resources, thread_id);
499+
thread_resources = *last_thread_resources;
500+
thread_resources->next = next;
501+
/* We don't have to tail-call ts_resource_ex, we can take the fast path to the return
502+
* because we already have the correct pointer. */
468503
}
504+
469505
tsrm_mutex_unlock(tsmm_mutex);
506+
470507
/* Read a specific resource from the thread's resources.
471508
* This is called outside of a mutex, so have to be aware about external
472509
* changes to the structure as we read it.
@@ -479,7 +516,6 @@ TSRM_API void *ts_resource_ex(ts_rsrc_id id, THREAD_T *th_id)
479516
void ts_free_thread(void)
480517
{/*{{{*/
481518
tsrm_tls_entry *thread_resources;
482-
int i;
483519
THREAD_T thread_id = tsrm_thread_id();
484520
int hash_value;
485521
tsrm_tls_entry *last=NULL;
@@ -492,17 +528,7 @@ void ts_free_thread(void)
492528

493529
while (thread_resources) {
494530
if (thread_resources->thread_id == thread_id) {
495-
for (i=0; i<thread_resources->count; i++) {
496-
if (resource_types_table[i].dtor) {
497-
resource_types_table[i].dtor(thread_resources->storage[i]);
498-
}
499-
}
500-
for (i=0; i<thread_resources->count; i++) {
501-
if (!resource_types_table[i].fast_offset) {
502-
free(thread_resources->storage[i]);
503-
}
504-
}
505-
free(thread_resources->storage);
531+
ts_free_resources(thread_resources);
506532
if (last) {
507533
last->next = thread_resources->next;
508534
} else {

Zend/Optimizer/zend_inference.c

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3436,6 +3436,9 @@ static zend_always_inline int _zend_update_type_info(
34363436
tmp |= zend_fetch_prop_type(script, prop_info, &ce);
34373437
if (opline->result_type == IS_VAR) {
34383438
tmp |= MAY_BE_REF | MAY_BE_INDIRECT;
3439+
if ((opline->extended_value & ZEND_FETCH_OBJ_FLAGS) == ZEND_FETCH_DIM_WRITE) {
3440+
tmp |= MAY_BE_UNDEF;
3441+
}
34393442
} else if (!(opline->op1_type & (IS_VAR|IS_TMP_VAR)) || !(t1 & MAY_BE_RC1)) {
34403443
zend_class_entry *ce = NULL;
34413444

@@ -3473,6 +3476,9 @@ static zend_always_inline int _zend_update_type_info(
34733476
zend_fetch_static_prop_info(script, op_array, ssa, opline), &ce);
34743477
if (opline->result_type == IS_VAR) {
34753478
tmp |= MAY_BE_REF | MAY_BE_INDIRECT;
3479+
if ((opline->extended_value & ZEND_FETCH_OBJ_FLAGS) == ZEND_FETCH_DIM_WRITE) {
3480+
tmp |= MAY_BE_UNDEF;
3481+
}
34763482
} else {
34773483
if (!result_may_be_separated(ssa, ssa_op)) {
34783484
tmp &= ~MAY_BE_RC1;

Zend/tests/arginfo_zpp_mismatch.inc

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ function skipFunction($function): bool {
99
/* intentionally violate invariants */
1010
|| $function === 'zend_create_unterminated_string'
1111
|| $function === 'zend_test_array_return'
12+
|| $function === 'zend_test_crash'
1213
|| $function === 'zend_leak_bytes'
1314
/* mess with output */
1415
|| (is_string($function) && str_starts_with($function, 'ob_'))

0 commit comments

Comments
 (0)