Repository: vuejs/vue
Pull request: fix(inject): hasOwn instead of 'in' (fix #7284)

The issue was caused by the [`in` operator check](https://github.com/vuejs/vue/blob/dev/src/core/instance/inject.js#L55) to see if an injection exists in a parent provide.

In the particular Issue, the injection didn't work because the the Symbol polyfill adds a setter to the Object prototype for every Symbol created and the `in`-operator check evaluated to true on any object inheriting Object. [Demo](http://jsfiddle.net/hirokiosame/dronjdzm/23/)

However, I'm thinking the implications of using `in` may be further reaching as it could have been any native prototype property. [Here](http://jsfiddle.net/hirokiosame/dronjdzm/24/) I demonstrate using the string `'constructor'` leads to unexpected injection behavior.

Although this fixes #7284, I am framing this as a fix for prototype properties being injected.

<!--
Please make sure to read the Pull Request Guidelines:
https://github.com/vuejs/vue/blob/dev/.github/CONTRIBUTING.md#pull-request-guidelines
-->

<!-- PULL REQUEST TEMPLATE -->
<!-- (Update "[ ]" to "[x]" to check a box) -->

**What kind of change does this PR introduce?** (check at least one)

- [x] Bugfix
- [ ] Feature
- [ ] Code style update
- [ ] Refactor
- [ ] Build-related changes
- [ ] Other, please describe:

**Does this PR introduce a breaking change?** (check one)

- [ ] Yes
- [x] No

If yes, please describe the impact and migration path for existing applications:

**The PR fulfills these requirements:**

- [x] It's submitted to the `dev` branch for v2.x (or to a previous version branch), _not_ the `master` branch
- [x] When resolving a specific issue, it's referenced in the PR's title (e.g. `fix #xxx[,#xxx]`, where "xxx" is the issue number)
- [x] All tests are passing: https://github.com/vuejs/vue/blob/dev/.github/CONTRIBUTING.md#development-setup
- [x] New/updated tests are included

If adding a **new feature**, the PR's description includes:
- [ ] A convincing reason for adding this feature (to avoid wasting your time, it's best to open a suggestion issue first and wait for approval before working on it)

**Other information:**


Changed files:
filename: src/core/instance/inject.js
patch: @@ -3,6 +3,7 @@
 import { warn } from '../util/index'
 import { hasSymbol } from 'core/util/env'
 import { defineReactive, observerState } from '../observer/index'
+import { hasOwn } from 'shared/util'
 
 export function initProvide (vm: Component) {
   const provide = vm.$options.provide
@@ -52,7 +53,7 @@ export function resolveInject (inject: any, vm: Component): ?Object {
       const provideKey = inject[key].from
       let source = vm
       while (source) {
-        if (source._provided && provideKey in source._provided) {
+        if (source._provided && hasOwn(source._provided, provideKey)) {
           result[key] = source._provided[provideKey]
           break
         }

filename: test/unit/features/options/inject.spec.js
patch: @@ -635,4 +635,16 @@ describe('Options provide/inject', () => {
 
     expect(injected).toEqual('foo')
   })
+
+  // #7284
+  it('should not inject prototype properties', () => {
+    const vm = new Vue({
+      provide: {}
+    })
+    new Vue({
+      parent: vm,
+      inject: ['constructor']
+    })
+    expect(`Injection "constructor" not found`).toHaveBeenWarned()
+  })
 })