0
Fork 0
mirror of https://github.com/TryGhost/Ghost.git synced 2025-02-03 23:00:14 -05:00

🐛 Fixed handling of image uploads with overly long filenames

fixes ENG-733
ref https://linear.app/tryghost/issue/ENG-733/handle-image-uploads-where-name-is-too-long

- filesystems usually have a filename length limit; ie. on macOS it is
  255 characters
- if a file is uploaded with a longer filename, we'll return a HTTP 500
- we shouldn't do this as it is user error, so we can just catch the
  error code and return BadRequest
- this implements that, and adds a breaking test
This commit is contained in:
Daniel Lockyer 2024-03-11 21:50:55 +01:00 committed by Daniel Lockyer
parent 6db20fc14b
commit 6842d599e9
3 changed files with 41 additions and 1 deletions

View file

@ -58,7 +58,15 @@ class LocalStorageBase extends StorageBase {
targetFilename = filename;
await fs.mkdirs(targetDir);
await fs.copy(file.path, targetFilename);
try {
await fs.copy(file.path, targetFilename);
} catch (err) {
if (err.code === 'ENAMETOOLONG') {
throw new errors.BadRequestError({err});
}
throw err;
}
// The src for the image must be in URI format, not a file system path, which in Windows uses \
// For local file system storage can use relative path so add a slash

View file

@ -71,3 +71,21 @@ Object {
],
}
`;
exports[`Images API Will error when filename is too long 1: [body] 1`] = `
Object {
"errors": Array [
Object {
"code": "ENAMETOOLONG",
"context": "The request could not be understood.",
"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": "Request not understood error, cannot upload image.",
"property": null,
"type": "BadRequestError",
},
],
}
`;

View file

@ -185,6 +185,20 @@ describe('Images API', function () {
await uploadImageCheck({path: originalFilePath, filename: 'loadingcat_square.gif', contentType: 'image/gif'});
});
it('Will error when filename is too long', async function () {
const originalFilePath = p.join(__dirname, '/../../utils/fixtures/images/ghost-logo.png');
const fileContents = await fs.readFile(originalFilePath);
const loggingStub = sinon.stub(logging, 'error');
await uploadImageRequest({fileContents, filename: `${'a'.repeat(300)}.png`, contentType: 'image/png'})
.expectStatus(400)
.matchBodySnapshot({
errors: [{
id: anyErrorId
}]
});
sinon.assert.calledOnce(loggingStub);
});
it('Can not upload a json file', async function () {
const originalFilePath = p.join(__dirname, '/../../utils/fixtures/data/redirects.json');
const fileContents = await fs.readFile(originalFilePath);