From 086c862e078a9808ebd5a3c8ba146e9931e3646d Mon Sep 17 00:00:00 2001 From: Hyeseong Kim Date: Wed, 16 Nov 2022 18:34:51 +0900 Subject: [PATCH] fix(gatsby-core-utils): decode uri-encode filename for remote file (#35637) Fixes https://github.com/gatsbyjs/gatsby/issues/35636 --- .../src/__tests__/fetch-remote-file.js | 43 +++++++++++++++++++ .../gatsby-core-utils/src/filename-utils.ts | 5 ++- .../gatsby-source-filesystem/src/utils.js | 2 +- 3 files changed, 48 insertions(+), 2 deletions(-) diff --git a/packages/gatsby-core-utils/src/__tests__/fetch-remote-file.js b/packages/gatsby-core-utils/src/__tests__/fetch-remote-file.js index 58f7fd1e26eae..0facbcc0e87ed 100644 --- a/packages/gatsby-core-utils/src/__tests__/fetch-remote-file.js +++ b/packages/gatsby-core-utils/src/__tests__/fetch-remote-file.js @@ -133,7 +133,23 @@ const server = setupServer( ctx.body(content) ) }), + // Should test with non-ascii word `개` (which means dog in Korean) + rest.get( + `http://external.com/${encodeURIComponent(`개`)}.jpg`, + async (req, res, ctx) => { + const { content, contentLength } = await getFileContent( + path.join(__dirname, `./fixtures/dog-thumbnail.jpg`), + req + ) + return res( + ctx.set(`Content-Type`, `image/jpg`), + ctx.set(`Content-Length`, contentLength), + ctx.status(200), + ctx.body(content) + ) + } + ), rest.get(`http://external.com/dog`, async (req, res, ctx) => { const { content, contentLength } = await getFileContent( path.join(__dirname, `./fixtures/dog-thumbnail.jpg`), @@ -333,6 +349,33 @@ describe(`fetch-remote-file`, () => { expect(gotStream).toBeCalledTimes(1) }) + it(`downloads and create a jpg file for file with non-ascii url`, async () => { + const filePath = await fetchRemoteFile({ + url: `http://external.com/${encodeURIComponent(`개`)}.jpg`, + cache, + }) + + expect(path.basename(filePath)).toBe(`개.jpg`) + expect(getFileSize(filePath)).resolves.toBe( + await getFileSize(path.join(__dirname, `./fixtures/dog-thumbnail.jpg`)) + ) + expect(gotStream).toBeCalledTimes(1) + }) + + it(`downloads and create a jpg file for file with non-ascii filename`, async () => { + const filePath = await fetchRemoteFile({ + url: `http://external.com/dog.jpg`, + name: `${encodeURIComponent(`개`)}`, + cache, + }) + + expect(path.basename(filePath)).toBe(`개.jpg`) + expect(getFileSize(filePath)).resolves.toBe( + await getFileSize(path.join(__dirname, `./fixtures/dog-thumbnail.jpg`)) + ) + expect(gotStream).toBeCalledTimes(1) + }) + it(`downloads and create a jpg file for unknown extension`, async () => { const filePath = await fetchRemoteFile({ url: `http://external.com/dog`, diff --git a/packages/gatsby-core-utils/src/filename-utils.ts b/packages/gatsby-core-utils/src/filename-utils.ts index 4478485e71c4e..463a2bea50c70 100644 --- a/packages/gatsby-core-utils/src/filename-utils.ts +++ b/packages/gatsby-core-utils/src/filename-utils.ts @@ -29,7 +29,7 @@ export function getRemoteFileExtension(url: string): string { * */ export function getRemoteFileName(url: string): string { - return getParsedPath(url).name + return decodeURIComponent(getParsedPath(url).name) } export function createFileHash(input: string, length: number = 8): string { @@ -52,6 +52,9 @@ export function createFilePath( filename: string, ext: string ): string { + directory = decodeURIComponent(directory) + filename = decodeURIComponent(filename) + const purgedFileName = filename.replace(filenamePurgeRegex, `-`) const shouldAddHash = purgedFileName !== filename diff --git a/packages/gatsby-source-filesystem/src/utils.js b/packages/gatsby-source-filesystem/src/utils.js index 6c758864263e5..2108b8a6c43c6 100644 --- a/packages/gatsby-source-filesystem/src/utils.js +++ b/packages/gatsby-source-filesystem/src/utils.js @@ -38,7 +38,7 @@ export function getRemoteFileExtension(url) { * @return {String} filename */ export function getRemoteFileName(url) { - return getParsedPath(url).name + return decodeURIComponent(getParsedPath(url).name) } // createFilePath should be imported from `gatsby-core-utils`