close
Skip to content

Fix avoid file_exists() on oversized strings in File detection to prevent PHP warnings - #267

Open
the-hercules wants to merge 1 commit into
WordPress:trunkfrom
the-hercules:add/fix-oversized-strings
Open

Fix avoid file_exists() on oversized strings in File detection to prevent PHP warnings#267
the-hercules wants to merge 1 commit into
WordPress:trunkfrom
the-hercules:add/fix-oversized-strings

Conversation

@the-hercules

@the-hercules the-hercules commented Jul 29, 2026

Copy link
Copy Markdown

Closes #258

Summary

File::detectAndProcessFile() calls file_exists() while determining whether an
input string is a local path, before the plain-base64 branch is reached. When the
input is a large base64 payload (e.g. an image returned by a provider via
bytesBase64Encoded), the string exceeds the platform's maximum path length and
PHP emits:

file_exists(): File name is longer than the maximum allowed path length on this platform (4096): /9j/4AAQSkZJRg...

The warning message embeds the entire input string, so each occurrence writes
~1 MB to the error log. In practice this produced multi-megabyte error logs from
only a handful of image-generation calls. Base64-encoded JPEG data begins with
/9j/, which resembles an absolute path, so the string reaches file_exists()
before detection falls through to the base64 handling that processes it correctly.

Functionally the input was always handled correctly — this is a log-noise issue,
not a data-correctness one.

Change

Guard the filesystem check with a length comparison:

if (strlen($file) <= PHP_MAXPATHLEN && file_exists($file) && is_file($file)) {

AI Disclosure

Claude Opus 4.8 was used for identification and then verification of correctness of the solution.

@github-actions

github-actions Bot commented Jul 29, 2026

Copy link
Copy Markdown

The following accounts have interacted with this PR and/or linked issues. I will continue to update these lists as activity occurs. You can also manually ask me to refresh this list by adding the props-bot label.

If you're merging code through a pull request on GitHub, copy and paste the following into the bottom of the merge commit message.

Co-authored-by: the-hercules <thehercules@git.wordpress.org>
Co-authored-by: felixarntz <flixos90@git.wordpress.org>
Co-authored-by: tyrann0us <tyrannous@git.wordpress.org>
Co-authored-by: giacomolanzi <glanzi@git.wordpress.org>

To understand the WordPress project's expectations around crediting contributors, please review the Contributor Attribution page in the Core Handbook.

@codecov

codecov Bot commented Jul 29, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 86.49%. Comparing base (a31b0ec) to head (3115919).

Additional details and impacted files
@@            Coverage Diff            @@
##              trunk     #267   +/-   ##
=========================================
  Coverage     86.49%   86.49%           
- Complexity     1327     1328    +1     
=========================================
  Files            68       68           
  Lines          4295     4295           
=========================================
  Hits           3715     3715           
  Misses          580      580           
Flag Coverage Δ
unit 86.49% <100.00%> (ø)

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@felixarntz felixarntz left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@the-hercules Great catch! I think we may be able to find a cleaner solution though.

Comment thread src/Files/DTO/File.php
// Check if it's a local file path (before base64 check).
// The length guard avoids calling file_exists() on over-length strings (e.g. base64 data),
// which would emit a warning containing the entire string.
if (strlen($file) <= PHP_MAXPATHLEN && file_exists($file) && is_file($file)) {

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

not sure this is the adequate check - can't we instead perform a check for whether the string is possibly a file path? maybe check if it starts with / (since it always needs to be an absolute path in practice)

@tyrann0us

Copy link
Copy Markdown

[…] this is a log-noise issue […]

Not entirely. I came across this because on nginx (Apache untested), with Query Monitor active, image generation fails with:

The response is not a valid JSON response.

According to Claude Code, this is because Query Monitor takes the full warning text and puts it in an X-QM-php-errors-error-1 response header, causing a 502 "too big header" error, and thus failing the image generation/insertion. I confirmed it by deactivating Query Monitor. Alternatively, a mu-plugin like this would also work around the issue:

add_filter( 'qm/dispatch/rest', '__return_false' )
// or more specifically
add_filter( 'qm/outputter/headers', fn( $o ) => array_diff_key( $o, [ 'php_errors' => 1 ] ), 999 ); // untested

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

File DTO: file_exists() called on oversized strings causes PHP warning spam when handling base64 image data

3 participants