From 6a8d0a054d6d43414427cbdfb3afcacc4aefa342 Mon Sep 17 00:00:00 2001 From: Niels Dossche <7771979+nielsdos@users.noreply.github.com> Date: Wed, 16 Oct 2024 22:35:13 +0200 Subject: [PATCH] Fix GH-16406: Assertion failure in ext/phar/phar.c:2808 When copying entries during conversion in phar_convert_to_other(), the header offset is not reset. This didn't matter in the past as it wasn't used anyway in the particular use-case, but since 1bb2a4f9 this is actually used and sanity-checked. Closes GH-16470. --- NEWS | 3 +++ ext/phar/phar_object.c | 3 +++ ext/phar/tests/gh16406.phpt | 35 +++++++++++++++++++++++++++++++++++ 3 files changed, 41 insertions(+) create mode 100644 ext/phar/tests/gh16406.phpt diff --git a/NEWS b/NEWS index b8ba02ad624..9a3d6fa01f0 100644 --- a/NEWS +++ b/NEWS @@ -50,6 +50,9 @@ PHP NEWS . Fixed bug GH-16433 (Large values for openssl_csr_sign() $days overflow). (cmb) +- Phar: + . Fixed bug GH-16406 (Assertion failure in ext/phar/phar.c:2808). (nielsdos) + - PHPDBG: . Fixed bug GH-16174 (Empty string is an invalid expression for ev). (cmb) diff --git a/ext/phar/phar_object.c b/ext/phar/phar_object.c index 646cf42c4a9..a509f7e0148 100644 --- a/ext/phar/phar_object.c +++ b/ext/phar/phar_object.c @@ -2286,6 +2286,9 @@ no_copy: newentry.tar_type = (entry->is_dir ? TAR_DIR : TAR_FILE); } + /* The header offset is only used for unmodified zips. + * Once modified, phar_zip_changed_apply_int() will update the header_offset. */ + newentry.header_offset = 0; newentry.is_modified = 1; newentry.phar = phar; newentry.old_flags = newentry.flags & ~PHAR_ENT_COMPRESSION_MASK; /* remove compression from old_flags */ diff --git a/ext/phar/tests/gh16406.phpt b/ext/phar/tests/gh16406.phpt new file mode 100644 index 00000000000..6df5fd3aab6 --- /dev/null +++ b/ext/phar/tests/gh16406.phpt @@ -0,0 +1,35 @@ +--TEST-- +GH-16406 (Assertion failure in ext/phar/phar.c:2808) +--EXTENSIONS-- +phar +zlib +--INI-- +phar.readonly=0 +phar.require_hash=0 +--FILE-- +'; +$files['b'] = 'b'; +$files['c'] = 'c'; +include __DIR__.'/files/phar_test.inc'; +$phar = new Phar($fname); +$phar->compressFiles(Phar::GZ); +$phar = $phar->convertToExecutable(Phar::TAR); +$phar = $phar->convertToExecutable(Phar::PHAR, Phar::GZ); +var_dump($phar['b']->openFile()->fread(4096)); +var_dump($phar['c']->openFile()->fread(4096)); +?> +--CLEAN-- + +--EXPECT-- +string(1) "b" +string(1) "c"