Skip to content

Commit e2ad0bb

Browse files
committed
Prevent embedding images with empty src attribute
1 parent 1a31d9a commit e2ad0bb

File tree

7 files changed

+55
-1
lines changed

7 files changed

+55
-1
lines changed

src/embed-images.ts

+11
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,17 @@ async function embedImageNode<T extends HTMLElement | SVGImageElement>(
4040
) {
4141
const isImageElement = isInstanceOfElement(clonedNode, HTMLImageElement)
4242

43+
// Skip images with empty sources. Note that reading the src property of an HTMLImageElement (or href of SVGImageElement)
44+
// which has an empty value will return the current URL.
45+
// This is a workaround to prevent the loading of current page URL as an image when there are empty images in the DOM.
46+
if (
47+
(isImageElement && clonedNode.getAttribute('src') === '') ||
48+
(isInstanceOfElement(clonedNode, SVGImageElement) &&
49+
clonedNode.getAttribute('href') === '')
50+
) {
51+
return
52+
}
53+
4354
if (
4455
!(isImageElement && !isDataUrl(clonedNode.src)) &&
4556
!(

test/resources/images/node-empty-png

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAASwAAAEsCAYAAAB5fY51AAAAAXNSR0IArs4c6QAAEihJREFUeF7t3XeoHFUfBuBjb1FRrNgVO2IFCxYQe8GC2GIXBdsfKjYQbGCv2LCLYgGxoaIIKoqoiAXEhtiw9y528/Fb2P3ujffmbmLeJBufA6Ims+/OfWbuy8zsmdlZJkyYMKEZBAgQGACBWRTWAGwlq0iAQEdAYdkRCBAYGAGFNTCbyooSIKCw7AMECAyMgMIamE1lRQkQUFj2AQIEBkZAYQ3MprKiBAgoLPsAAQIDI6CwBmZTWVECBBSWfYAAgYERUFgDs6msKAECCss+QIDAwAgorIHZVFaUAAGFZR8gQGBgBBTWwGwqK0qAgMKyDxAgMDACCmtgNpUVJUBAYdkHCBAYGAGFNTCbyooSIKCw7AMECAyMgMIamE1lRQkQUFj2AQIEBkZAYQ3MprKiBAgoLPsAAQIDI6CwBmZTWVECBBSWfYAAgYERUFgDs6msKAECCss+QIDAwAgorIHZVFaUAAGFZR8gQGBgBBTWwGwqK0qAgMKyDxAgMDACCmtgNpUVJUBAYdkHCBAYGIFIYf3+++/txhtvnCTCrLPO2uaff/624IILtrXWWqsts8wyfaH9+OOP7bbbbhu27JxzztkOOeSQMV//4Ycftoceeqi33Lrrrts23HDDMV/XXeCLL75o999/f3vkkUdaZX366aet3nvVVVft/LPOOuu0vfbaq80999x9Z1qQAIH+BSKF9d1337WFFlqo/7VorS211FJt/Pjx7cgjj2zLLbfcqK99//332worrPCPv3/yySfb5ptvPsn3rKLZfvvte8ucfPLJ7ZxzzhlzPb///vt2yimntGuuuab9/fffk1x+iSWWaMcdd1w74ogj2rhx48bMtgABAv0LzDCF1V3leeedt11wwQWd4hppjFZYe++9d7vjjjumemG9/PLLbccdd+wcTU3OqPKsEjUIEJh6AtOksOaYY4624oorDlvrP/74o3NaVf8eaZx//vnthBNO+MdfjVZYdWpWeYstttioOpN7hPXKK6+0Lbfcsn399de9zPpZtttuu84/Sy+9dKtT248//rg98cQT7cEHH2w///xzZ9mNNtqoPfvss1NvS0kiQKBNk8Jafvnl23vvvfcP7r/++qt98MEH7corr2yXXXZZ+/PPP3vLzDLLLO35559vG2ywwbDXjVZYtdDZZ5/dOXUbbUxOYf30009tjTXW6JRgd6y33nrt9ttv71yvGmnUqeO5557bLr300s71LIXlN4zA1BWYroU19Ed54YUX2qabbtp+++233h/vtNNO7YEHHphkYc0222ytiq9GXft69913O0c9I43JKaxjjz22UzzdUR8MPPPMM31dl3rppZdaHSHeeeedU3drSSPwHxeYYQqrtkP9kp900km9TTLXXHO1b7/9ts0zzzy9P5v4CKtO2epIrI6IatRpWV1z+jeFVUeDK6+8cq8IZ5999vbaa6+1VVZZpe/dpU516/TRIEBg6gnMUIVVpVNTHYaOOqrZeOONRy2sXXfdtS2++OKdT/BqVFlVaf2bwjr99NPbGWec0Ys46KCD2k033TT11CURIDBFAjNUYdVPsOyyyw67bnTfffe1XXbZZZKFVQVT14xq1OngO++80+q62cSj31PC+oBg6DW3p556qm222WZTBOxFBAhMPYEZrrDqIvuLL77Y+wnrIvc+++wzycK699572yabbNK7yF0X3usC/JQUVl0DW2mllXovrflkX375ZatrZQYBAtNXYIYrrJr5/sMPP/RU6qho2223HbOwbr311nbAAQd0lqupDfXpXk11GDr6OcK666672p577tl72dZbb90effTR6buVvDsBAh2BGaqw3n777c7F7qHjjTfeaKutttqYhfXrr7925kV150zVJNKaTDq5hVVHZzU1oTuOPvrodvnll9tdCBCYAQRmqMLaYYcd2sMPP9xjWXLJJdsnn3wyjGniTwnronudEtaoiaYXXnhh579HmmnezxFWHaXV0Vp3XHzxxa2mOBgECEx/gRmisGp2+Kmnnjps3lPRnHjiie28887ru7DqCK2mHkyYMKHzmldffbWtueaavdf3U1hVgHWDc3fUp4+HH3749N9S1oAAgWlzSlhHSvfcc88w7pqnVEdLb731Vrv55pvbRx99NOzva6rC66+/3hZeeOG+C6sWrOtd3WtOE5/O9VNYNa+rbrPpjltuuaXtv//+I+4qNQ2jSnG0UVM0hham/Y0AgX8nME2OsCZ3FeuTuccff7w3VWHo6yd1SljL1TSI3XbbrfOSBRZYoHNKOd9883X+v5/CqukLTz/9dO8t61E2++6774g/wnPPPTdsjtjEC7mfcHK3vOUJTFpghiusbbbZpl1//fWjPh9rrMKq23RqDlb3iO3aa69thx12WN+FNfF1tBtuuGHUZ20pLL9eBKatwHQtrJp20H2AX81mr/lWY51CjVVYxXfmmWe20047rSNZD+mre/v6PcKqdRh6D+AVV1zRjjrqKEdY03a/9G4ERhSYJoVVNyW/+eabw1agZqRPPE+qn23UT2HVaWC9Z/fpD3UkVE8W7eeUsJ7DdfXVV/dWpYqvZtKPNOri/tCbtWuZofc9OiXsZ4tahkD/AtOksEZ7vEz/q/n/JfsprFp6jz32aHfffXfnhQceeGDnwn4/hVVHVMccc0zvDffbb79h0xzGWud6LE53KKyxtPw9gckTmGkL67HHHmtbbbVVR6OesV4P2aunOoz1iOS64D70vsH111+/1aNv+h0Kq18pyxGYfIGZtrDqdK1myNe0iRoXXXRR54F8YxVWTVWoqRTdJ6HWqevnn3/eFllkkb50FVZfTBYiMEUCM21hlcYll1zS+UKIGnXLTz3VtD4F7I7RvoRi9913782er2Un9UnhxOoKa4r2Qy8i0JfATF1Y9fC/+jaeX375pYNR5VW32oxVWDXTvWa8d8fqq6/emSA62pNMh0orrL72OwsRmCKBmbqwSuTggw/uXHCvUad633zzzZiFVZ8urr322p2Z9t1R9ygef/zxYyIrrDGJLEBgigVm+sKqC+2jfVnqpL6XsB7at8UWW/Rg63lYdWpYnziONqrohj4W2aeEU7xfeiGBEQVm+sKqn7o+6etOHh2qMNYXqQ59+kP3dTvvvHPnS1LrnsN65nyN+kboupWo5mx1L/LXnyssv3UEpq7Af6Kw6laf7u05k1NYtWzNcr/qqqtGVK9PDus5XN0vwJh4oZpw2p1xP3U3mzQC/02B/0Rh1eNr6uJ7fW/g5BZWTY+47rrrOt93OPT616R2l3qveuhf9ybs/+au5acmMPUFIoVVRxz1nYLdUY+XGetr5Pv90T777LNhTxKtSZ5nnXXWmC+v52oNfThgvWD8+PEjHnmNFPbVV191iqtmzw995nx32bp2VaeA9ZTTQw89tHe6OOaKWYAAgb4FIoXV97sP6IJ1pFUz56s8a6rDoosu2uqbdsaNGzegP5HVJjAYAgprMLaTtSRAIPUlFGQJECCQEHCElVCVSYBAREBhRViFEiCQEFBYCVWZBAhEBBRWhFUoAQIJAYWVUJVJgEBEQGFFWIUSIJAQUFgJVZkECEQEFFaEVSgBAgkBhZVQlUmAQERAYUVYhRIgkBBQWAlVmQQIRAQUVoRVKAECCQGFlVCVSYBAREBhRViFEiCQEFBYCVWZBAhEBBRWhFUoAQIJAYWVUJVJgEBEQGFFWIUSIJAQUFgJVZkECEQEFFaEVSgBAgkBhZVQlUmAQERAYUVYhRIgkBBQWAlVmQQIRAQUVoRVKAECCQGFlVCVSYBAREBhRViFEiCQEFBYCVWZBAhEBBRWhFUoAQIJAYWVUJVJgEBEQGFFWIUSIJAQUFgJVZkECEQEFFaEVSgBAgkBhZVQlUmAQERAYUVYhRIgkBBQWAlVmQQIRAQUVoRVKAECCQGFlVCVSYBAREBhRViFEiCQEFBYCVWZBAhEBBRWhFUoAQIJAYWVUJVJgEBEQGFFWIUSIJAQUFgJVZkECEQEFFaEVSgBAgkBhZVQlUmAQERAYUVYhRIgkBBQWAlVmQQIRAQUVoRVKAECCQGFlVCVSYBAREBhRViFEiCQEFBYCVWZBAhEBBRWhFUoAQIJAYWVUJVJgEBEQGFFWIUSIJAQUFgJVZkECEQEFFaEVSgBAgkBhZVQlUmAQERAYUVYhRIgkBBQWAlVmQQIRAQUVoRVKAECCQGFlVCVSYBAREBhRViFEiCQEFBYCVWZBAhEBBRWhFUoAQIJAYWVUJVJgEBEQGFFWIUSIJAQUFgJVZkECEQEFFaEVSgBAgkBhZVQlUmAQERAYUVYhRIgkBBQWAlVmQQIRAQUVoRVKAECCQGFlVCVSYBAREBhRViFEiCQEFBYCVWZBAhEBBRWhFUoAQIJAYWVUJVJgEBEQGFFWIUSIJAQUFgJVZkECEQEFFaEVSgBAgkBhZVQlUmAQERAYUVYhRIgkBBQWAlVmQQIRAQUVoRVKAECCQGFlVCVSYBAREBhRViFEiCQEFBYCVWZBAhEBBRWhFUoAQIJAYWVUJVJgEBEQGFFWIUSIJAQUFgJVZkECEQEFFaEVSgBAgkBhZVQlUmAQERAYUVYhRIgkBBQWAlVmQQIRAQUVoRVKAECCQGFlVCVSYBAREBhRViFEiCQEFBYCVWZBAhEBBRWhFUoAQIJAYWVUJVJgEBEQGFFWIUSIJAQUFgJVZkECEQEFFaEVSgBAgkBhZVQlUmAQERAYUVYhRIgkBBQWAlVmQQIRAQUVoRVKAECCQGFlVCVSYBAREBhRViFEiCQEFBYCVWZBAhEBBRWhFUoAQIJAYWVUJVJgEBEQGFFWIUSIJAQUFgJVZkECEQEFFaEVSgBAgkBhZVQlUmAQERAYUVYhRIgkBBQWAlVmQQIRAQUVoRVKAECCQGFlVCVSYBAREBhRViFEiCQEFBYCVWZBAhEBBRWhFUoAQIJAYWVUJVJgEBEQGFFWIUSIJAQUFgJVZkECEQEFFaEVSgBAgkBhZVQlUmAQERAYUVYhRIgkBBQWAlVmQQIRAQUVoRVKAECCQGFlVCVSYBAREBhRViFEiCQEFBYCVWZBAhEBBRWhFUoAQIJAYWVUJVJgEBEQGFFWIUSIJAQUFgJVZkECEQEFFaEVSgBAgkBhZVQlUmAQERAYUVYhRIgkBBQWAlVmQQIRAQUVoRVKAECCQGFlVCVSYBAREBhRViFEiCQEFBYCVWZBAhEBBRWhFUoAQIJAYWVUJVJgEBEQGFFWIUSIJAQUFgJVZkECEQEFFaEVSgBAgkBhZVQlUmAQERAYUVYhRIgkBBQWAlVmQQIRAQUVoRVKAECCQGFlVCVSYBAREBhRViFEiCQEFBYCVWZBAhEBBRWhFUoAQIJAYWVUJVJgEBEQGFFWIUSIJAQUFgJVZkECEQEFFaEVSgBAgkBhZVQlUmAQERAYUVYhRIgkBBQWAlVmQQIRAQUVoRVKAECCQGFlVCVSYBAREBhRViFEiCQEFBYCVWZBAhEBBRWhFUoAQIJAYWVUJVJgEBEQGFFWIUSIJAQUFgJVZkECEQEFFaEVSgBAgkBhZVQlUmAQERAYUVYhRIgkBBQWAlVmQQIRAQUVoRVKAECCQGFlVCVSYBAREBhRViFEiCQEFBYCVWZBAhEBBRWhFUoAQIJAYWVUJVJgEBEQGFFWIUSIJAQUFgJVZkECEQEFFaEVSgBAgkBhZVQlUmAQERAYUVYhRIgkBBQWAlVmQQIRAQUVoRVKAECCQGFlVCVSYBAREBhRViFEiCQEFBYCVWZBAhEBBRWhFUoAQIJAYWVUJVJgEBEQGFFWIUSIJAQUFgJVZkECEQEFFaEVSgBAgkBhZVQlUmAQERAYUVYhRIgkBBQWAlVmQQIRAQUVoRVKAECCQGFlVCVSYBAREBhRViFEiCQEFBYCVWZBAhEBBRWhFUoAQIJAYWVUJVJgEBEQGFFWIUSIJAQUFgJVZkECEQEFFaEVSgBAgkBhZVQlUmAQERAYUVYhRIgkBBQWAlVmQQIRAQUVoRVKAECCQGFlVCVSYBAREBhRViFEiCQEFBYCVWZBAhEBBRWhFUoAQIJAYWVUJVJgEBEQGFFWIUSIJAQUFgJVZkECEQEFFaEVSgBAgkBhZVQlUmAQERAYUVYhRIgkBBQWAlVmQQIRAQUVoRVKAECCQGFlVCVSYBAREBhRViFEiCQEFBYCVWZBAhEBBRWhFUoAQIJgf8Bkmz29QpmUTEAAAAASUVORK5CYII=

test/resources/images/node-empty.html

+2
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
<img src="" />
2+
<img src="/base/test/resources/images/image.png" />
+17
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
<svg
2+
width="200"
3+
height="200"
4+
viewBox="0 0 200 200"
5+
xmlns="http://www.w3.org/2000/svg"
6+
>
7+
<image
8+
height="200"
9+
width="200"
10+
href="/base/test/resources/svg-image/svg-image.png"
11+
/>
12+
<image
13+
height="200"
14+
width="200"
15+
href=""
16+
/>
17+
</svg>

test/spec/basic.spec.ts

+12
Original file line numberDiff line numberDiff line change
@@ -183,6 +183,18 @@ describe('basic usage', () => {
183183
.catch(done)
184184
})
185185

186+
it('should not fail on empty images', (done) => {
187+
bootstrap(
188+
'images/node-empty.html',
189+
'images/style.css',
190+
'images/node-empty-png',
191+
)
192+
.then(delay(500))
193+
.then(assertTextRendered(['PNG']))
194+
.then(done)
195+
.catch(done)
196+
})
197+
186198
it('should render webp images', (done) => {
187199
bootstrap('webp/node.html', 'webp/style.css')
188200
.then(delay(500))

test/spec/helper.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -164,7 +164,7 @@ export async function getSvgDocument(dataUrl: string): Promise<XMLDocument> {
164164
.then((str) => new window.DOMParser().parseFromString(str, 'text/xml'))
165165
}
166166

167-
const PASS_TEXT_MATCH = true
167+
const PASS_TEXT_MATCH = false
168168

169169
export function assertTextRendered(lines: string[], options?: Options) {
170170
return (node: HTMLDivElement = getCaptureNode()) =>

test/spec/svg.spec.ts

+11
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,17 @@ describe('work with svg element', () => {
4747
.catch(done)
4848
})
4949

50+
it('should not fail on empty href in svg `<image>`', (done) => {
51+
bootstrap(
52+
'svg-image/node-empty.html',
53+
'svg-image/style.css',
54+
'svg-image/image',
55+
)
56+
.then(renderAndCheck)
57+
.then(done)
58+
.catch(done)
59+
})
60+
5061
it('should render SVG use tags', function (done) {
5162
bootstrap(
5263
'svg-use-tag/node.html',

0 commit comments

Comments
 (0)