Skip to content

Commit 50cbe4a

Browse files
feat(execution): add max coercion errors option to execution context (#4366)
This PR add `executionOptions` property to the `ExecutionArgs`. Currently only one option can be configured, as is the one I need, but I have built an object so it can easily be extended in the future. The property allows the configuration of the maximum number of errors (`maxErrors`) for coercion. This allows the current hardcoded limit (`50`) to be reduced to a small number to avoid possible DoS attacks. > Also, it updates the execution docs to reflect this new change. I think the documentation was outdated since functions were using positional arguments and now they only accept an object. No longer updates the docs.
1 parent 5adeb7f commit 50cbe4a

File tree

2 files changed

+78
-1
lines changed

2 files changed

+78
-1
lines changed

src/execution/__tests__/executor-test.ts

+71
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import { Kind } from '../../language/kinds';
1111
import { parse } from '../../language/parser';
1212

1313
import {
14+
GraphQLInputObjectType,
1415
GraphQLInterfaceType,
1516
GraphQLList,
1617
GraphQLNonNull,
@@ -1320,4 +1321,74 @@ describe('Execute: Handles basic execution tasks', () => {
13201321
expect(result).to.deep.equal({ data: { foo: { bar: 'bar' } } });
13211322
expect(possibleTypes).to.deep.equal([fooObject]);
13221323
});
1324+
1325+
it('uses a different number of max coercion errors', () => {
1326+
const schema = new GraphQLSchema({
1327+
query: new GraphQLObjectType({
1328+
name: 'Query',
1329+
fields: {
1330+
dummy: { type: GraphQLString },
1331+
},
1332+
}),
1333+
mutation: new GraphQLObjectType({
1334+
name: 'Mutation',
1335+
fields: {
1336+
updateUser: {
1337+
type: GraphQLString,
1338+
args: {
1339+
data: {
1340+
type: new GraphQLInputObjectType({
1341+
name: 'User',
1342+
fields: {
1343+
email: { type: new GraphQLNonNull(GraphQLString) },
1344+
},
1345+
}),
1346+
},
1347+
},
1348+
},
1349+
},
1350+
}),
1351+
});
1352+
1353+
const document = parse(`
1354+
mutation ($data: User) {
1355+
updateUser(data: $data)
1356+
}
1357+
`);
1358+
1359+
const options = {
1360+
maxCoercionErrors: 1,
1361+
};
1362+
1363+
const result = executeSync({
1364+
schema,
1365+
document,
1366+
variableValues: {
1367+
data: {
1368+
email: '',
1369+
wrongArg: 'wrong',
1370+
wrongArg2: 'wrong',
1371+
wrongArg3: 'wrong',
1372+
},
1373+
},
1374+
options,
1375+
});
1376+
1377+
// Returns at least 2 errors, one for the first 'wrongArg', and one for coercion limit
1378+
expect(result.errors).to.have.lengthOf(options.maxCoercionErrors + 1);
1379+
1380+
expectJSON(result).toDeepEqual({
1381+
errors: [
1382+
{
1383+
message:
1384+
'Variable "$data" got invalid value { email: "", wrongArg: "wrong", wrongArg2: "wrong", wrongArg3: "wrong" }; Field "wrongArg" is not defined by type "User".',
1385+
locations: [{ line: 2, column: 17 }],
1386+
},
1387+
{
1388+
message:
1389+
'Too many errors processing variables, error limit reached. Execution aborted.',
1390+
},
1391+
],
1392+
});
1393+
});
13231394
});

src/execution/execute.ts

+7-1
Original file line numberDiff line numberDiff line change
@@ -152,6 +152,11 @@ export interface ExecutionArgs {
152152
fieldResolver?: Maybe<GraphQLFieldResolver<any, any>>;
153153
typeResolver?: Maybe<GraphQLTypeResolver<any, any>>;
154154
subscribeFieldResolver?: Maybe<GraphQLFieldResolver<any, any>>;
155+
/** Additional execution options. */
156+
options?: {
157+
/** Set the maximum number of errors allowed for coercing (defaults to 50). */
158+
maxCoercionErrors?: number;
159+
};
155160
}
156161

157162
/**
@@ -286,6 +291,7 @@ export function buildExecutionContext(
286291
fieldResolver,
287292
typeResolver,
288293
subscribeFieldResolver,
294+
options,
289295
} = args;
290296

291297
let operation: OperationDefinitionNode | undefined;
@@ -329,7 +335,7 @@ export function buildExecutionContext(
329335
schema,
330336
variableDefinitions,
331337
rawVariableValues ?? {},
332-
{ maxErrors: 50 },
338+
{ maxErrors: options?.maxCoercionErrors ?? 50 },
333339
);
334340

335341
if (coercedVariableValues.errors) {

0 commit comments

Comments
 (0)