Skip to content

Commit 7150f9f

Browse files
cristunaranjoyaacovCR
authored andcommitted
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 e347d87 commit 7150f9f

File tree

2 files changed

+78
-1
lines changed

2 files changed

+78
-1
lines changed

src/execution/__tests__/executor-test.ts

Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import { Kind } from '../../language/kinds.js';
1010
import { parse } from '../../language/parser.js';
1111

1212
import {
13+
GraphQLInputObjectType,
1314
GraphQLInterfaceType,
1415
GraphQLList,
1516
GraphQLNonNull,
@@ -1380,4 +1381,74 @@ describe('Execute: Handles basic execution tasks', () => {
13801381
expect(result).to.deep.equal({ data: { foo: { bar: 'bar' } } });
13811382
expect(possibleTypes).to.deep.equal([fooObject]);
13821383
});
1384+
1385+
it('uses a different number of max coercion errors', () => {
1386+
const schema = new GraphQLSchema({
1387+
query: new GraphQLObjectType({
1388+
name: 'Query',
1389+
fields: {
1390+
dummy: { type: GraphQLString },
1391+
},
1392+
}),
1393+
mutation: new GraphQLObjectType({
1394+
name: 'Mutation',
1395+
fields: {
1396+
updateUser: {
1397+
type: GraphQLString,
1398+
args: {
1399+
data: {
1400+
type: new GraphQLInputObjectType({
1401+
name: 'User',
1402+
fields: {
1403+
email: { type: new GraphQLNonNull(GraphQLString) },
1404+
},
1405+
}),
1406+
},
1407+
},
1408+
},
1409+
},
1410+
}),
1411+
});
1412+
1413+
const document = parse(`
1414+
mutation ($data: User) {
1415+
updateUser(data: $data)
1416+
}
1417+
`);
1418+
1419+
const options = {
1420+
maxCoercionErrors: 1,
1421+
};
1422+
1423+
const result = executeSync({
1424+
schema,
1425+
document,
1426+
variableValues: {
1427+
data: {
1428+
email: '',
1429+
wrongArg: 'wrong',
1430+
wrongArg2: 'wrong',
1431+
wrongArg3: 'wrong',
1432+
},
1433+
},
1434+
options,
1435+
});
1436+
1437+
// Returns at least 2 errors, one for the first 'wrongArg', and one for coercion limit
1438+
expect(result.errors).to.have.lengthOf(options.maxCoercionErrors + 1);
1439+
1440+
expectJSON(result).toDeepEqual({
1441+
errors: [
1442+
{
1443+
message:
1444+
'Variable "$data" has invalid value: Expected value of type "User" not to include unknown field "wrongArg", found: { email: "", wrongArg: "wrong", wrongArg2: "wrong", wrongArg3: "wrong" }.',
1445+
locations: [{ line: 2, column: 17 }],
1446+
},
1447+
{
1448+
message:
1449+
'Too many errors processing variables, error limit reached. Execution aborted.',
1450+
},
1451+
],
1452+
});
1453+
});
13831454
});

src/execution/execute.ts

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -199,6 +199,11 @@ export interface ExecutionArgs {
199199
enableEarlyExecution?: Maybe<boolean>;
200200
hideSuggestions?: Maybe<boolean>;
201201
abortSignal?: Maybe<AbortSignal>;
202+
/** Additional execution options. */
203+
options?: {
204+
/** Set the maximum number of errors allowed for coercing (defaults to 50). */
205+
maxCoercionErrors?: number;
206+
};
202207
}
203208

204209
export interface StreamUsage {
@@ -472,6 +477,7 @@ export function validateExecutionArgs(
472477
perEventExecutor,
473478
enableEarlyExecution,
474479
abortSignal,
480+
options,
475481
} = args;
476482

477483
if (abortSignal?.aborted) {
@@ -534,7 +540,7 @@ export function validateExecutionArgs(
534540
variableDefinitions,
535541
rawVariableValues ?? {},
536542
{
537-
maxErrors: 50,
543+
maxErrors: options?.maxCoercionErrors ?? 50,
538544
hideSuggestions,
539545
},
540546
);

0 commit comments

Comments
 (0)