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>
pull/15587/head
Paolo Ricciuti 6 months ago committed by GitHub
parent 7fe9bf524b
commit 3080c1334e
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

@ -0,0 +1,5 @@
---
'svelte': patch
---
fix: prevent state runes from being called with spread

@ -660,6 +660,12 @@ Cannot access a computed property of a rune
`%name%` is not a valid rune
```
### rune_invalid_spread
```
`%rune%` cannot be called with a spread argument
```
### rune_invalid_usage
```

@ -162,6 +162,10 @@ This turned out to be buggy and unpredictable, particularly when working with de
> `%name%` is not a valid rune
## rune_invalid_spread
> `%rune%` cannot be called with a spread argument
## rune_invalid_usage
> Cannot use `%rune%` rune in non-runes mode

@ -383,6 +383,16 @@ export function rune_invalid_name(node, name) {
e(node, 'rune_invalid_name', `\`${name}\` is not a valid rune\nhttps://svelte.dev/e/rune_invalid_name`);
}
/**
* `%rune%` cannot be called with a spread argument
* @param {null | number | NodeLike} node
* @param {string} rune
* @returns {never}
*/
export function rune_invalid_spread(node, rune) {
e(node, 'rune_invalid_spread', `\`${rune}\` cannot be called with a spread argument\nhttps://svelte.dev/e/rune_invalid_spread`);
}
/**
* Cannot use `%rune%` rune in non-runes mode
* @param {null | number | NodeLike} node

@ -17,6 +17,14 @@ export function CallExpression(node, context) {
const rune = get_rune(node, context.state.scope);
if (rune && rune !== '$inspect') {
for (const arg of node.arguments) {
if (arg.type === 'SpreadElement') {
e.rune_invalid_spread(node, rune);
}
}
}
switch (rune) {
case null:
if (!is_safe_identifier(node.callee, context.state.scope)) {

@ -0,0 +1,14 @@
[
{
"code": "rune_invalid_spread",
"end": {
"column": 35,
"line": 3
},
"message": "`$derived.by` cannot be called with a spread argument",
"start": {
"column": 15,
"line": 3
}
}
]

@ -0,0 +1,4 @@
<script>
const args = [0];
const count = $derived.by(...args);
</script>

@ -0,0 +1,14 @@
[
{
"code": "rune_invalid_spread",
"end": {
"column": 32,
"line": 3
},
"message": "`$derived` cannot be called with a spread argument",
"start": {
"column": 15,
"line": 3
}
}
]

@ -0,0 +1,4 @@
<script>
const args = [0];
const count = $derived(...args);
</script>

@ -0,0 +1,14 @@
[
{
"code": "rune_invalid_spread",
"end": {
"column": 34,
"line": 3
},
"message": "`$state.raw` cannot be called with a spread argument",
"start": {
"column": 15,
"line": 3
}
}
]

@ -0,0 +1,4 @@
<script>
const args = [0];
const count = $state.raw(...args);
</script>

@ -0,0 +1,14 @@
[
{
"code": "rune_invalid_spread",
"end": {
"column": 30,
"line": 3
},
"message": "`$state` cannot be called with a spread argument",
"start": {
"column": 15,
"line": 3
}
}
]

@ -0,0 +1,4 @@
<script>
const args = [0];
const count = $state(...args);
</script>
Loading…
Cancel
Save