Skip to content

Instantly share code, notes, and snippets.

@DavidBruant
Created January 8, 2012 15:15
Show Gist options
  • Save DavidBruant/1578659 to your computer and use it in GitHub Desktop.
Save DavidBruant/1578659 to your computer and use it in GitHub Desktop.
function getHiddenRecord(key) {
if (key !== Object(key)) {
throw new TypeError('Not an object: ' + key);
}
var hiddenRecord = key[HIDDEN_NAME];
if (hiddenRecord && hop.call(key, HIDDEN_NAME)) { return hiddenRecord; }
if (!originalProps.isExtensible(key)) {
// Weak map must brute force, as explained in doc-comment above.
return void 0;
}
var gets = [];
var vals = [];
/* __DAVID_BRUANT__
In case HIDDEN_NAME is compromised, this definition of hiddenRecord seems to
provide a lot of authority since gets and vals are mutable and iterable ECMAScript arrays.
It seems that only few opertions are used on these arrays (and thus needed)
It intuit with no proof that reducing the authority provided by access to hiddenRecord
make weakmap secure even if an attacker knows HIDDEN_NAME.
It seems that the two above arrays and how they are used are a "naiveWeakMap"
*/
hiddenRecord = {
gets: gets, // get___ methods identifying weak maps
vals: vals // values associated with this key in each
// corresponding weak map.
};
defProp(key, HIDDEN_NAME, {
value: hiddenRecord,
writable: false,
enumerable: false,
configurable: false
});
return hiddenRecord;
}
@erights
Copy link

erights commented Jan 8, 2012

if (hiddenRecord && hiddenRecord.key === key
/* DAVID_BRUANT
Why the "hiddenRecord.key === key" test?
Assuming HIDDEN_NAME is never discovered nor forged, the rules of creation of
hiddenRecord and how it's used internally already enforce key[HIDDEN_NAME].key === key
*/

If key does not have an own HIDDEN_NAME but inherits from an object that does, the conjunction will still be false.
If we drop the "=== key" conjunct, the test will be true and hilarity will ensue. That's why line 29 above reads

  key: key,   // self pointer for quick own check above.

By "above" there, I mean that "=== key" test.

@DavidBruant
Copy link
Author

I was editing the gist, so now it shows.
If instead of "var hiddenRecord = key[HIDDEN_NAME];" you have "var hiddenRecord = Object.getOwnPropertytDescriptor(key, HIDDEN_NAME).value;", then the test does not seems necessary

@DavidBruant
Copy link
Author

I've just updated the gist to show what I mean.
Some (a || b) trickeries in case the property is not defined.

@erights
Copy link

erights commented Jan 8, 2012

That works too. By why is it better? I haven't measured, by I expect it is typically slower due to the allocation and eventual collection of the fresh descriptor which is otherwise unused.

@DavidBruant
Copy link
Author

The other minor changes that came along was the removal of they "key" property in the hiddenRecord object. I would consider this to be an improvement.
Besides expressiveness, I can't say if it's better or not, especially not performance-wise.

If the deep reason of the hiddenRecord "key" property and the "hiddenRecord.key === key" test is the inheritance case, it may be as good to test "hop.call(key, HIDDEN_NAME);" (hop === Object.prototype.hasOwnProperty)
I don't know more about performance for this case, but the code would show more clearly the intent.

Changing the gist accordingly

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment