Hacktoberfest 2026: le issue che i maintainer hanno segnato per ottobre, aperte e adatte ai principianti. Sfoglia le issue Hacktoberfest

[Bug]: Image editor silently writes PNG data into .JPG files (uppercase extension breaks canvas.toBlob MIME)

Aperta Adatta ai principianti
#3,424 3 commenti 0 reazioni 0 assegnatari Vedi su GitHub

I maintainer di solito rispondono entro 2 giorni

@aniruddh18122006-cyber ci sta già lavorando.

Dal 9/10/2026.

  • #3429 di @aniruddh18122006-cyber — chiusa senza merge

Valutazione

Difficoltà
2/5
Tempo stimato
1-3 ore
Idoneità per principianti
78/100
Tipo di issue
Bug
Chiarezza
Specificata chiaramente
Stato di attività
Attiva
Stack tecnologico
javascript
Ambito
backend, frontend

Direzione di ricerca

Inizia da src/components/ImageEditor.vue, in particolare da defaultSavedImageType() e onSave(), poi segui come la finestra di dialogo «Save image as» gestisce il campo del formato. Riproduci il problema con un’immagine con estensione .JPG maiuscola e controlla il tipo del blob codificato prima del caricamento. Il lavoro è completato quando il salvataggio preserva i byte JPEG per le estensioni maiuscole e i dati codificati non corrispondenti non vengono caricati silenziosamente.

Scritto dal modello di indicizzazione a partire dal testo della issue.

Descrizione

Bug description

Editing a photo whose extension is uppercase .JPG in the built-in viewer image
editor corrupts the file: the stored bytes become PNG while the filename keeps its
.JPG extension.

Observed on Nextcloud 32.0.14.1, viewer 5.0.0, Chrome 155:

before after "Speichern" (save)
content type image/jpeg image/png
size 2 865 024 B 504 955 B
magic bytes FF D8 FF 89 50 4E 47

file on the server: PNG image data, 4320 x 3240, 8-bit/color RGBA.

The upload itself succeeds (PUT /remote.php/dav/files/<user>/<path>.JPG → 204),
so there is no indication anything went wrong.

Steps to reproduce
  1. Upload a JPEG with an uppercase extension (e.g. ABC1234.JPG — the default
    export of many cameras).
  2. Open it in the viewer (/apps/files/... → click the file), press Ctrl+E
    (or open with ?editing=true) so the image editor opens.
  3. Apply any change (e.g. Filters → Black & White).
  4. Click Save → Save image as dialog appears → Save → confirm overwrite.
  5. Inspect the file server-side:
file data/<user>/files/ABC1234.JPG
# PNG image data, 4320 x 3240, 8-bit/color RGBA, non-interlaced
Expected behaviour

The file must still be a JPEG (or the user must be told the format changed).

Root cause

In src/components/ImageEditor.vue (viewer 5.0.0):

defaultSavedImageType() {
    return extname(this.decodedSourceName).slice(1) || 'jpeg'   // -> "JPG"
}

The extension is not lower-cased. The Filerobot editor then builds the MIME
type from it ('image/' + (ext === 'jpg' ? 'jpeg' : ext)) → image/JPG.

onSave() only normalises case-sensitively:

mimeType = mimeType.replace('jpg', 'jpeg')      // no-op for "image/JPG"
...
const blob = await new Promise(resolve => imageCanvas.toBlob(resolve, mimeType, quality))
const response = await axios.put(putUrl, new File([blob], fullName))

HTMLCanvasElement.toBlob() falls back to image/png for an unknown MIME type
(per spec: "if type is not a supported image format, use image/png"), so PNG
bytes are uploaded under the original .JPG name. The File's name is also not
checked against blob.type.

Consequences seen in the wild:

  • PNG files that are 5–15× larger than the JPEG they replace (a 15 MB PNG was
    written over a 1.4 MB JPEG in a user report).
  • Metadata/EXIF is lost, so Memories date/time editing then fails with
    Could not set exif data: Error: Not a valid JPG (looks more like a PNG) (HTTP 500).
  • Previews, sync clients and third-party apps see a file whose extension lies
    about its content.
Suggested fix
defaultSavedImageType() {
    return (extname(this.decodedSourceName).slice(1) || 'jpeg').toLowerCase()
}

plus a defensive normalisation in onSave() (case-insensitive jpg → jpeg)
and, most importantly, a check after encoding:

if (blob.type !== mimeType) { showError(...); return }   // never upload mismatched bytes

Also worth lower-casing/validating the extension in the "Save image as" dialog
(format field), which currently keeps JPG as well.

Environment
  • Nextcloud 32.0.14.1, PHP 8.3.33, viewer 5.0.0 (default install)
  • Chrome 155, Linux
  • Affected files: any image with an uppercase .JPG/.JPEG/.PNG-style extension;
    lowercase .jpg is unaffected (image/jpeg works).
Lingua principale
Nessun dato sulla lingua
Stelle
122
Fork
75
Merge medio
4g 14h
PR unite (30g)
45

Preparare l'ambiente

Come iniziare

  1. Leggi tutta la issue e poi la guida ai contributi del progetto.
  2. Commenta sulla issue per dire che te ne occupi tu — evita che due persone facciano lo stesso lavoro.
  3. Fai un fork del repository e lavora su un branch.
  4. Apri una pull request che faccia riferimento al numero della issue.

Altre issue di nextcloud/viewer

Tutte le issue di nextcloud/viewer

Issue simili

Altre issue su Backend & API Design

Ricevi le nuove issue nella tua casella

Un breve riepilogo di issue GitHub adatte ai principianti.