[SERVER-78357] Object.entries does not return lazy properties that were not previously resolved for JS Object-BSON/BSONInfo Created: 22/Jun/23  Updated: 30/Jan/24  Resolved: 09/Jan/24

Status: Closed
Project: Core Server
Component/s: None
Affects Version/s: None
Fix Version/s: 7.3.0-rc0

Type: Bug Priority: Critical - P2
Reporter: George Wangensteen Assignee: Santiago Roche
Resolution: Fixed Votes: 3
Labels: greenerbuild
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified

Issue Links:
Problem/Incident
Related
related to SERVER-84525 Array.sort() is not a valid function ... Closed
related to SERVER-85927 Reduce fuzzer comparison result speed... Backlog
Assigned Teams:
Query Integration
Backwards Compatibility: Fully Compatible
Operating System: ALL
Steps To Reproduce:

 

 

(function()
{ "use strict"; db.bson_object_entries_bug.drop(); // We want some BSON objects for this test. One convenient way to get that is to insert them // into the database and then get them back through a query. const coll = db.bson_object_entries_bug;assert.commandWorked(coll.insert(\{a: 1, b: 2}
));
let res = coll.findOne();
assert.eq(["_id", "a", "b"], Object.keys(res))
// This is wrong! We should see [\{_id: ObjectId(...)}, \{a: 1}, \{b: 1}]
assert.eq([], Object.entries(res))
// We can still access the entries via normally property access, both with dots...
assert.eq(1, res.a);
//...and brackets
assert.eq(2, res["b"]);
// Once we've accessed the entries, they show up in the Object.entries output.
assert.eq([["a", 1], ["b", 2]], Object.entries(res))
}()); 

Participants:
Linked BF Score: 146

 Description   

Spidermonkey/mozjs has a concept of "lazy properties" for custom Javascript objects defined with JSAPI. When a property is not found in Javascript for some custom object, a hook (the "resolve" function) for that custom object is called to (possibly) load the property into the JS engine.  

The custom BSON JS object we provide to mozjs uses this feature to implement all of it's properties; each BSON element corresponds to a property of the JS object, but the properties are loaded into JS lazily as needed through calls to the "BSONInfo::resolve" function defined here . Similarly, the enumerable property keys (not values; just the names of the properties) are provided to the JS engine via the "BSONInfo::enumerate" function.

This works when properties are accessed on the objects in JS, and all of the keys are correctly visible in JS via Object.keys. However, the Object.entries function excludes the key/value pair for any property that wasn't already resolved into JS by previous property lookup. See the reproduction script for specifics.

The issue appears to be due to the fact that the mozjs implementation of the Object.entries is not calling the resolve function for unresolved properties. Reading the code, I couldn't figure out why, as it appears to be attempting to. It's unclear to me if it needs to, though, or if the enumerate function is required to previously have resolved all lazy properties into the engine. 

We need to figure out if enumerate should be doing this work + load the values into JS there if needed, or determine the root-cause of this issue if not. 

 

A workaround in the meanwhile is to simply to Object.assign to copy the BSON-object into an empty object before using Object.entries, which will resolve all lazy properties.  for..in can also be used instead of Object.entries as it forces property resolution correctly. 



 Comments   
Comment by Githook User [ 09/Jan/24 ]

Author:

{'name': 'Santiago Roche', 'email': 'santiago.roche@mongodb.com', 'username': ''}

Message: SERVER-78357: Resolve lazy properties in Object.entries().

GitOrigin-RevId: dfc2b86a23341b1bf5265a2f3d68e3c7f056f090
Branch: master
https://github.com/mongodb/mongo/commit/0fe1b867bf0a4e20a6f791301a893eebaa63370e

Comment by Phoebe Du [ 27/Jun/23 ]

Re-assigning to Query Integration team since Service Arch believes this fall under Query Integration's responsibility per team charter. 

cc brenda.rodriguez@mongodb.com 

Generated at Thu Feb 08 06:38:08 UTC 2024 using Jira 9.7.1#970001-sha1:2222b88b221c4928ef0de3161136cc90c8356a66.