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

Issue 835678 link

Starred by 4 users

Issue metadata

Status: Available
Owner: ----
Cc:
Components:
EstimatedDays: ----
NextAction: ----
OS: Linux , Windows , Chrome , Mac
Pri: 3
Type: Bug



Sign in to add a comment

chrome.storage should not be sorting object keys

Reported by thd...@gmail.com, Apr 22 2018

Issue description

UserAgent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/65.0.3325.181 Safari/537.36

Steps to reproduce the problem:
1. Store some dummy object (you can open any extension background page and enter this):

chrome.storage.local.set({
  'obj': {
    'k1': 'one',
    'k2': 'two',
    'k10': 'ten'
  }
});

2. Retrieve the data:

chrome.storage.local.get('obj', function(items) {
  for (var i in items['obj']) {
    console.log(i);
  }
});

What is the expected behavior?
It should output the keys in the order in which they were provided:

k1
k2
k10

What went wrong?
It outputs the keys in lexicographic order:

k1
k10
k2

Did this work before? N/A 

Does this work in other browsers? Yes

Chrome version: 65.0.3325.181  Channel: n/a
OS Version: 10.0
Flash Version: 

This is in regards to the chrome.storage API only, not Chromium, which correctly keeps the object string keys unsorted per the ES6 spec:

http://exploringjs.com/es6/ch_oop-besides-classes.html#_traversal-order-of-properties

> Retrieves the keys of all own properties of an object, in the following order:
> - First, the string keys that are integer indices (what these are is explained in
> the next section), in ascending numeric order.
> - Then all other string keys, **in the order in which they were added to the object**.
> - Lastly, all symbol keys, in the order in which they were added to the object.

If chrome.storage does not follow ES6 by design, then I guess this is not a bug but a feature request: please keep object string keys unsorted to be consistent with Chromium's JS engine.
 
Labels: Needs-Triage-M65

Comment 2 Deleted

Comment 3 by thd...@gmail.com, Apr 23 2018

@woxxom it is still confusing to me that when I traverse the same object in Chrome/Firefox I get a different order (unsorted). Are we to expect that because "the order in which for-in traverses properties is not defined" each API can have their own interpretation? My main point is that the behavior is inconsistent between Chrome and chrome.storage.
Cc: sindhu.chelamcherla@chromium.org
Components: Blink>Storage
Labels: Triaged-ET M-68 FoundIn-68 Target-68 OS-Linux OS-Mac
Status: Untriaged (was: Unconfirmed)
Able to reproduce this issue on reported version 65.0.3325.181, on latest stable 66.0.3359.117 , on latest canary 68.0.3404.0 using Windows 10, Ubuntu 14.04 and Mac 10.13.3.

This issue is seen from M-60. Hence considering this issue as Non-Regression and marking as Untriaged.

Thanks!
Components: -Blink>Storage Platform>Extensions>API Internals>Storage
Labels: -Hotlist-Interop

Comment 6 by jsb...@chromium.org, May 14 2018

Components: -Internals>Storage
Owner: rdevlin....@chromium.org
ECMAScript specification here is somewhat irrelevant. Serialization/deserialization is outside the bounds of what that covers.

In this case, I believe the serialization/deserialization is done by converting the JS value to a base::Value (src/base/values.h) and serializing/deserializing using that somehow (I stopped digging). A JS object is mapped to a base::DictionaryValue which doesn't preserve order.

Most web-facing APIs use the HTML-specified structured serialization (https://html.spec.whatwg.org/multipage/structured-data.html#safe-passing-of-structured-data) which is higher fidelity and does preserve ordering. 

I assume we don't want to invest heavily in this API, and would need to handle backwards compatibility/migration if we did make changes, but I defer to the extensions folks.
Cc: rdevlin....@chromium.org
Labels: -Pri-2 -M-68 -Target-68 OS-Chrome Pri-3
Owner: ----
Status: Available (was: Untriaged)
Yeah, this is because of the underlying implementation.  We do multiple base::Value conversions back-and-forth, which results in sorted keys.  Note that we specify any behavior regarding key order in the documentation for the chrome.storage API, so there are no strong guarantees here.

I'm not against having a defined structure here, and longer-term we do want to improve our storage capabilities for extensions for better support.  However, this probably isn't something we'll try and tackle in the near future.

I'm marking this as available, in case anyone wants to pursue it.  Note, though, that there be dragons: this is a long and convoluted code path, and trying to preserve order is likely very difficult.

Sign in to add a comment