Просмотр исходного кода

fix(runtime-core): prevent self-injection (#2424)

fix #2400
Hunter 5 лет назад
Родитель
Сommit
111d04f119

+ 15 - 0
packages/runtime-core/__tests__/apiInject.spec.ts

@@ -303,4 +303,19 @@ describe('api: provide/inject', () => {
     render(h(Provider), root)
     expect(`injection "foo" not found.`).not.toHaveBeenWarned()
   })
+
+  // #2400
+  it('should not self-inject', () => {
+    const Comp = {
+      setup() {
+        provide('foo', 'foo')
+        const injection = inject('foo', null)
+        return () => injection
+      }
+    }
+
+    const root = nodeOps.createElement('div')
+    render(h(Comp), root)
+    expect(serialize(root)).toBe(`<div><!----></div>`)
+  })
 })

+ 9 - 2
packages/runtime-core/src/apiInject.ts

@@ -47,8 +47,15 @@ export function inject(
   // a functional component
   const instance = currentInstance || currentRenderingInstance
   if (instance) {
-    const provides = instance.provides
-    if ((key as string | symbol) in provides) {
+    // #2400
+    // to support `app.use` plugins,
+    // fallback to appContext's `provides` if the intance is at root
+    const provides =
+      instance.parent == null
+        ? instance.vnode.appContext && instance.vnode.appContext.provides
+        : instance.parent.provides
+
+    if (provides && (key as string | symbol) in provides) {
       // TS doesn't allow symbol as index type
       return provides[key as string]
     } else if (arguments.length > 1) {