fix: improve compiler attribute validation logic (#12081)

prevent misidentification of bindings as delegatable event handlers if used outside event attribute
Fixes #12074

---------

Co-authored-by: Rich Harris <rich.harris@vercel.com>
pull/12085/head
Dominic Gannaway 5 months ago committed by GitHub
parent 69ee547c21
commit 696a4b3dae
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

@ -0,0 +1,5 @@
---
"svelte": patch
---
fix: prevent misidentification of bindings as delegatable event handlers if used outside event attribute

@ -111,23 +111,24 @@ function get_delegated_event(event_name, handler, context) {
if (binding != null) { if (binding != null) {
for (const { path } of binding.references) { for (const { path } of binding.references) {
const parent = path.at(-1); const parent = path.at(-1);
if (parent == null) { if (parent == null) return non_hoistable;
return non_hoistable;
} const grandparent = path.at(-2);
/** @type {import('#compiler').RegularElement | null} */ /** @type {import('#compiler').RegularElement | null} */
let element = null; let element = null;
/** @type {string | null} */ /** @type {string | null} */
let event_name = null; let event_name = null;
if (parent.type === 'OnDirective') { if (parent.type === 'OnDirective') {
element = /** @type {import('#compiler').RegularElement} */ (path.at(-2)); element = /** @type {import('#compiler').RegularElement} */ (grandparent);
event_name = parent.name; event_name = parent.name;
} else if ( } else if (
parent.type === 'ExpressionTag' && parent.type === 'ExpressionTag' &&
is_event_attribute(/** @type {import('#compiler').Attribute} */ (path.at(-2))) grandparent?.type === 'Attribute' &&
is_event_attribute(grandparent)
) { ) {
element = /** @type {import('#compiler').RegularElement} */ (path.at(-3)); element = /** @type {import('#compiler').RegularElement} */ (path.at(-3));
const attribute = /** @type {import('#compiler').Attribute} */ (path.at(-2)); const attribute = /** @type {import('#compiler').Attribute} */ (grandparent);
event_name = get_attribute_event_name(attribute.name); event_name = get_attribute_event_name(attribute.name);
} }

@ -0,0 +1,7 @@
import { test } from '../../test';
export default test({
test() {
// Compiler shouldn't error
}
});

@ -0,0 +1,5 @@
<script>
function f() {}
</script>
<input onchange={f}>{f}
Loading…
Cancel
Save