Skip to content

Commit fd0bc29

Browse files
fix: correctly validate head snippets on the server (#15755)
* fix: correctly validate head snippets on the server * put the logic in copy_payload so it gets treeshaken in most cases --------- Co-authored-by: Rich Harris <rich.harris@vercel.com>
1 parent 3153384 commit fd0bc29

File tree

5 files changed

+50
-15
lines changed

5 files changed

+50
-15
lines changed

.changeset/dirty-zebras-do.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
'svelte': patch
3+
---
4+
5+
fix: correctly validate head snippets on the server

packages/svelte/src/internal/server/dev.js

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ import {
66
} from '../../html-tree-validation.js';
77
import { current_component } from './context.js';
88
import { invalid_snippet_arguments } from '../shared/errors.js';
9-
import { Payload } from './payload.js';
9+
import { HeadPayload, Payload } from './payload.js';
1010

1111
/**
1212
* @typedef {{
@@ -105,7 +105,11 @@ export function pop_element() {
105105
* @param {Payload} payload
106106
*/
107107
export function validate_snippet_args(payload) {
108-
if (typeof payload !== 'object' || !(payload instanceof Payload)) {
108+
if (
109+
typeof payload !== 'object' ||
110+
// for some reason typescript consider the type of payload as never after the first instanceof
111+
!(payload instanceof Payload || /** @type {any} */ (payload) instanceof HeadPayload)
112+
) {
109113
invalid_snippet_arguments();
110114
}
111115
}

packages/svelte/src/internal/server/payload.js

Lines changed: 21 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,25 @@
1+
export class HeadPayload {
2+
/** @type {Set<{ hash: string; code: string }>} */
3+
css = new Set();
4+
out = '';
5+
uid = () => '';
6+
title = '';
7+
8+
constructor(css = new Set(), out = '', title = '', uid = () => '') {
9+
this.css = css;
10+
this.out = out;
11+
this.title = title;
12+
this.uid = uid;
13+
}
14+
}
15+
116
export class Payload {
217
/** @type {Set<{ hash: string; code: string }>} */
318
css = new Set();
419
out = '';
520
uid = () => '';
621

7-
head = {
8-
/** @type {Set<{ hash: string; code: string }>} */
9-
css: new Set(),
10-
title: '',
11-
out: '',
12-
uid: () => ''
13-
};
22+
head = new HeadPayload();
1423

1524
constructor(id_prefix = '') {
1625
this.uid = props_id_generator(id_prefix);
@@ -30,12 +39,11 @@ export function copy_payload({ out, css, head, uid }) {
3039
payload.css = new Set(css);
3140
payload.uid = uid;
3241

33-
payload.head = {
34-
title: head.title,
35-
out: head.out,
36-
css: new Set(head.css),
37-
uid: head.uid
38-
};
42+
payload.head = new HeadPayload();
43+
payload.head.out = head.out;
44+
payload.head.css = new Set(head.css);
45+
payload.head.title = head.title;
46+
payload.head.uid = head.uid;
3947

4048
return payload;
4149
}
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
import { test } from '../../test';
2+
3+
export default test({
4+
compileOptions: {
5+
dev: true
6+
},
7+
mode: ['server'],
8+
async test({ errors, assert }) {
9+
assert.equal(errors, []);
10+
}
11+
});
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
{#snippet head()}
2+
<title>Cool</title>
3+
{/snippet}
4+
5+
<svelte:head>
6+
{@render head()}
7+
</svelte:head>

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy