Skip to content

Commit

Permalink
Use defineProperty if user data happens to have __proto__
Browse files Browse the repository at this point in the history
  • Loading branch information
rlidwka committed Dec 11, 2020
1 parent adfee17 commit a003121
Show file tree
Hide file tree
Showing 3 changed files with 31 additions and 5 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- "duplicate mapping key" exception now points at the correct column, #452.
- Extra commas in flow collections (e.g. `[foo,,bar]`) now throw an exception
instead of producing null, #321.
- `__proto__` key no longer overrides object prototype, #164.
- Removed `bower.json`.


Expand Down
21 changes: 16 additions & 5 deletions lib/loader.js
Original file line number Diff line number Diff line change
Expand Up @@ -339,7 +339,18 @@ function storeMappingPair(state, _result, overridableKeys, keyTag, keyNode, valu
state.position = startPos || state.position;
throwError(state, 'duplicated mapping key');
}
_result[keyNode] = valueNode;

// used for this specific key only because Object.defineProperty is slow
if (keyNode === '__proto__') {
Object.defineProperty(_result, keyNode, {
configurable: true,
enumerable: true,
writable: true,
value: valueNode
});
} else {
_result[keyNode] = valueNode;
}
delete overridableKeys[keyNode];
}

Expand Down Expand Up @@ -683,7 +694,7 @@ function readFlowCollection(state, nodeIndent) {
isPair,
isExplicitPair,
isMapping,
overridableKeys = {},
overridableKeys = Object.create(null),
keyNode,
keyTag,
valueNode,
Expand Down Expand Up @@ -997,7 +1008,7 @@ function readBlockMapping(state, nodeIndent, flowIndent) {
_tag = state.tag,
_anchor = state.anchor,
_result = {},
overridableKeys = {},
overridableKeys = Object.create(null),
keyTag = null,
keyNode = null,
valueNode = null,
Expand Down Expand Up @@ -1476,8 +1487,8 @@ function readDocument(state) {

state.version = null;
state.checkLineBreaks = state.legacy;
state.tagMap = {};
state.anchorMap = {};
state.tagMap = Object.create(null);
state.anchorMap = Object.create(null);

while ((ch = state.input.charCodeAt(state.position)) !== 0) {
skipSeparationSpace(state, true, -1);
Expand Down
14 changes: 14 additions & 0 deletions test/issues/0164.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
'use strict';


const assert = require('assert');
const yaml = require('../../');


it('should define __proto__ as a value (not invoke setter)', function () {
let object = yaml.load('{ __proto__: {foo: bar} }');

assert.strictEqual(({}).hasOwnProperty.call(yaml.load('{}'), '__proto__'), false);
assert.strictEqual(({}).hasOwnProperty.call(object, '__proto__'), true);
assert(!object.foo);
});

0 comments on commit a003121

Please sign in to comment.