New issue
Advanced search Search tips
Note: Color blocks (like or ) mean that a user may not be available. Tooltip shows the reason.

Issue 638414 link

Starred by 1 user

Issue metadata

Status: WontFix
Owner:
Closed: Aug 2016
Cc:
Components:
EstimatedDays: ----
NextAction: ----
OS: Linux , Windows , Mac
Pri: 2
Type: Bug



Sign in to add a comment

Proxy handler.set reports incorrect keys and values for target array

Reported by sen...@allebrum.com, Aug 16 2016

Issue description

UserAgent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/51.0.2704.103 Safari/537.36

Steps to reproduce the problem:
1. Open Chrome and go to http://codepen.io/anon/pen/YWgNdY
2. Run and look at console.

Alternative
1. create a proxy of an empty array.
2. create a 'set' handler
3. in the set handler, modify an existing value of the target instead of the incoming property.

What is the expected behavior?
It is expected that the target object define the final value of the object.

In the example above, I expect that splice work based based on the target object. The final result should be: ['dude', 'bob', 'senica', 'test']

What went wrong?
The final result is ['yo', 'bob', 'senica', 'test'].

It seems that keys of the array are not updated (or updated in an untimely manner. Or perhaps, there is some internal pointer that is not being updated.

The current code is the closest I've been able to come to getting an accurate result. But it always goes awry.

The get handler is necessary, otherwise the array just fills up with undefined values if you try and modify an different value of the target array.

http://stackoverflow.com/questions/38982598/javascript-proxy-modify-array-target-and-update-array-length-content/38983212?noredirect=1#comment65320078_38983212

Did this work before? No 

Chrome version: 51.0.2704.103  Channel: n/a
OS Version: OS X 10.11.5
Flash Version: Shockwave Flash 22.0 r0

Same behavior in Firefox.
 
Cc: rnimmagadda@chromium.org
Components: Internals>Network>Proxy
Status: Untriaged (was: Unconfirmed)
Untriaging it since the same behavior is observed on Firefox too.

Could some one from "Proxy" team please look into this issue.

Thank you.


Labels: OS-Linux OS-Windows
Components: -Internals>Network>Proxy -Blink Blink>JavaScript
This is not related to network proxies, it's about the Javascript Proxy object.
Cc: littledan@chromium.org adamk@chromium.org
Components: -Blink>JavaScript Blink>JavaScript>Language
Adam/Dan Is this working as intended?

Comment 5 by adamk@chromium.org, Aug 18 2016

Owner: adamk@chromium.org
Status: WontFix (was: Untriaged)
This is just how Array.prototype.splice works. See https://tc39.github.io/ecma262/#sec-array.prototype.splice

In particular, see the loop at step 11 of the above-linked algorithm. When asked to delete, as in the call to `test.splice(0, 2)`, it first moves values down in the array, then reduces the length.

In the example, taking `test = ["what", "yo", "dude"]`, the first thing splice does is set test[0] to "dude". But the set handler sees that "dude" is already present at index 2, and so it remains there. The handler also (for some reason) does target.splice(0, 1), thus removing "what" and moving "yo" down one. Then test.length is reduced by splice, and we're left with an array of length 1 containing "yo".

All of which is to say, this isn't a bug.

Comment 6 by sen...@allebrum.com, Aug 18 2016

@adamk
I started typing a huge reply with various test cases, but in my bias for my own use-case I completely misunderstood how the set handler is called for various operations, and failed to fully appreciate what you were saying.

But, I realized my folly. To answer your semi-question of why the set handler called splice, here is a shortened example using just pushes and no splice: http://codepen.io/anon/pen/akxdKL As you can see, the final result is ["what", "hi", "yo", undefined, undefined]. The splices were to remove the undefined values.

In the first use-case, the idea is to create some data protection that checks for duplicate values. However, with no direct way to know what type of operation was called that caused the set handler to be invoked (push, splice, concat), it makes it quite difficult. Further, on a splice operation the deleteProperty handler gets called after the set handler (rightfully so) but too late to do any detection.

What I had failed to realize was that on a splice the set handler was being called for every value (to reset the key) behind the value(s) being removed.

Apologies for the bogus ticket.

Sign in to add a comment