Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

update try catch when set target.__proto__ (fix #9329) #10117

Open
wants to merge 1 commit into
base: dev
Choose a base branch
from

Conversation

daydream-like
Copy link

@daydream-like daydream-like commented Jun 7, 2019

What kind of change does this PR introduce? (check at least one)

  • Bugfix
  • Feature
  • Code style update
  • Refactor
  • Build-related changes
  • Other, please describe:

Does this PR introduce a breaking change? (check one)

  • Yes
  • No

If yes, please describe the impact and migration path for existing applications:

when we use mobx,when the Proxy property is array,set proto return false,then put the Proxy Object to vue data, the vue application will be crashed!

The PR fulfills these requirements:

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:
error
"TypeError: 'set' on proxy: trap returned falsish for property 'proto'"

my code

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
    <script src="https://unpkg.com/mobx/lib/mobx.umd.js"></script>
    <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
</head>

<body>
    <div id="app">
        <h1>{{name}}</h1>
        <h1>{{age}}</h1>
        <ul v-for="role in role">
            {{role.title}}
            {{role.name}}
        </ul>
    </div>
    <script>
        const data = mobx.observable({
            name: 'like',
            age: 1,
            role: [{
                title: 'student',
                name: "111"
            }, {
                title: 'student2',
                name: "222"
            }]
        })
        var app = new Vue({
            el: '#app',
            data:data
        })

    </script>

</body>

</html>

vue code

 /**
   * Augment a target Object or Array by intercepting
   * the prototype chain using __proto__
   */
  function protoAugment (target, src) {
    /* eslint-disable no-proto */
    target.__proto__ = src;
    /* eslint-enable no-proto */
  }

mobx code

set: function (target, name, value) {
            if (name === "length") {
                target[$mobx].setArrayLength(value);
                return true;
            }
            if (typeof name === "number") {
                arrayExtensions.set.call(target, name, value);
                return true;
            }
            if (!isNaN(name)) {
                arrayExtensions.set.call(target, parseInt(name), value);
                return true;
            }
            return false;
        },

when mobx check the name is ' proto', will return false to protect other code to modify it!
but vue modify it --> target.proto = src;

@posva
Copy link
Member

posva commented Jun 7, 2019

Ah, now I get what you are trying to fix, it's #9329

It wasn't clear at all without any description and no reference to the original issue

I still don't know if the fix should be in mobx side or here

@daydream-like
Copy link
Author

@posva Thank you for your fast reply , it's my description

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
    <script src="https://unpkg.com/mobx/lib/mobx.umd.js"></script>
    <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
</head>

<body>
    <div id="app">
        <h1>{{name}}</h1>
        <h1>{{age}}</h1>
        <ul v-for="role in role">
            {{role.title}}
            {{role.name}}
        </ul>
    </div>
    <script>
        const data = mobx.observable({
            name: 'like',
            age: 1,
            role: [{
                title: 'student',
                name: "111"
            }, {
                title: 'student2',
                name: "222"
            }]
        })
        var app = new Vue({
            el: '#app',
            data:data
        })

    </script>

</body>

</html>

error

Uncaught TypeError: 'set' on proxy: trap returned falsish for property '__proto__'

vue code

 /**
   * Augment a target Object or Array by intercepting
   * the prototype chain using __proto__
   */
  function protoAugment (target, src) {
    /* eslint-disable no-proto */
    target.__proto__ = src;
    /* eslint-enable no-proto */
  }

mobx code

  var arrayTraps = {
        get: function (target, name) {
            if (name === $mobx)
                return target[$mobx];
            if (name === "length")
                return target[$mobx].getArrayLength();
            if (typeof name === "number") {
                return arrayExtensions.get.call(target, name);
            }
            if (typeof name === "string" && !isNaN(name)) {
                return arrayExtensions.get.call(target, parseInt(name));
            }
            if (arrayExtensions.hasOwnProperty(name)) {
                return arrayExtensions[name];
            }
            return target[name];
        },
        set: function (target, name, value) {
            if (name === "length") {
                target[$mobx].setArrayLength(value);
                return true;
            }
            if (typeof name === "number") {
                arrayExtensions.set.call(target, name, value);
                return true;
            }
            if (!isNaN(name)) {
                arrayExtensions.set.call(target, parseInt(name), value);
                return true;
            }
            return false;
        },
        preventExtensions: function (target) {
            fail("Observable arrays cannot be frozen");
            return false;
        }
    };

@daydream-like daydream-like changed the title fix:when users use mobx and vue , Proxy property is array ,the mobx not allowed modify __proto__,put it to vue data ,then app will be crashed! update try catch when set target.__proto__ (fix #3899) Jun 8, 2019
@daydream-like daydream-like changed the title update try catch when set target.__proto__ (fix #3899) update try catch when set target.__proto__ (fix #9329) Jun 8, 2019
@daydream-like
Copy link
Author

@posva thanks for you replay, and now what should i do ?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants