From 9410f466d80b30f52e5f926e5d17a513beec1084 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bar=C4=B1=C5=9F=20Soner=20U=C5=9Fakl=C4=B1?= Date: Fri, 24 Oct 2025 11:04:29 -0400 Subject: [PATCH 1/2] fix: closes #13729, fix filename encoding --- src/middleware/multer.js | 16 ++++++++++++++++ src/routes/admin.js | 4 +--- src/routes/api.js | 4 +--- src/routes/authentication.js | 5 +---- src/routes/helpers.js | 4 +--- 5 files changed, 20 insertions(+), 13 deletions(-) create mode 100644 src/middleware/multer.js diff --git a/src/middleware/multer.js b/src/middleware/multer.js new file mode 100644 index 0000000000..e15c146ff3 --- /dev/null +++ b/src/middleware/multer.js @@ -0,0 +1,16 @@ +'use strict'; + +const multer = require('multer'); +const storage = multer.diskStorage({}); +const upload = multer({ storage, + // from https://github.com/TriliumNext/Trilium/pull/3058/files + fileFilter: (req, file, cb) => { + // UTF-8 file names are not well decoded by multer/busboy, so we handle the conversion on our side. + // See https://github.com/expressjs/multer/pull/1102. + file.originalname = Buffer.from(file.originalname, 'latin1').toString('utf-8'); + cb(null, true); + } +}); + +module.exports = upload; + diff --git a/src/routes/admin.js b/src/routes/admin.js index 5421b4d0ef..4788593c5a 100644 --- a/src/routes/admin.js +++ b/src/routes/admin.js @@ -85,9 +85,7 @@ function apiRoutes(router, name, middleware, controllers) { router.post(`/api/${name}/manage/categories/:cid/name`, middleware.ensureLoggedIn, helpers.tryRoute(controllers.admin.categories.renameRemote)); router.delete(`/api/${name}/manage/categories/:cid`, middleware.ensureLoggedIn, helpers.tryRoute(controllers.admin.categories.removeRemote)); - const multer = require('multer'); - const storage = multer.diskStorage({}); - const upload = multer({ storage }); + const upload = require('../middleware/multer'); const middlewares = [ upload.array('files[]', 20), diff --git a/src/routes/api.js b/src/routes/api.js index 4424d9a979..79fb83b811 100644 --- a/src/routes/api.js +++ b/src/routes/api.js @@ -23,9 +23,7 @@ module.exports = function (app, middleware, controllers) { router.get('/topic/teaser/:topic_id', [...middlewares], helpers.tryRoute(controllers.topics.teaser)); router.get('/topic/pagination/:topic_id', [...middlewares], helpers.tryRoute(controllers.topics.pagination)); - const multer = require('multer'); - const storage = multer.diskStorage({}); - const upload = multer({ storage }); + const upload = require('../middleware/multer'); const postMiddlewares = [ middleware.maintenanceMode, diff --git a/src/routes/authentication.js b/src/routes/authentication.js index 720675b29d..9836cf22a5 100644 --- a/src/routes/authentication.js +++ b/src/routes/authentication.js @@ -154,10 +154,7 @@ Auth.reloadRoutes = async function (params) { }); }); - - const multer = require('multer'); - const storage = multer.diskStorage({}); - const upload = multer({ storage }); + const upload = require('../middleware/multer') const middlewares = [ upload.any(), Auth.middleware.applyCSRF, diff --git a/src/routes/helpers.js b/src/routes/helpers.js index 2109a0bd9c..079eb36536 100644 --- a/src/routes/helpers.js +++ b/src/routes/helpers.js @@ -54,9 +54,7 @@ helpers.setupApiRoute = function (...args) { const [router, verb, name] = args; let middlewares = args.length > 4 ? args[args.length - 2] : []; const controller = args[args.length - 1]; - const multer = require('multer'); - const storage = multer.diskStorage({}); - const upload = multer({ storage }); + const upload = require('../middleware/multer'); middlewares = [ middleware.autoLocale, middleware.applyBlacklist, From 430a3e81130ac6c1393f9854e1ac78de484e8c92 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bar=C4=B1=C5=9F=20Soner=20U=C5=9Fakl=C4=B1?= Date: Fri, 24 Oct 2025 11:12:20 -0400 Subject: [PATCH 2/2] test: add test for #13729 --- test/files/测试.jpg | Bin 0 -> 1010 bytes test/uploads.js | 6 ++++++ 2 files changed, 6 insertions(+) create mode 100644 test/files/测试.jpg diff --git a/test/files/测试.jpg b/test/files/测试.jpg new file mode 100644 index 0000000000000000000000000000000000000000..905e886eef32d9fa695e35e69f69314c0d5850cc GIT binary patch literal 1010 zcmex=5A1R0qH8UG()kY-?DVrFDyWIzCRpldmpn1Pb|0t}4IV8Fxa4 zIw}PwvKKar8i_dtB~4uP5U4?dkpXBJ!YCk%iG>+tkCGq*6B837kOP-xWD;Zsnxka+ z!6Sa$#(TjgQ|Y5V{SLOjx6Mv%A%bW#uXH*X0MjL*yQWsYu~uNGq;8Qn&jcU-r>jO z0N>0fJIgE7jT`f&oHmJP-g$9v$~L9Sw`zMM9~hcvYgAtMnqw67Mqu%?+TUTq@*UTv z|J2^TRqbe``R=8c3fZ%EH#JQ1;dquE_A1wOo8X@`Zmn%aj0?g(2`qV|X~^~Nub7&$IkY{)M;AjwMxmbk&%?_R~_AZtI8Y8)^gWuXVk5 z{ryKge}BE((ajvW2cF%${fc?dtl0@ucl|7N5f58@X7ZNm$+z~c-O}65^>?XyNp-09 zb^qH_Hr;N|&l6^1_`dF0S80e@D=ntK7x@s)sqJ;7)a)%=m*(4xQ?(^`>2pc#5zlvwe3C1}W%@YztC*O(R{nQ> do1crieDwF!%ojGi?EiKChm1vCJLdeq2>^^Eisk?S literal 0 HcmV?d00001 diff --git a/test/uploads.js b/test/uploads.js index 1e5b3d19e3..8a57c0d06e 100644 --- a/test/uploads.js +++ b/test/uploads.js @@ -194,6 +194,12 @@ describe('Upload Controllers', () => { assert(body.response.images[0].url); }); + it('should upload a file with utf8 characters in the name to a post', async () => { + const { body } = await helpers.uploadFile(`${nconf.get('url')}/api/post/upload`, path.join(__dirname, '../test/files/测试.jpg'), {}, jar, csrf_token); + + assert(body.response.images[0].url.endsWith('测试.jpg')); + }); + it('should fail to upload image to post if image dimensions are too big', async () => { const { response, body } = await helpers.uploadFile(`${nconf.get('url')}/api/post/upload`, path.join(__dirname, '../test/files/toobig.png'), {}, jar, csrf_token); assert.strictEqual(response.statusCode, 500);