0
Fork 0
mirror of https://github.com/withastro/astro.git synced 2025-02-17 22:44:24 -05:00

Prevent errant HTML from crashing server islands (#11692)

This commit is contained in:
Matthew Phillips 2024-08-15 08:04:02 -04:00 committed by GitHub
parent 44453146cd
commit 35af73aace
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
5 changed files with 30 additions and 3 deletions

View file

@ -0,0 +1,7 @@
---
'astro': patch
---
Prevent errant HTML from crashing server islands
When an HTML minifier strips away the server island comment, the script can't correctly know where the end of the fallback content is. This makes it so that it simply doesn't remove any DOM in that scenario. This means the fallback isn't removed, but it also doesn't crash the browser.

View file

@ -0,0 +1 @@
<div id="first"></div>

View file

@ -1,6 +1,7 @@
--- ---
import Island from '../components/Island.astro'; import Island from '../components/Island.astro';
import Self from '../components/Self.astro'; import Self from '../components/Self.astro';
import HTMLError from '../components/HTMLError.astro';
--- ---
<html> <html>
@ -12,5 +13,16 @@ import Self from '../components/Self.astro';
<h3 id="children">children</h3> <h3 id="children">children</h3>
</Island> </Island>
<Self server:defer /> <Self server:defer />
<div id="error-test">
<HTMLError server:defer>
<script is:inline slot="fallback">
// Delete the previous element, the island comment
document.currentScript.previousSibling.remove();
// This simulates a host which has minified the HTML, destroying the comment
</script>
</HTMLError>
</div>
</body> </body>
</html> </html>

View file

@ -50,6 +50,12 @@ test.describe('Server islands', () => {
await expect(el).toHaveCount(2); await expect(el).toHaveCount(2);
}); });
test('Missing server island start comment doesn\'t cause browser to lock up', async ({ page, astro }) => {
await page.goto(astro.resolveUrl('/base/'));
let el = page.locator('#first');
await expect(el).toHaveCount(1);
});
}); });
test.describe('Development - trailingSlash: ignore', () => { test.describe('Development - trailingSlash: ignore', () => {

View file

@ -86,9 +86,10 @@ if(response.status === 200 && response.headers.get('content-type') === 'text/htm
let html = await response.text(); let html = await response.text();
// Swap! // Swap!
while(script.previousSibling?.nodeType !== 8 && while(script.previousSibling &&
script.previousSibling?.data !== 'server-island-start') { script.previousSibling.nodeType !== 8 &&
script.previousSibling?.remove(); script.previousSibling.data !== 'server-island-start') {
script.previousSibling.remove();
} }
script.previousSibling?.remove(); script.previousSibling?.remove();