Skip to content

Commit 918953b

Browse files
lameulerematipico
andauthoredOct 3, 2024··
use shorthash for data url image to prevent ENAMETOOLONG (#12108)
* 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 <my.burning@gmail.com>
1 parent fdba5f3 commit 918953b

File tree

6 files changed

+94
-1
lines changed

6 files changed

+94
-1
lines changed
 

‎.changeset/dull-worms-own.md

+5
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
'astro': patch
3+
---
4+
5+
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.

‎packages/astro/src/assets/utils/transformToPath.ts

+5-1
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,11 @@ import { isESMImportedImage } from './imageKind.js';
88
export function propsToFilename(filePath: string, transform: ImageTransform, hash: string) {
99
let filename = decodeURIComponent(removeQueryString(filePath));
1010
const ext = extname(filename);
11-
filename = basename(filename, ext);
11+
if (filePath.startsWith('data:')) {
12+
filename = shorthash(filePath);
13+
} else {
14+
filename = basename(filename, ext);
15+
}
1216
const prefixDirname = isESMImportedImage(transform.src) ? dirname(filePath) : '';
1317

1418
let outputExt = transform.format ? `.${transform.format}` : ext;

‎packages/astro/test/core-image.test.js

+53
Original file line numberDiff line numberDiff line change
@@ -1263,4 +1263,57 @@ describe('astro:image', () => {
12631263
assert.equal(imgData instanceof Buffer, true);
12641264
});
12651265
});
1266+
1267+
describe('build data url', () => {
1268+
before(async () => {
1269+
fixture = await loadFixture({
1270+
root: './fixtures/core-image-data-url/',
1271+
image: {
1272+
remotePatterns: [
1273+
{
1274+
protocol: 'data',
1275+
},
1276+
],
1277+
},
1278+
});
1279+
1280+
await fixture.build();
1281+
});
1282+
1283+
it('uses short hash for data url filename', async () => {
1284+
const html = await fixture.readFile('/index.html');
1285+
const $ = cheerio.load(html);
1286+
const src1 = $('#data-url img').attr('src');
1287+
assert.equal(basename(src1).length < 32, true);
1288+
const src2 = $('#data-url-no-size img').attr('src');
1289+
assert.equal(basename(src2).length < 32, true);
1290+
assert.equal(src1.split('_')[0], src2.split('_')[0]);
1291+
});
1292+
1293+
it('adds file extension for data url images', async () => {
1294+
const html = await fixture.readFile('/index.html');
1295+
const $ = cheerio.load(html);
1296+
const src = $('#data-url img').attr('src');
1297+
assert.equal(src.endsWith('.webp'), true);
1298+
});
1299+
1300+
it('writes data url images to dist', async () => {
1301+
const html = await fixture.readFile('/index.html');
1302+
const $ = cheerio.load(html);
1303+
const src = $('#data-url img').attr('src');
1304+
assert.equal(src.length > 0, true);
1305+
const data = await fixture.readFile(src, null);
1306+
assert.equal(data instanceof Buffer, true);
1307+
});
1308+
1309+
it('infers size of data url images', async () => {
1310+
const html = await fixture.readFile('/index.html');
1311+
const $ = cheerio.load(html);
1312+
const img = $('#data-url-no-size img');
1313+
const width = img.attr('width');
1314+
const height = img.attr('height');
1315+
assert.equal(width, '256');
1316+
assert.equal(height, '144');
1317+
});
1318+
});
12661319
});
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
{
2+
"name": "@test/core-image-data-url",
3+
"version": "0.0.0",
4+
"private": true,
5+
"dependencies": {
6+
"astro": "workspace:*"
7+
}
8+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
---
2+
import { Image } from 'astro:assets';
3+
const data = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAQAAAACQCAQAAABNan0aAAAABGdBTUEAALGPC/xhBQAAACBjSFJNAAB6JgAAgIQAAPoAAACA6AAAdTAAAOpgAAA6mAAAF3CculE8AAAAAmJLR0QAAKqNIzIAAAAJcEhZcwAACxMAAAsTAQCanBgAAAAHdElNRQflBAsNKgIhYT8HAAAAXklEQVR42u3BMQEAAADCoPVPbQlPoAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA4G8gnwABm4i4EAAAACV0RVh0ZGF0ZTpjcmVhdGUAMjAyMS0wNC0xMVQxMzo0MjowMiswMDowMNhkaiwAAAAldEVYdGRhdGU6bW9kaWZ5ADIwMjEtMDQtMTFUMTM6NDI6MDIrMDA6MDCpOdKQAAAAAElFTkSuQmCC"
4+
---
5+
<html>
6+
<head>
7+
8+
</head>
9+
<body>
10+
<div id="data-url">
11+
<Image src={data} alt="transparent" width="128" height="72" />
12+
</div>
13+
<div id="data-url-no-size">
14+
<Image src={data} inferSize={true} alt="transparent" />
15+
</div>
16+
</body>
17+
</html>

‎pnpm-lock.yaml

+6
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)
Please sign in to comment.