From 37c8bd7e6794bcb6ffc8fc4f1a84c2838c2dd7ac Mon Sep 17 00:00:00 2001 From: Vaibhav Rai Date: Fri, 5 May 2023 19:02:27 +0530 Subject: [PATCH] fix: var scope should not extend outside the reactive block (#6800) Fixes: #6794 --------- Co-authored-by: Simon Holthausen --- CHANGELOG.md | 1 + src/compiler/compile/Component.ts | 15 +++++++++++++- src/compiler/compile/compiler_errors.ts | 4 ++++ .../invalid-reactive-var-1/errors.json | 6 ++++++ .../invalid-reactive-var-1/input.svelte | 20 +++++++++++++++++++ .../invalid-reactive-var-2/errors.json | 6 ++++++ .../invalid-reactive-var-2/input.svelte | 8 ++++++++ .../samples/valid-reactive-vars/errors.json | 1 + .../samples/valid-reactive-vars/input.svelte | 18 +++++++++++++++++ 9 files changed, 78 insertions(+), 1 deletion(-) create mode 100644 test/validator/samples/invalid-reactive-var-1/errors.json create mode 100644 test/validator/samples/invalid-reactive-var-1/input.svelte create mode 100644 test/validator/samples/invalid-reactive-var-2/errors.json create mode 100644 test/validator/samples/invalid-reactive-var-2/input.svelte create mode 100644 test/validator/samples/valid-reactive-vars/errors.json create mode 100644 test/validator/samples/valid-reactive-vars/input.svelte diff --git a/CHANGELOG.md b/CHANGELOG.md index 9258e5a3b6..05de113ee2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -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) diff --git a/src/compiler/compile/Component.ts b/src/compiler/compile/Component.ts index 2ca04f3adf..f6ef17f641 100644 --- a/src/compiler/compile/Component.ts +++ b/src/compiler/compile/Component.ts @@ -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(); 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); } diff --git a/src/compiler/compile/compiler_errors.ts b/src/compiler/compile/compiler_errors.ts index 860fa20d9f..6b891d2574 100644 --- a/src/compiler/compile/compiler_errors.ts +++ b/src/compiler/compile/compiler_errors.ts @@ -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}` diff --git a/test/validator/samples/invalid-reactive-var-1/errors.json b/test/validator/samples/invalid-reactive-var-1/errors.json new file mode 100644 index 0000000000..9316d51168 --- /dev/null +++ b/test/validator/samples/invalid-reactive-var-1/errors.json @@ -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 } +}] diff --git a/test/validator/samples/invalid-reactive-var-1/input.svelte b/test/validator/samples/invalid-reactive-var-1/input.svelte new file mode 100644 index 0000000000..7fe774959d --- /dev/null +++ b/test/validator/samples/invalid-reactive-var-1/input.svelte @@ -0,0 +1,20 @@ + + +

Hello {a}

diff --git a/test/validator/samples/invalid-reactive-var-2/errors.json b/test/validator/samples/invalid-reactive-var-2/errors.json new file mode 100644 index 0000000000..c28d767778 --- /dev/null +++ b/test/validator/samples/invalid-reactive-var-2/errors.json @@ -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 } +}] diff --git a/test/validator/samples/invalid-reactive-var-2/input.svelte b/test/validator/samples/invalid-reactive-var-2/input.svelte new file mode 100644 index 0000000000..b3a1c4272c --- /dev/null +++ b/test/validator/samples/invalid-reactive-var-2/input.svelte @@ -0,0 +1,8 @@ + + +

Hello

diff --git a/test/validator/samples/valid-reactive-vars/errors.json b/test/validator/samples/valid-reactive-vars/errors.json new file mode 100644 index 0000000000..fe51488c70 --- /dev/null +++ b/test/validator/samples/valid-reactive-vars/errors.json @@ -0,0 +1 @@ +[] diff --git a/test/validator/samples/valid-reactive-vars/input.svelte b/test/validator/samples/valid-reactive-vars/input.svelte new file mode 100644 index 0000000000..0052101bd9 --- /dev/null +++ b/test/validator/samples/valid-reactive-vars/input.svelte @@ -0,0 +1,18 @@ + + +

Hello {name}