Skip to content

Commit

Permalink
use shorthash for data url image to prevent ENAMETOOLONG (#12108)
Browse files Browse the repository at this point in the history
* use shorthash for filename of data url images

* add changeset

* add fixture to test processing of data url images

* run format

* update changeset

* fix test

* Update .changeset/dull-worms-own.md

---------

Co-authored-by: Emanuele Stoppa <[email protected]>
  • Loading branch information
lameuler and ematipico authored Oct 3, 2024
1 parent fdba5f3 commit 918953b
Show file tree
Hide file tree
Showing 6 changed files with 94 additions and 1 deletion.
5 changes: 5 additions & 0 deletions .changeset/dull-worms-own.md
Original file line number Diff line number Diff line change
@@ -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.
6 changes: 5 additions & 1 deletion packages/astro/src/assets/utils/transformToPath.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
53 changes: 53 additions & 0 deletions packages/astro/test/core-image.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -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');
});
});
});
8 changes: 8 additions & 0 deletions packages/astro/test/fixtures/core-image-data-url/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
{
"name": "@test/core-image-data-url",
"version": "0.0.0",
"private": true,
"dependencies": {
"astro": "workspace:*"
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
---
import { Image } from 'astro:assets';
const data = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAQAAAACQCAQAAABNan0aAAAABGdBTUEAALGPC/xhBQAAACBjSFJNAAB6JgAAgIQAAPoAAACA6AAAdTAAAOpgAAA6mAAAF3CculE8AAAAAmJLR0QAAKqNIzIAAAAJcEhZcwAACxMAAAsTAQCanBgAAAAHdElNRQflBAsNKgIhYT8HAAAAXklEQVR42u3BMQEAAADCoPVPbQlPoAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA4G8gnwABm4i4EAAAACV0RVh0ZGF0ZTpjcmVhdGUAMjAyMS0wNC0xMVQxMzo0MjowMiswMDowMNhkaiwAAAAldEVYdGRhdGU6bW9kaWZ5ADIwMjEtMDQtMTFUMTM6NDI6MDIrMDA6MDCpOdKQAAAAAElFTkSuQmCC"
---
<html>
<head>

</head>
<body>
<div id="data-url">
<Image src={data} alt="transparent" width="128" height="72" />
</div>
<div id="data-url-no-size">
<Image src={data} inferSize={true} alt="transparent" />
</div>
</body>
</html>
6 changes: 6 additions & 0 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

0 comments on commit 918953b

Please sign in to comment.