Skip to content

Commit 3080c13

Browse files
fix: prevent state runes from being called with spread (#15585)
* fix: prevent state runes from being called with spread * prevent spread arguments for all runes except $inspect --------- Co-authored-by: Rich Harris <rich.harris@vercel.com>
1 parent 7fe9bf5 commit 3080c13

File tree

13 files changed

+105
-0
lines changed

13 files changed

+105
-0
lines changed

.changeset/nice-pianos-punch.md

+5
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
'svelte': patch
3+
---
4+
5+
fix: prevent state runes from being called with spread

documentation/docs/98-reference/.generated/compile-errors.md

+6
Original file line numberDiff line numberDiff line change
@@ -660,6 +660,12 @@ Cannot access a computed property of a rune
660660
`%name%` is not a valid rune
661661
```
662662

663+
### rune_invalid_spread
664+
665+
```
666+
`%rune%` cannot be called with a spread argument
667+
```
668+
663669
### rune_invalid_usage
664670

665671
```

packages/svelte/messages/compile-errors/script.md

+4
Original file line numberDiff line numberDiff line change
@@ -162,6 +162,10 @@ This turned out to be buggy and unpredictable, particularly when working with de
162162

163163
> `%name%` is not a valid rune
164164
165+
## rune_invalid_spread
166+
167+
> `%rune%` cannot be called with a spread argument
168+
165169
## rune_invalid_usage
166170

167171
> Cannot use `%rune%` rune in non-runes mode

packages/svelte/src/compiler/errors.js

+10
Original file line numberDiff line numberDiff line change
@@ -383,6 +383,16 @@ export function rune_invalid_name(node, name) {
383383
e(node, 'rune_invalid_name', `\`${name}\` is not a valid rune\nhttps://svelte.dev/e/rune_invalid_name`);
384384
}
385385

386+
/**
387+
* `%rune%` cannot be called with a spread argument
388+
* @param {null | number | NodeLike} node
389+
* @param {string} rune
390+
* @returns {never}
391+
*/
392+
export function rune_invalid_spread(node, rune) {
393+
e(node, 'rune_invalid_spread', `\`${rune}\` cannot be called with a spread argument\nhttps://svelte.dev/e/rune_invalid_spread`);
394+
}
395+
386396
/**
387397
* Cannot use `%rune%` rune in non-runes mode
388398
* @param {null | number | NodeLike} node

packages/svelte/src/compiler/phases/2-analyze/visitors/CallExpression.js

+8
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,14 @@ export function CallExpression(node, context) {
1717

1818
const rune = get_rune(node, context.state.scope);
1919

20+
if (rune && rune !== '$inspect') {
21+
for (const arg of node.arguments) {
22+
if (arg.type === 'SpreadElement') {
23+
e.rune_invalid_spread(node, rune);
24+
}
25+
}
26+
}
27+
2028
switch (rune) {
2129
case null:
2230
if (!is_safe_identifier(node.callee, context.state.scope)) {
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
[
2+
{
3+
"code": "rune_invalid_spread",
4+
"end": {
5+
"column": 35,
6+
"line": 3
7+
},
8+
"message": "`$derived.by` cannot be called with a spread argument",
9+
"start": {
10+
"column": 15,
11+
"line": 3
12+
}
13+
}
14+
]
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
<script>
2+
const args = [0];
3+
const count = $derived.by(...args);
4+
</script>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
[
2+
{
3+
"code": "rune_invalid_spread",
4+
"end": {
5+
"column": 32,
6+
"line": 3
7+
},
8+
"message": "`$derived` cannot be called with a spread argument",
9+
"start": {
10+
"column": 15,
11+
"line": 3
12+
}
13+
}
14+
]
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
<script>
2+
const args = [0];
3+
const count = $derived(...args);
4+
</script>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
[
2+
{
3+
"code": "rune_invalid_spread",
4+
"end": {
5+
"column": 34,
6+
"line": 3
7+
},
8+
"message": "`$state.raw` cannot be called with a spread argument",
9+
"start": {
10+
"column": 15,
11+
"line": 3
12+
}
13+
}
14+
]
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
<script>
2+
const args = [0];
3+
const count = $state.raw(...args);
4+
</script>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
[
2+
{
3+
"code": "rune_invalid_spread",
4+
"end": {
5+
"column": 30,
6+
"line": 3
7+
},
8+
"message": "`$state` cannot be called with a spread argument",
9+
"start": {
10+
"column": 15,
11+
"line": 3
12+
}
13+
}
14+
]
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
<script>
2+
const args = [0];
3+
const count = $state(...args);
4+
</script>

0 commit comments

Comments
 (0)