Skip to content

Commit

Permalink
馃悰 Fixed handling of image uploads with overly long filenames
Browse files Browse the repository at this point in the history
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
  • Loading branch information
daniellockyer committed Mar 12, 2024
1 parent b11ae81 commit 466e3f9
Show file tree
Hide file tree
Showing 3 changed files with 41 additions and 1 deletion.
10 changes: 9 additions & 1 deletion ghost/core/core/server/adapters/storage/LocalStorageBase.js
Expand Up @@ -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
Expand Down
18 changes: 18 additions & 0 deletions ghost/core/test/e2e-api/admin/__snapshots__/images.test.js.snap
Expand Up @@ -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",
},
],
}
`;
14 changes: 14 additions & 0 deletions ghost/core/test/e2e-api/admin/images.test.js
Expand Up @@ -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);
Expand Down

0 comments on commit 466e3f9

Please sign in to comment.