Skip to content

Commit e09f7da

Browse files
benjieyaacovCR
andauthored
Use Object.create(null) over {} to avoid prototype issues (#4634)
Forward-port of #4631. From #4631 (on v16): > Object.create(null) is generally safer since it is not vulnerable to prototype pollution in user code. To avoid breaking changes I've returned { ...obj } thus ensuring that the returned object still has the default Object prototype. This PR on v17 skips that latter portion, i.e. on v17 this PR returns `obj` rather than `{ ...obj }`, a BREAKING CHANGE for v17 which minimizes the performance regression. --------- Co-authored-by: Yaacov Rydzinski <yaacovCR@gmail.com>
1 parent d7e040e commit e09f7da

File tree

2 files changed

+5
-4
lines changed

2 files changed

+5
-4
lines changed

src/execution/values.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -205,8 +205,8 @@ export function getArgumentValues(
205205
variableValues?: Maybe<VariableValues>,
206206
fragmentVariableValues?: Maybe<FragmentVariableValues>,
207207
hideSuggestions?: Maybe<boolean>,
208-
): { [argument: string]: unknown } {
209-
const coercedValues: { [argument: string]: unknown } = {};
208+
): ObjMap<unknown> {
209+
const coercedValues: ObjMap<unknown> = Object.create(null);
210210

211211
const argumentNodes = node.arguments ?? [];
212212
const argNodeMap = new Map(argumentNodes.map((arg) => [arg.name.value, arg]));

src/utilities/coerceInputValue.ts

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import { invariant } from '../jsutils/invariant.js';
22
import { isIterableObject } from '../jsutils/isIterableObject.js';
33
import { isObjectLike } from '../jsutils/isObjectLike.js';
44
import type { Maybe } from '../jsutils/Maybe.js';
5+
import type { ObjMap } from '../jsutils/ObjMap.js';
56

67
import type { ValueNode, VariableNode } from '../language/ast.js';
78
import { Kind } from '../language/kinds.js';
@@ -69,7 +70,7 @@ export function coerceInputValue(
6970
return; // Invalid: intentionally return no value.
7071
}
7172

72-
const coercedValue: any = {};
73+
const coercedValue: ObjMap<unknown> = Object.create(null);
7374
const fieldDefs = type.getFields();
7475
const hasUndefinedField = Object.keys(inputValue).some(
7576
(name) => !Object.hasOwn(fieldDefs, name),
@@ -211,7 +212,7 @@ export function coerceInputLiteral(
211212
return; // Invalid: intentionally return no value.
212213
}
213214

214-
const coercedValue: { [field: string]: unknown } = {};
215+
const coercedValue: ObjMap<unknown> = Object.create(null);
215216
const fieldDefs = type.getFields();
216217
const hasUndefinedField = valueNode.fields.some(
217218
(field) => !Object.hasOwn(fieldDefs, field.name.value),

0 commit comments

Comments
 (0)