Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion src/functions.js
Original file line number Diff line number Diff line change
Expand Up @@ -1698,7 +1698,7 @@ const functions = (() => {
}
}
}
} else if (input !== null && typeof input === 'object' && !isFunction(input)) {
} else if (input !== null && typeof input === 'object' && Object.prototype.hasOwnProperty.call(input, key) && !isFunction(input)) {
result = input[key];
}
return result;
Expand Down
8 changes: 0 additions & 8 deletions src/jsonata.js
Original file line number Diff line number Diff line change
Expand Up @@ -1293,13 +1293,6 @@ var jsonata = (function() {
}
for(var ii = 0; ii < matches.length; ii++) {
var match = matches[ii];
if (match && (match.isPrototypeOf(result) || match instanceof Object.constructor)) {
throw {
code: "D1010",
stack: (new Error()).stack,
position: expr.position
};
}
Comment thread
mattbaileyuk marked this conversation as resolved.
// evaluate the update value for each match
var update = await evaluate(expr.update, match, environment);
// update must be an object
Expand Down Expand Up @@ -1989,7 +1982,6 @@ var jsonata = (function() {
"T1007": "Attempted to partially apply a non-function. Did you mean ${{{token}}}?",
"T1008": "Attempted to partially apply a non-function",
"D1009": "Multiple key definitions evaluate to same key: {{value}}",
"D1010": "Attempted to access the Javascript object prototype", // Javascript specific
"T1010": "The matcher function argument passed to function {{token}} does not return the correct object structure",
"T2001": "The left side of the {{token}} operator must evaluate to a number",
"T2002": "The right side of the {{token}} operator must evaluate to a number",
Expand Down
42 changes: 27 additions & 15 deletions test/implementation-tests.js
Original file line number Diff line number Diff line change
Expand Up @@ -955,33 +955,45 @@ describe("Tests that are specific to a Javascript runtime", () => {
});
});
});
describe("Expressions that attempt to pollute the object prototype", function() {
it("should throw an error with __proto__", async function() {
const expr = jsonata('{} ~> | __proto__ | {"is_admin": true} |');

describe("Expressions that attempt to access the object prototype", function() {
const data = {"foo": {"bar": "baz"}};
it("should ignore __proto__", async function() {
const expr = jsonata('foo.__proto__');
const result = await expr.evaluate(data);
expect(result).to.deep.equal(undefined);
});

it("should throw an error trying to invoke toString()", async function() {
const expr = jsonata('foo.toString()');
expect(
expr.evaluate()
expr.evaluate(data)
).to.eventually.be.rejected.to.deep.contain({
position: 7,
code: "D1010",
position: 13,
code: "T1006",
});
});
});

describe("Expressions that attempt to pollute the object prototype", function() {
it("should ignore __proto__", async function() {
const expr = jsonata('{} ~> | __proto__ | {"is_admin": true} |');
const result = await expr.evaluate();
expect(result).to.deep.equal({});
});
it("should throw an error with __lookupGetter__", async function() {
const expr = jsonata('{} ~> | __lookupGetter__("__proto__")() | {"is_admin": true} |');
expect(
expr.evaluate()
).to.eventually.be.rejected.to.deep.contain({
position: 7,
code: "D1010",
position: 25,
code: "T1006",
});
});
it("should throw an error with constructor", async function() {
it("should ignore constructor", async function() {
const expr = jsonata('{} ~> | constructor | {"is_admin": true} |');
expect(
expr.evaluate()
).to.eventually.be.rejected.to.deep.contain({
position: 7,
code: "D1010",
});
const result = await expr.evaluate();
expect(result).to.deep.equal({});
});
});
});
Expand Down
Loading