From 374fcbfadb1c369d24e9025d544bd0d815d7432f Mon Sep 17 00:00:00 2001 From: npmrun <1549469775@qq.com> Date: Mon, 27 Apr 2026 11:40:54 +0800 Subject: [PATCH] fix(upload): resolve file path conflicts during image conversion - Updated the image upload handler to prevent conflicts when the input and output paths are the same, particularly for webp images. - Introduced a temporary output path for converted images, ensuring the original file is preserved during processing. - Enhanced error handling to clean up temporary files and maintain the integrity of the final output. These changes improve the reliability of the image upload process and prevent potential file overwrites. --- packages/drizzle-pkg/db.sqlite | Bin 188416 -> 188416 bytes server/api/file/upload.post.ts | 19 ++++++++++++++++--- 2 files changed, 16 insertions(+), 3 deletions(-) diff --git a/packages/drizzle-pkg/db.sqlite b/packages/drizzle-pkg/db.sqlite index 3f8aa141fa0c326f3a08e791e809ea598f90601f..b1eb4fac3b6e5affc887eccf20f31938229db35c 100644 GIT binary patch delta 833 zcmbV~O=uHQ6oub=lc`QJ^KP;*A;j7Y{(y@(KTR@;DI&U4C>FG|2(_^pLuhJ4noxv7 z8ij5f$zpKf4-^zp8cP-fE~M*9sEcmef<@dUi&_y&7lz`bXj;KVb@RAz&%5V4aHba> z(~FLh4@Vy!zl@^`!_S{OW)O&U2JS;Yt%{{Q<E-Y9XKmK-s4P~L)^MZTUm3*Lt8Xgjhix@m-{cXTLE0~Sf*vGgz>O!zYAHW<;!9`%{ z61_rQRnfmA6e3I>|4$_6fsbw0!=S<$rf<(t4u)05NX}!g`SKkez+Qw92P+7gumU^q z4K|?;pW!2{R>f;?!T7pNY?w0^X7Nd*xr~q68Q4Pb1GZtyq#y7n=wKO)os7A?fkC#m z>&V(QVBMrnQUl5}HXnyG+3`E6wC*$-UBqXJR$HPvteVtM-UCq9(zHd4QJ2UGdna;q z^1IY0)J&I5sKYUY-N+-IF0w_JF&ZPIm;PGYf2xSFae-)t&_gy`J++&=J%r5t1SO~T A5&!@I delta 550 zcmXYuL1@!Z7{}jxYnHZ2-d7lF?IPcP_xFAXvgS@B?*CbG+)Ki~hy|Kodar6a6#gu09~ zclRE{ndg;94~1<63Veo}FiYD?{T}5l!bi%rRO5DY?7-5sbC)lk&n;Ni;;>UCkDm&I-&hSXOOpH`AfFf8|>ZrKJYuY-6@HkJIh7)}c!1!!eBW&= zCtiW`bAyD02tp_t_GO%RUf;n}qXxM}CQq>Z9$4e2}hk60jgN{ol$a{d{a8NS#AEKP>^m1f8T0ufZ+@Z3x z?!P7#Vzzx6$5A4;zs8|Na-`;D$|Nt?G9KL>I_WaGD+n?#>h;tN#G? CL!O8L diff --git a/server/api/file/upload.post.ts b/server/api/file/upload.post.ts index b3b1bca..cfe679d 100644 --- a/server/api/file/upload.post.ts +++ b/server/api/file/upload.post.ts @@ -102,6 +102,8 @@ export default defineWrappedResponseHandler(async (event) => { const stem = path.parse(file.filename).name; const finalName = `${stem}.webp`; const finalPath = path.join(uploadDir, finalName); + // sharp 不允许输入与输出指向同一路径(常见于原图本身就是 webp) + const tempOutputPath = file.path === finalPath ? path.join(uploadDir, `${stem}-converted.webp`) : finalPath; try { await sharp(file.path) @@ -113,11 +115,11 @@ export default defineWrappedResponseHandler(async (event) => { withoutEnlargement: true, }) .webp({ quality: MEDIA_WEBP_QUALITY }) - .toFile(finalPath); + .toFile(tempOutputPath); } catch (procErr) { - if (fs.existsSync(finalPath)) { + if (fs.existsSync(tempOutputPath)) { try { - fs.unlinkSync(finalPath); + fs.unlinkSync(tempOutputPath); } catch { /* ignore */ } @@ -126,6 +128,17 @@ export default defineWrappedResponseHandler(async (event) => { throw createError({ statusCode: 400, statusMessage: msg }); } + if (tempOutputPath !== finalPath) { + if (fs.existsSync(finalPath)) { + try { + fs.unlinkSync(finalPath); + } catch { + /* ignore */ + } + } + fs.renameSync(tempOutputPath, finalPath); + } + if (file.path !== finalPath) { try { fs.unlinkSync(file.path);