Skip to content

Commit 1219d7d

Browse files
authored
fix(runtime-vapor): guard attrs proxy traps for symbol keys (#14447)
1 parent ccd1ddf commit 1219d7d

2 files changed

Lines changed: 34 additions & 12 deletions

File tree

packages/runtime-vapor/__tests__/component.spec.ts

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import {
88
onUpdated,
99
provide,
1010
ref,
11+
toDisplayString,
1112
useAttrs,
1213
watch,
1314
watchEffect,
@@ -20,6 +21,7 @@ import {
2021
renderEffect,
2122
setInsertionState,
2223
template,
24+
txt,
2325
} from '../src'
2426
import { makeRender } from './_utils'
2527
import type { VaporComponentInstance } from '../src/component'
@@ -510,6 +512,24 @@ describe('component', () => {
510512
'Property "foo" was accessed during render but is not defined on instance.',
511513
).toHaveBeenWarned()
512514
})
515+
516+
test('display attrs', () => {
517+
const App = defineVaporComponent({
518+
props: {},
519+
emits: [],
520+
setup(props, { attrs }) {
521+
const n0 = template('<div> ')() as any
522+
const x0 = txt(n0) as any
523+
renderEffect(() => setText(x0, toDisplayString(attrs)))
524+
return n0
525+
},
526+
})
527+
const { render } = define(App)
528+
expect(render).not.toThrow(TypeError)
529+
expect(
530+
'Unhandled error during execution of setup function',
531+
).not.toHaveBeenWarned()
532+
})
513533
})
514534

515535
function getEffectsCount(scope: EffectScope): number {

packages/runtime-vapor/src/componentProps.ts

Lines changed: 14 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
import {
22
EMPTY_ARR,
33
NO,
4-
YES,
54
camelize,
65
hasOwn,
76
isArray,
@@ -98,9 +97,12 @@ export function getPropsProxyHandlers(
9897
: NO
9998
) as (key: string | symbol) => key is string
10099
const isAttr = propsOptions
101-
? (key: string) =>
102-
key !== '$' && !isProp(key) && !isEmitListener(emitsOptions, key)
103-
: YES
100+
? (key: string | symbol) =>
101+
isString(key) &&
102+
key !== '$' &&
103+
!isProp(key) &&
104+
!isEmitListener(emitsOptions, key)
105+
: (key: string | symbol) => isString(key)
104106

105107
const getProp = (instance: VaporComponentInstance, key: string | symbol) => {
106108
// this enables direct watching of props and prevents `Invalid watch source` DEV warnings.
@@ -200,13 +202,13 @@ export function getPropsProxyHandlers(
200202
})
201203
}
202204

203-
const getAttr = (target: RawProps, key: string) => {
204-
if (!isProp(key) && !isEmitListener(emitsOptions, key)) {
205+
const getAttr = (target: RawProps, key: string | symbol) => {
206+
if (isString(key) && !isProp(key) && !isEmitListener(emitsOptions, key)) {
205207
return getAttrFromRawProps(target, key)
206208
}
207209
}
208210

209-
const hasAttr = (target: RawProps, key: string) => {
211+
const hasAttr = (target: RawProps, key: string | symbol) => {
210212
if (isAttr(key)) {
211213
return hasAttrFromRawProps(target, key)
212214
} else {
@@ -215,15 +217,15 @@ export function getPropsProxyHandlers(
215217
}
216218

217219
const getOnceAttr = withOnceCache((instance, key) =>
218-
getAttr(instance.rawProps, key as string),
220+
getAttr(instance.rawProps, key),
219221
)
220222
const attrsHandlers = {
221-
get: (target, key: string) =>
223+
get: (target, key: string | symbol) =>
222224
once ? getOnceAttr(target, key) : getAttr(target.rawProps, key),
223-
has: (target, key: string) => hasAttr(target.rawProps, key),
225+
has: (target, key: string | symbol) => hasAttr(target.rawProps, key),
224226
ownKeys: target => getKeysFromRawProps(target.rawProps).filter(isAttr),
225-
getOwnPropertyDescriptor(target, key: string) {
226-
if (hasAttr(target.rawProps, key)) {
227+
getOwnPropertyDescriptor(target, key: string | symbol) {
228+
if (isString(key) && hasAttr(target.rawProps, key)) {
227229
return {
228230
configurable: true,
229231
enumerable: true,

0 commit comments

Comments
 (0)