Skip to content

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

Description

@giacomolanzi

Description

File::detectAndProcessFile() in src/Files/DTO/File.php calls file_exists() before checking whether the input string is plain base64 data. When a caller passes a large base64-encoded image (e.g. from Google Imagen / Gemini via bytesBase64Encoded), PHP emits:

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

Because the base64 data is embedded verbatim in the warning message, each occurrence adds ~1 MB to the PHP error log. In production this caused a 5.3 MB error log from only 6–8 image generation calls.

Root Cause

The detection order in detectAndProcessFile() is:

  1. URL check → skip
  2. Data URI check → skip
  3. file_exists($file) called → PHP warning (string > 4096 chars)
  4. Plain base64 regex check → matches correctly

Base64-encoded JPEG data starts with /9j/ (the base64 representation of the JPEG magic bytes FF D8 FF), which looks like an absolute file path on Linux. PHP calls the filesystem with a ~750 KB–1 MB "path" and emits the warning before the code ever reaches the base64 branch.

Reproduction

// Simulate what ai-provider-for-google does when Google AI returns bytesBase64Encoded
$base64Jpeg = base64_encode(file_get_contents('/path/to/any/image.jpg')); // > 4 KB
$file = new \WordPress\AiClient\Files\DTO\File($base64Jpeg, 'image/jpeg');
// → PHP Warning: file_exists(): File name is longer than the maximum allowed path length on this platform (4096)

Affected code

File: src/Files/DTO/File.php, line 94 (as of the version bundled with WordPress 6.9)

// Before (bug):
if (file_exists($file) && is_file($file)) {

// After (fix):
if (strlen($file) <= PHP_MAXPATHLEN && file_exists($file) && is_file($file)) {

PHP_MAXPATHLEN is the PHP constant that reflects the OS limit (typically 4096 on Linux). A string longer than that can never be a valid file path, so short-circuiting the check is semantically correct and has no side effects on legitimate use cases.

Context

  • Observed on a WordPress 6.9 site using the ai-provider-for-google plugin v1.1.0
  • The plugin passes $predictionData['bytesBase64Encoded'] directly to new File(...), which is the documented usage (plain base64 with MIME type)
  • The File class is supposed to handle this case, but the file_exists() call causes a noisy warning before it gets there
  • Images returned by Google AI contain C2PA metadata, making them even larger and amplifying the log impact

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions