Skip to content

Commit 37c8bd7

Browse files
fix: var scope should not extend outside the reactive block (#6800)
Fixes: #6794 --------- Co-authored-by: Simon Holthausen <[email protected]>
1 parent 81cfab9 commit 37c8bd7

File tree

9 files changed

+78
-1
lines changed

9 files changed

+78
-1
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
* Initialize stylesheet with `/* empty */` to enable setting CSP directive that also works in Safari ([#7800](https://github.com/sveltejs/svelte/pull/7800))
2222
* Treat slots as if they don't exist when using CSS adjacent and general sibling combinators ([#8284](https://github.com/sveltejs/svelte/issues/8284))
2323
* 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)).
24+
* Explicitly disallow `var` declarations extending the reactive statement scope ([#6800](https://github.com/sveltejs/svelte/pull/6800))
2425

2526
## Unreleased (3.0)
2627

src/compiler/compile/Component.ts

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ import TemplateScope from './nodes/shared/TemplateScope';
2626
import fuzzymatch from '../utils/fuzzymatch';
2727
import get_object from './utils/get_object';
2828
import Slot from './nodes/Slot';
29-
import { Node, ImportDeclaration, ExportNamedDeclaration, Identifier, ExpressionStatement, AssignmentExpression, Literal, Property, RestElement, ExportDefaultDeclaration, ExportAllDeclaration, FunctionDeclaration, FunctionExpression, ObjectExpression } from 'estree';
29+
import { Node, ImportDeclaration, ExportNamedDeclaration, Identifier, ExpressionStatement, AssignmentExpression, Literal, Property, RestElement, ExportDefaultDeclaration, ExportAllDeclaration, FunctionDeclaration, FunctionExpression, VariableDeclarator, ObjectExpression } from 'estree';
3030
import add_to_set from './utils/add_to_set';
3131
import check_graph_for_cycles from './utils/check_graph_for_cycles';
3232
import { print, b } from 'code-red';
@@ -1356,10 +1356,23 @@ export default class Component {
13561356
const module_dependencies = new Set<string>();
13571357

13581358
let scope = this.instance_scope;
1359+
const { declarations: outset_scope_decalarations } = this.instance_scope;
13591360
const map = this.instance_scope_map;
13601361

13611362
walk(node.body, {
13621363
enter(node: Node, parent) {
1364+
if (node.type === 'VariableDeclaration' && node.kind === 'var') {
1365+
const is_var_in_outset = node.declarations.some((declaration: VariableDeclarator) => {
1366+
const names: string[] = extract_names(declaration.id);
1367+
return !!names.find((name: string) => {
1368+
const var_node = outset_scope_decalarations.get(name);
1369+
return var_node === node;
1370+
});
1371+
});
1372+
if (is_var_in_outset) {
1373+
return component.error(node as any, compiler_errors.invalid_var_declaration);
1374+
}
1375+
}
13631376
if (map.has(node)) {
13641377
scope = map.get(node);
13651378
}

src/compiler/compile/compiler_errors.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -300,6 +300,10 @@ export default {
300300
code: 'invalid-component-style-directive',
301301
message: 'Style directives cannot be used on components'
302302
},
303+
invalid_var_declaration: {
304+
code: 'invalid_var_declaration',
305+
message: '"var" scope should not extend outside the reactive block'
306+
},
303307
invalid_style_directive_modifier: (valid: string) => ({
304308
code: 'invalid-style-directive-modifier',
305309
message: `Valid modifiers for style directives are: ${valid}`
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
[{
2+
"code": "invalid_var_declaration",
3+
"message": "\"var\" scope should not extend outside the reactive block",
4+
"start": { "line": 14, "column": 7 },
5+
"end": { "line": 14, "column": 16 }
6+
}]
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
<script>
2+
var a;
3+
var {a, b: [d, f], c}= {a: 1, b: [1, 2], c: 2};
4+
$: {
5+
function one() {
6+
var a = 'a';
7+
function two() {
8+
var a = 'b';
9+
return a;
10+
}
11+
return two();
12+
}
13+
a = one();
14+
for (var i = 0; i<5; i ++ ) {
15+
// Todo
16+
}
17+
}
18+
</script>
19+
20+
<h1>Hello {a}</h1>
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
[{
2+
"code": "invalid_var_declaration",
3+
"message": "\"var\" scope should not extend outside the reactive block",
4+
"start": { "line": 4, "column": 2 },
5+
"end": { "line": 4, "column": 50 }
6+
}]
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
<script>
2+
$: {
3+
let f = 'f';
4+
var {a, b: [c, d], e} = {a: 1, b: [2, 3], e: 4};
5+
}
6+
</script>
7+
8+
<h1>Hello</h1>
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
[]
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
<script>
2+
var name = 'name';
3+
var c = 'cc';
4+
let d = 'd';
5+
$: {
6+
function a() {
7+
function b() {
8+
var c = 'c';
9+
return c;
10+
}
11+
return b;
12+
}
13+
let d = 'dd';
14+
name = a()();
15+
}
16+
</script>
17+
18+
<h1>Hello {name}</h1>

0 commit comments

Comments
 (0)