[wp-trac] [WordPress Trac] #65320: WordPress 7 core update silently truncates filenames longer than 100 characters during extraction (wp-includes/php-ai-client/ affected)
WordPress Trac
noreply at wordpress.org
Fri May 22 09:21:47 UTC 2026
#65320: WordPress 7 core update silently truncates filenames longer than 100
characters during extraction (wp-includes/php-ai-client/ affected)
--------------------------+-----------------------------
Reporter: arakelxvi | Owner: (none)
Type: defect (bug) | Status: new
Priority: normal | Milestone: Awaiting Review
Component: General | Version: 7.0
Severity: major | Keywords:
Focuses: |
--------------------------+-----------------------------
== Description ==
When updating to WordPress 7 — either via the admin dashboard or WP-CLI
— files whose path within the archive exceeds 100 characters are extracted
with silently truncated
filenames. No error is reported. WordPress 7 introduced wp-includes/php-
ai-client/, a new AI client library containing many files with archive-
internal paths of 101–131
characters. Every file exceeding the 100-char boundary is extracted with
a truncated name, causing every WordPress 7 installation to immediately
fail wp core verify-checksums.
== Environment ==
- '''WordPress version:''' 7.0
- '''PHP version:''' multiple tested — issue is not PHP version specific
- '''OS:''' Ubuntu Linux
- '''Reproduction:''' 100% reproducible on every fresh install or update
to WP7
== Steps to Reproduce ==
1. Update to WordPress 7 via admin dashboard or wp core update --allow-
root
2. Run wp core verify-checksums --allow-root
== Expected Behavior ==
All files extracted with correct full filenames. wp core verify-
checksums passes.
== Actual Behavior ==
Files with archive-internal paths exceeding 100 characters are extracted
with silently truncated names. wp core verify-checksums reports each
affected file twice:
{{{
Warning: File doesn't exist: wp-includes/php-ai-client/third-
party/Http/Discovery/Exception/PuliUnavailableException.php
Warning: File should not exist: wp-includes/php-ai-client/third-
party/Http/Discovery/Exception/PuliUnavailableException.ph
Warning: File doesn't exist: wp-includes/php-ai-client/third-
party/Http/Discovery/Exception/StrategyUnavailableException.php
Warning: File should not exist: wp-includes/php-ai-client/third-
party/Http/Discovery/Exception/StrategyUnavailableExceptio
Warning: File doesn't exist: wp-includes/php-ai-
client/src/Providers/OpenAiCompatibleImplementation/AbstractOpenAiCompatibleModelMetadataDirectory.php
Warning: File should not exist: wp-includes/php-ai-
client/src/Providers/OpenAiCompatibleImplementation/AbstractOpenAiCompa
}}}
The truncation point is exactly 100 characters of the archive-internal
path in every case. All files with archive-internal paths ≤ 100 chars
extract correctly. All files exceeding
100 chars are affected.
== Root Cause ==
PHP's PharData (used for tar.gz extraction) reads only the 100-byte name
field from tar headers, ignoring the prefix field and PAX extended headers
that carry the full path for
entries exceeding 100 characters. This is a known limitation of PHP's
libphar implementation.
'''Confirmed:''' PHP reads filenames truncated via PharData, while
system tools extract correctly:
{{{#!sh
PharData — truncated at 100 chars
php -r "
$phar = new PharData('/tmp/wp7.tar.gz');
foreach (new RecursiveIteratorIterator($phar) as $f) {
if (strpos($f->getPathName(), 'PuliUnavailable') !== false)
echo $f->getPathName() . PHP_EOL;
}
"
Result: phar:///tmp/wp7.tar.gz/wordpress/.../PuliUnavailableException.ph
(truncated)
system tar — correct
tar -tvf /tmp/wp7.tar.gz | grep PuliUnavailable
Result: wordpress/.../PuliUnavailableException.php (correct)
}}}
{{{#!sh
ZipArchive (.zip) — correct
php -r "
$z = new ZipArchive();
$z->open('/tmp/wp7.zip');
for ($i = 0; $i < $z->numFiles; $i++) {
$name = $z->getNameIndex($i);
if (strpos($name, 'PuliUnavailable') !== false)
echo strlen($name) . ' ' . $name . PHP_EOL;
}
$z->close();
"
Result: 101 wordpress/.../PuliUnavailableException.php (correct)
}}}
phar:///tmp/wp7.tar.gz/ = 23 chars + 100-char tar name field = 123 chars
total. The character at position 101 of the internal path is silently
dropped.
--
Ticket URL: <https://core.trac.wordpress.org/ticket/65320>
WordPress Trac <https://core.trac.wordpress.org/>
WordPress publishing platform
More information about the wp-trac
mailing list