]> git.ipfire.org Git - thirdparty/vuejs/core.git/commitdiff
fix(runtime-core): avoid symbol coercion during props validation (#8539)
authorArtyom Tuchkov <throwget@gmail.com>
Wed, 6 May 2026 06:43:29 +0000 (10:43 +0400)
committerGitHub <noreply@github.com>
Wed, 6 May 2026 06:43:29 +0000 (14:43 +0800)
close #8487

packages/runtime-core/__tests__/componentProps.spec.ts
packages/runtime-core/src/componentProps.ts

index b8eb0e4720874764616e18a9eb73352a61fbc20d..9c713806779fb730c141e2dad7d1757760d0800b 100644 (file)
@@ -406,6 +406,8 @@ describe('component props', () => {
       props: {
         bool: { type: Boolean },
         str: { type: String },
+        symStr: { type: String },
+        sym: { type: Symbol },
         num: { type: Number },
         arr: { type: Array },
         obj: { type: Object },
@@ -422,6 +424,8 @@ describe('component props', () => {
       h(Comp, {
         bool: 'true',
         str: 100,
+        symStr: Symbol(),
+        sym: 'symbol',
         num: '100',
         arr: {},
         obj: 'false',
@@ -438,6 +442,12 @@ describe('component props', () => {
     expect(
       `Invalid prop: type check failed for prop "str". Expected String with value "100", got Number with value 100.`,
     ).toHaveBeenWarned()
+    expect(
+      `Invalid prop: type check failed for prop "symStr". Expected String, got Symbol`,
+    ).toHaveBeenWarned()
+    expect(
+      `Invalid prop: type check failed for prop "sym". Expected Symbol, got String with value "symbol".`,
+    ).toHaveBeenWarned()
     expect(
       `Invalid prop: type check failed for prop "num". Expected Number with value 100, got String with value "100".`,
     ).toHaveBeenWarned()
index 775eb8b67281ae74708588a9101b7ba338542cbd..87a73996651be93a805d22020cc13ba3300cc6c3 100644 (file)
@@ -21,6 +21,7 @@ import {
   isOn,
   isReservedProp,
   isString,
+  isSymbol,
   makeMap,
   toRawType,
 } from '@vue/shared'
@@ -777,7 +778,7 @@ function getInvalidTypeMessage(
   if (
     expectedTypes.length === 1 &&
     isExplicable(expectedType) &&
-    !isBoolean(expectedType, receivedType)
+    isCoercible(expectedType, receivedType)
   ) {
     message += ` with value ${expectedValue}`
   }
@@ -793,7 +794,9 @@ function getInvalidTypeMessage(
  * dev only
  */
 function styleValue(value: unknown, type: string): string {
-  if (type === 'String') {
+  if (isSymbol(value)) {
+    return value.toString()
+  } else if (type === 'String') {
     return `"${value}"`
   } else if (type === 'Number') {
     return `${Number(value)}`
@@ -813,6 +816,9 @@ function isExplicable(type: string): boolean {
 /**
  * dev only
  */
-function isBoolean(...args: string[]): boolean {
-  return args.some(elem => elem.toLowerCase() === 'boolean')
+function isCoercible(...args: string[]): boolean {
+  return args.every(elem => {
+    const value = elem.toLowerCase()
+    return value !== 'boolean' && value !== 'symbol'
+  })
 }