fix: disallow accessing internal Svelte props (#12207)

closes #12184
pull/12219/head
Simon H 6 months ago committed by GitHub
parent 33e44ea697
commit c42bb04276
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

@ -0,0 +1,5 @@
---
'svelte': patch
---
fix: disallow accessing internal Svelte props

@ -78,6 +78,10 @@
> Cannot use `$props()` more than once
## props_illegal_name
> Declaring or accessing a prop starting with `$$` is illegal (they are reserved for Svelte internals)
## props_invalid_identifier
> `$props()` can only be used with an object destructuring pattern

@ -276,6 +276,15 @@ export function props_duplicate(node) {
e(node, "props_duplicate", "Cannot use `$props()` more than once");
}
/**
* Declaring or accessing a prop starting with `$$` is illegal (they are reserved for Svelte internals)
* @param {null | number | NodeLike} node
* @returns {never}
*/
export function props_illegal_name(node) {
e(node, "props_illegal_name", "Declaring or accessing a prop starting with `$$` is illegal (they are reserved for Svelte internals)");
}
/**
* `$props()` can only be used with an object destructuring pattern
* @param {null | number | NodeLike} node

@ -341,6 +341,14 @@ function validate_block_not_empty(node, context) {
* @type {import('zimmerframe').Visitors<import('#compiler').SvelteNode, import('./types.js').AnalysisState>}
*/
const validation = {
MemberExpression(node, context) {
if (node.object.type === 'Identifier' && node.property.type === 'Identifier') {
const binding = context.state.scope.get(node.object.name);
if (binding?.kind === 'rest_prop' && node.property.name.startsWith('$$')) {
e.props_illegal_name(node.property);
}
}
},
AssignmentExpression(node, context) {
validate_assignment(node, node.left, context.state);
},
@ -1255,6 +1263,10 @@ export const validation_runes = merge(validation, a11y_validators, {
e.props_invalid_pattern(property);
}
if (property.key.type === 'Identifier' && property.key.name.startsWith('$$')) {
e.props_illegal_name(property);
}
const value =
property.value.type === 'AssignmentPattern' ? property.value.left : property.value;

@ -0,0 +1,9 @@
import { test } from '../../test';
export default test({
error: {
code: 'props_illegal_name',
message:
'Declaring or accessing a prop starting with `$$` is illegal (they are reserved for Svelte internals)'
}
});

@ -0,0 +1,9 @@
import { test } from '../../test';
export default test({
error: {
code: 'props_illegal_name',
message:
'Declaring or accessing a prop starting with `$$` is illegal (they are reserved for Svelte internals)'
}
});

@ -0,0 +1,4 @@
<script>
let props = $props();
props.$$slots;
</script>
Loading…
Cancel
Save