diff --git a/.changeset/dull-worms-own.md b/.changeset/dull-worms-own.md new file mode 100644 index 0000000000..fb5384d015 --- /dev/null +++ b/.changeset/dull-worms-own.md @@ -0,0 +1,5 @@ +--- +'astro': patch +--- + +Fixes a bug where [data URL images](https://developer.mozilla.org/en-US/docs/Web/URI/Schemes/data) were not correctly handled. The bug resulted in an `ENAMETOOLONG` error. diff --git a/packages/astro/src/assets/utils/transformToPath.ts b/packages/astro/src/assets/utils/transformToPath.ts index 554761487d..e11680a122 100644 --- a/packages/astro/src/assets/utils/transformToPath.ts +++ b/packages/astro/src/assets/utils/transformToPath.ts @@ -8,7 +8,11 @@ import { isESMImportedImage } from './imageKind.js'; export function propsToFilename(filePath: string, transform: ImageTransform, hash: string) { let filename = decodeURIComponent(removeQueryString(filePath)); const ext = extname(filename); - filename = basename(filename, ext); + if (filePath.startsWith('data:')) { + filename = shorthash(filePath); + } else { + filename = basename(filename, ext); + } const prefixDirname = isESMImportedImage(transform.src) ? dirname(filePath) : ''; let outputExt = transform.format ? `.${transform.format}` : ext; diff --git a/packages/astro/test/core-image.test.js b/packages/astro/test/core-image.test.js index 9c62a679ef..887a3a35de 100644 --- a/packages/astro/test/core-image.test.js +++ b/packages/astro/test/core-image.test.js @@ -1263,4 +1263,57 @@ describe('astro:image', () => { assert.equal(imgData instanceof Buffer, true); }); }); + + describe('build data url', () => { + before(async () => { + fixture = await loadFixture({ + root: './fixtures/core-image-data-url/', + image: { + remotePatterns: [ + { + protocol: 'data', + }, + ], + }, + }); + + await fixture.build(); + }); + + it('uses short hash for data url filename', async () => { + const html = await fixture.readFile('/index.html'); + const $ = cheerio.load(html); + const src1 = $('#data-url img').attr('src'); + assert.equal(basename(src1).length < 32, true); + const src2 = $('#data-url-no-size img').attr('src'); + assert.equal(basename(src2).length < 32, true); + assert.equal(src1.split('_')[0], src2.split('_')[0]); + }); + + it('adds file extension for data url images', async () => { + const html = await fixture.readFile('/index.html'); + const $ = cheerio.load(html); + const src = $('#data-url img').attr('src'); + assert.equal(src.endsWith('.webp'), true); + }); + + it('writes data url images to dist', async () => { + const html = await fixture.readFile('/index.html'); + const $ = cheerio.load(html); + const src = $('#data-url img').attr('src'); + assert.equal(src.length > 0, true); + const data = await fixture.readFile(src, null); + assert.equal(data instanceof Buffer, true); + }); + + it('infers size of data url images', async () => { + const html = await fixture.readFile('/index.html'); + const $ = cheerio.load(html); + const img = $('#data-url-no-size img'); + const width = img.attr('width'); + const height = img.attr('height'); + assert.equal(width, '256'); + assert.equal(height, '144'); + }); + }); }); diff --git a/packages/astro/test/fixtures/core-image-data-url/package.json b/packages/astro/test/fixtures/core-image-data-url/package.json new file mode 100644 index 0000000000..a402422dbb --- /dev/null +++ b/packages/astro/test/fixtures/core-image-data-url/package.json @@ -0,0 +1,8 @@ +{ + "name": "@test/core-image-data-url", + "version": "0.0.0", + "private": true, + "dependencies": { + "astro": "workspace:*" + } +} \ No newline at end of file diff --git a/packages/astro/test/fixtures/core-image-data-url/src/pages/index.astro b/packages/astro/test/fixtures/core-image-data-url/src/pages/index.astro new file mode 100644 index 0000000000..5e8d291480 --- /dev/null +++ b/packages/astro/test/fixtures/core-image-data-url/src/pages/index.astro @@ -0,0 +1,17 @@ +--- +import { Image } from 'astro:assets'; +const data = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAQAAAACQCAQAAABNan0aAAAABGdBTUEAALGPC/xhBQAAACBjSFJNAAB6JgAAgIQAAPoAAACA6AAAdTAAAOpgAAA6mAAAF3CculE8AAAAAmJLR0QAAKqNIzIAAAAJcEhZcwAACxMAAAsTAQCanBgAAAAHdElNRQflBAsNKgIhYT8HAAAAXklEQVR42u3BMQEAAADCoPVPbQlPoAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA4G8gnwABm4i4EAAAACV0RVh0ZGF0ZTpjcmVhdGUAMjAyMS0wNC0xMVQxMzo0MjowMiswMDowMNhkaiwAAAAldEVYdGRhdGU6bW9kaWZ5ADIwMjEtMDQtMTFUMTM6NDI6MDIrMDA6MDCpOdKQAAAAAElFTkSuQmCC" +--- + + + + + +
+ transparent +
+
+ transparent +
+ + \ No newline at end of file diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index ffb68676bd..08d69a407b 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -2813,6 +2813,12 @@ importers: specifier: workspace:* version: link:../../.. + packages/astro/test/fixtures/core-image-data-url: + dependencies: + astro: + specifier: workspace:* + version: link:../../.. + packages/astro/test/fixtures/core-image-deletion: dependencies: '@astrojs/markdoc':