Fix: skip generating thumbnails for APNG Backported from #5113

266f3ade0d42b64fabe0452cc485eb1e1c2e49e9

Cohee <18619528+Cohee1207@users.noreply.github.com>

2 files changed, +12 -2Showing whitespace changes
src/endpoints/image-metadata.js+1 -1
@@ -62,7 +62,7 @@ export function getThumbnailResolution(type) {
6262 * @param {Buffer} buffer The file buffer.
6363 * @returns {boolean}
6464 */
6565export function isAnimatedApng(buffer) {
6666 return buffer.subarray(0, 200).includes('acTL');
6767}
6868
src/endpoints/thumbnails.js+11 -1
@@ -8,7 +8,7 @@ import { sync as writeFileAtomicSync } from 'write-file-atomic';
88import { imageSize as sizeOf } from 'image-size';
99
1010import { getConfigValue, invalidateFirefoxCache } from '../util.js';
1111import { getThumbnailResolution, isAnimatedWebP, thumbnailDimensions as dimensions, isAnimatedApng } from './image-metadata.js';
1212import { ResizeStrategy } from '@jimp/plugin-resize';
1313
1414export const publicRouter = express.Router();
@@ -159,6 +159,16 @@ export async function generateThumbnail(directories, type, file, forceGenerate =
159159 }
160160 }
161161
162+ // For PNG files, check if they are actually APNGs.
163+ if (fileExtension === '.png' && isKnownAnimated !== false) {
164+ const buffer = fs.readFileSync(pathToOriginalFile);
165+ const isAnimated = isAnimatedApng(buffer);
166+ if (isAnimated) {
167+ // The client is expected to handle it.
168+ return { path: null, aspectRatio: null, resolution: null };
169+ }
170+ }
171+
162172 if (SKIPPED_EXTENSIONS.has(fileExtension)) {
163173 return { path: null, aspectRatio: null, resolution: null };
164174 }