Misleading error message when uploading format on different cased extenions #2227

Open
opened 2026-10-05 01:10:26 +02:00 by adam · 0 comments
Owner

Description

When $conf['enable_formats'] is active and formats are uploaded through the web upload form, files whose extension is written in uppercase are not recognised as formats when the defined format_ext are in e.g. lower case.

The user-facing error is also misleading: Piwigo reports that no picture with that name was found, although the base photo exists and the base name matches perfectly. The lookup never reaches the database — the file is discarded before that, because the extension was not recognised.

Steps to reproduce

  1. Enable multiple formats via LocalFiles Editor:
    $conf['enable_formats'] = true;
    $conf['format_ext'] = array('cr2', 'nef', 'dng', 'tif', 'tiff');
    
  2. Upload a photo named IMG_5993.JPG through the web upload form.
  3. Go to the upload page again, tick "Upload formats", and upload IMG_5993.CR2 (uppercase extension, as written by the camera).

Expected behaviour

The RAW file is attached as a format to photo IMG_5993.JPG.

Actual behaviour

The upload fails with "No picture with this name found: IMG_5993". Renaming the file to IMG_5993.cr2 (lowercase extension) makes it work immediately or adding CR2 to format_ext.

Root cause

In include/ws_functions/pwg.images.php, function ws_images_formats_searchImage(), the candidate filename is matched against $conf['format_ext'] with a case-sensitive regular expression:

if (preg_match('/^(.*?)\.('.implode('|', $conf['format_ext']).')$/', $format_filename, $matches))
{
  $candidate_filename_wo_ext = $matches[1];
}

if (empty($candidate_filename_wo_ext))
{
  $result[$format_external_id] = array('status' => 'not found');
  continue;
}

With format_ext holding lowercase values, IMG_5993.CR2 does not match, $candidate_filename_wo_ext stays empty, and the function returns not found without ever querying the images table.

The same case-sensitive pattern is used in ws_images_add() in the same file:

if (preg_match('/\.('.implode('|', $conf['format_ext']).')$/', $params['name'], $matches))
{
  $format_ext = $matches[1];
}

Note that the base photo side is not affected: get_filename_wo_extension() simply truncates at the last dot, so IMG_5993.JPG correctly yields IMG_5993. The mismatch is purely on the format side.

Suggested fix

Make both checks case-insensitive by adding the i modifier:

preg_match('/^(.*?)\.('.implode('|', $conf['format_ext']).')$/i', $format_filename, $matches)

The extension stored in image_format.ext should then be normalised (e.g. via strtolower()) so that the duplicate check further down in ws_images_formats_searchImage() — which compares pathinfo($format_filename, PATHINFO_EXTENSION) against the extensions already stored for that image — does not treat .CR2 and .cr2 as two different formats.

This matches how the same class of problem was handled in #1354, where the conclusion was that extension checks should be case-insensitive.

Secondary issue: misleading error message

Even with the fix in place, it would help to distinguish the two failure modes. Currently an unrecognised extension and a genuinely missing base photo produce the same "no picture with this name" message, which sends users looking in the wrong direction. A distinct status for "extension not in format_ext" would make this much easier to diagnose.

Workaround

Either list both spellings in the configuration:

$conf['format_ext'] = array('cr2','CR2','cr3','CR3','nef','NEF','arw','ARW','dng','DNG');

or rename all RAW files to a lowercase extension before uploading.

Environment

  • Piwigo 16.4.0
  • Betriebssystem: Linux
  • Container info: Official 16.4.0a
  • PHP: 8.4.20 (Info anzeigen) [2026-08-01 00:54:29]
  • MySQL: 11.8.6-MariaDB-ubu2404 [2026-08-01 00:54:29]
  • Grafikbibliothek: External ImageMagick 7.1.2-19
  • Größe des Cache 24.8 Mo   berechnet vor 1 Woche Aktualisieren
### Description When `$conf['enable_formats']` is active and formats are uploaded through the web upload form, files whose extension is written in uppercase are not recognised as formats when the defined format_ext are in e.g. lower case. The user-facing error is also misleading: Piwigo reports that no picture with that name was found, although the base photo exists and the base name matches perfectly. The lookup never reaches the database — the file is discarded before that, because the extension was not recognised. ### Steps to reproduce 1. Enable multiple formats via LocalFiles Editor: ```php $conf['enable_formats'] = true; $conf['format_ext'] = array('cr2', 'nef', 'dng', 'tif', 'tiff'); ``` 2. Upload a photo named `IMG_5993.JPG` through the web upload form. 3. Go to the upload page again, tick "Upload formats", and upload `IMG_5993.CR2` (uppercase extension, as written by the camera). ### Expected behaviour The RAW file is attached as a format to photo `IMG_5993.JPG`. ### Actual behaviour The upload fails with "No picture with this name found: IMG_5993". Renaming the file to `IMG_5993.cr2` (lowercase extension) makes it work immediately or adding CR2 to format_ext. ### Root cause In `include/ws_functions/pwg.images.php`, function `ws_images_formats_searchImage()`, the candidate filename is matched against `$conf['format_ext']` with a case-sensitive regular expression: ```php if (preg_match('/^(.*?)\.('.implode('|', $conf['format_ext']).')$/', $format_filename, $matches)) { $candidate_filename_wo_ext = $matches[1]; } if (empty($candidate_filename_wo_ext)) { $result[$format_external_id] = array('status' => 'not found'); continue; } ``` With `format_ext` holding lowercase values, `IMG_5993.CR2` does not match, `$candidate_filename_wo_ext` stays empty, and the function returns `not found` without ever querying the images table. The same case-sensitive pattern is used in `ws_images_add()` in the same file: ```php if (preg_match('/\.('.implode('|', $conf['format_ext']).')$/', $params['name'], $matches)) { $format_ext = $matches[1]; } ``` Note that the base photo side is not affected: `get_filename_wo_extension()` simply truncates at the last dot, so `IMG_5993.JPG` correctly yields `IMG_5993`. The mismatch is purely on the format side. ### Suggested fix Make both checks case-insensitive by adding the `i` modifier: ```php preg_match('/^(.*?)\.('.implode('|', $conf['format_ext']).')$/i', $format_filename, $matches) ``` The extension stored in `image_format.ext` should then be normalised (e.g. via `strtolower()`) so that the duplicate check further down in `ws_images_formats_searchImage()` — which compares `pathinfo($format_filename, PATHINFO_EXTENSION)` against the extensions already stored for that image — does not treat `.CR2` and `.cr2` as two different formats. This matches how the same class of problem was handled in #1354, where the conclusion was that extension checks should be case-insensitive. ### Secondary issue: misleading error message Even with the fix in place, it would help to distinguish the two failure modes. Currently an unrecognised extension and a genuinely missing base photo produce the same "no picture with this name" message, which sends users looking in the wrong direction. A distinct status for "extension not in format_ext" would make this much easier to diagnose. ### Workaround Either list both spellings in the configuration: ```php $conf['format_ext'] = array('cr2','CR2','cr3','CR3','nef','NEF','arw','ARW','dng','DNG'); ``` or rename all RAW files to a lowercase extension before uploading. ### Environment - Piwigo 16.4.0 - Betriebssystem: Linux - Container info: Official 16.4.0a - PHP: 8.4.20 (Info anzeigen) [2026-08-01 00:54:29] - MySQL: 11.8.6-MariaDB-ubu2404 [2026-08-01 00:54:29] - Grafikbibliothek: External ImageMagick 7.1.2-19 - Größe des Cache 24.8 Mo   berechnet vor 1 Woche Aktualisieren <!-- github-sync-id:5033964609 -->
Sign in to join this conversation.
No labels
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: adam/Piwigo#2227