fix: var scope should not extend outside the reactive block (#6800)

Fixes: #6794

---------

Co-authored-by: Simon Holthausen <simon.holthausen@vercel.com>
pull/8566/head
Vaibhav Rai 2 years ago committed by GitHub
parent 81cfab9142
commit 37c8bd7e67
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -21,6 +21,7 @@
* Initialize stylesheet with `/* empty */` to enable setting CSP directive that also works in Safari ([#7800](https://github.com/sveltejs/svelte/pull/7800))
* Treat slots as if they don't exist when using CSS adjacent and general sibling combinators ([#8284](https://github.com/sveltejs/svelte/issues/8284))
* Fix transitions so that they don't require a `style-src 'unsafe-inline'` Content Security Policy (CSP) ([#6662](https://github.com/sveltejs/svelte/issues/6662)).
* Explicitly disallow `var` declarations extending the reactive statement scope ([#6800](https://github.com/sveltejs/svelte/pull/6800))
## Unreleased (3.0)

@ -26,7 +26,7 @@ import TemplateScope from './nodes/shared/TemplateScope';
import fuzzymatch from '../utils/fuzzymatch';
import get_object from './utils/get_object';
import Slot from './nodes/Slot';
import { Node, ImportDeclaration, ExportNamedDeclaration, Identifier, ExpressionStatement, AssignmentExpression, Literal, Property, RestElement, ExportDefaultDeclaration, ExportAllDeclaration, FunctionDeclaration, FunctionExpression, ObjectExpression } from 'estree';
import { Node, ImportDeclaration, ExportNamedDeclaration, Identifier, ExpressionStatement, AssignmentExpression, Literal, Property, RestElement, ExportDefaultDeclaration, ExportAllDeclaration, FunctionDeclaration, FunctionExpression, VariableDeclarator, ObjectExpression } from 'estree';
import add_to_set from './utils/add_to_set';
import check_graph_for_cycles from './utils/check_graph_for_cycles';
import { print, b } from 'code-red';
@ -1356,10 +1356,23 @@ export default class Component {
const module_dependencies = new Set<string>();
let scope = this.instance_scope;
const { declarations: outset_scope_decalarations } = this.instance_scope;
const map = this.instance_scope_map;
walk(node.body, {
enter(node: Node, parent) {
if (node.type === 'VariableDeclaration' && node.kind === 'var') {
const is_var_in_outset = node.declarations.some((declaration: VariableDeclarator) => {
const names: string[] = extract_names(declaration.id);
return !!names.find((name: string) => {
const var_node = outset_scope_decalarations.get(name);
return var_node === node;
});
});
if (is_var_in_outset) {
return component.error(node as any, compiler_errors.invalid_var_declaration);
}
}
if (map.has(node)) {
scope = map.get(node);
}

@ -300,6 +300,10 @@ export default {
code: 'invalid-component-style-directive',
message: 'Style directives cannot be used on components'
},
invalid_var_declaration: {
code: 'invalid_var_declaration',
message: '"var" scope should not extend outside the reactive block'
},
invalid_style_directive_modifier: (valid: string) => ({
code: 'invalid-style-directive-modifier',
message: `Valid modifiers for style directives are: ${valid}`

@ -0,0 +1,6 @@
[{
"code": "invalid_var_declaration",
"message": "\"var\" scope should not extend outside the reactive block",
"start": { "line": 14, "column": 7 },
"end": { "line": 14, "column": 16 }
}]

@ -0,0 +1,20 @@
<script>
var a;
var {a, b: [d, f], c}= {a: 1, b: [1, 2], c: 2};
$: {
function one() {
var a = 'a';
function two() {
var a = 'b';
return a;
}
return two();
}
a = one();
for (var i = 0; i<5; i ++ ) {
// Todo
}
}
</script>
<h1>Hello {a}</h1>

@ -0,0 +1,6 @@
[{
"code": "invalid_var_declaration",
"message": "\"var\" scope should not extend outside the reactive block",
"start": { "line": 4, "column": 2 },
"end": { "line": 4, "column": 50 }
}]

@ -0,0 +1,8 @@
<script>
$: {
let f = 'f';
var {a, b: [c, d], e} = {a: 1, b: [2, 3], e: 4};
}
</script>
<h1>Hello</h1>

@ -0,0 +1,18 @@
<script>
var name = 'name';
var c = 'cc';
let d = 'd';
$: {
function a() {
function b() {
var c = 'c';
return c;
}
return b;
}
let d = 'dd';
name = a()();
}
</script>
<h1>Hello {name}</h1>
Loading…
Cancel
Save