diff --git a/ghost/core/core/server/web/api/middleware/upload.js b/ghost/core/core/server/web/api/middleware/upload.js index 30549356a6..513ebf0453 100644 --- a/ghost/core/core/server/web/api/middleware/upload.js +++ b/ghost/core/core/server/web/api/middleware/upload.js @@ -62,8 +62,8 @@ const single = name => function singleUploadFunction(req, res, next) { singleUpload(req, res, (err) => { if (err) { - // Multer or Dicer errors are usually caused by invalid file uploads - if (err instanceof multer.MulterError || err.stack?.includes('dicer')) { + // Busboy, Multer or Dicer errors are usually caused by invalid file uploads + if (err instanceof multer.MulterError || err.stack?.includes('dicer') || err.stack?.includes('busboy')) { return next(new errors.BadRequestError({ err })); @@ -105,8 +105,8 @@ const media = (fileName, thumbName) => function mediaUploadFunction(req, res, ne mediaUpload(req, res, (err) => { if (err) { - // Multer or Dicer errors are usually caused by invalid file uploads - if (err instanceof multer.MulterError || err.stack?.includes('dicer')) { + // Busboy, Multer or Dicer errors are usually caused by invalid file uploads + if (err instanceof multer.MulterError || err.stack?.includes('dicer') || err.stack?.includes('busboy')) { return next(new errors.BadRequestError({ err })); diff --git a/ghost/core/test/e2e-api/admin/__snapshots__/images.test.js.snap b/ghost/core/test/e2e-api/admin/__snapshots__/images.test.js.snap index 6443b8ddeb..b2fdbf7f2f 100644 --- a/ghost/core/test/e2e-api/admin/__snapshots__/images.test.js.snap +++ b/ghost/core/test/e2e-api/admin/__snapshots__/images.test.js.snap @@ -144,6 +144,24 @@ Object { } `; +exports[`Images API Errors when trying to upload invalid form body 1: [body] 1`] = ` +Object { + "errors": Array [ + Object { + "code": null, + "context": null, + "details": null, + "ghostErrorCode": null, + "help": null, + "id": StringMatching /\\[a-f0-9\\]\\{8\\}-\\[a-f0-9\\]\\{4\\}-\\[a-f0-9\\]\\{4\\}-\\[a-f0-9\\]\\{4\\}-\\[a-f0-9\\]\\{12\\}/, + "message": "The request could not be understood.", + "property": null, + "type": "BadRequestError", + }, + ], +} +`; + exports[`Images API Will error when filename is too long 1: [body] 1`] = ` Object { "errors": Array [ diff --git a/ghost/core/test/e2e-api/admin/images.test.js b/ghost/core/test/e2e-api/admin/images.test.js index cb73a7bab0..ee882b35cb 100644 --- a/ghost/core/test/e2e-api/admin/images.test.js +++ b/ghost/core/test/e2e-api/admin/images.test.js @@ -321,6 +321,21 @@ describe('Images API', function () { sinon.assert.notCalled(unlinkStub); }); + it('Errors when trying to upload invalid form body', async function () { + sinon.stub(logging, 'error'); + + await agent + .post('/images/upload/') + .header('Content-Type', 'multipart/form-data') + .body(new FormData()) + .expectStatus(400) + .matchBodySnapshot({ + errors: [{ + id: anyErrorId + }] + }); + }); + it('Errors when image request body is broken', async function () { // Manually construct a broken request body const blob = await fetch('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAUAAAAFCAYAAACNbyblAAAAHElEQVQI12P4//8/w38GIAXDIBKE0DHxgljNBAAO9TXL0Y4OHwAAAABJRU5ErkJggg==').then(res => res.blob());