@@ -262,8 +262,13 @@ class GraphqlFieldDefinitionMethodCall extends GraphqlSchemaObjectClassMethodCal
262
262
/**
263
263
* Gets an argument call inside this field definition.
264
264
*/
265
- GraphqlFieldArgumentDefinitionMethodCall getAnArgumentCall ( ) {
266
- result .getEnclosingCallable ( ) = this .getBlock ( )
265
+ GraphqlFieldArgumentDefinitionMethodCall getAnArgumentCall ( ) { result = this .getArgumentCall ( _) }
266
+
267
+ /**
268
+ * Gets the argument call for `name` inside this field definition.
269
+ */
270
+ GraphqlFieldArgumentDefinitionMethodCall getArgumentCall ( string name ) {
271
+ result .getEnclosingCallable ( ) = this .getBlock ( ) and result .getArgumentName ( ) = name
267
272
}
268
273
}
269
274
@@ -277,7 +282,7 @@ class GraphqlInputObjectArgumentDefinitionCall extends DataFlow::CallNode {
277
282
.getMember ( "InputObject" )
278
283
.getADescendentModule ( )
279
284
.getAnOwnModuleSelf ( )
280
- .getAMethodCall ( )
285
+ .getAMethodCall ( "argument" )
281
286
}
282
287
283
288
/** Gets the name of the argument (i.e. the first argument to this `argument` method call) */
@@ -443,13 +448,16 @@ class GraphqlFieldResolutionMethod extends Method, Http::Server::RequestHandler:
443
448
444
449
/** Gets the method call which is the definition of the field corresponding to this resolver method. */
445
450
GraphqlFieldDefinitionMethodCall getDefinition ( ) {
446
- result
447
- .getKeywordArgument ( "resolver_method" )
448
- .getConstantValue ( )
449
- .isStringlikeValue ( this .getName ( ) )
450
- or
451
- not exists ( result .getKeywordArgument ( "resolver_method" ) .( SymbolLiteral ) ) and
452
- result .getFieldName ( ) = this .getName ( )
451
+ result .getEnclosingModule ( ) = this .getEnclosingModule ( ) and
452
+ (
453
+ result
454
+ .getKeywordArgument ( "resolver_method" )
455
+ .getConstantValue ( )
456
+ .isStringlikeValue ( this .getName ( ) )
457
+ or
458
+ not exists ( result .getKeywordArgument ( "resolver_method" ) .( SymbolLiteral ) ) and
459
+ result .getFieldName ( ) = this .getName ( )
460
+ )
453
461
}
454
462
455
463
// check for a named argument the same name as a defined argument for this field
@@ -471,42 +479,78 @@ class GraphqlFieldResolutionMethod extends Method, Http::Server::RequestHandler:
471
479
GraphqlSchemaObjectClass getGraphqlClass ( ) { result = schemaObjectClass }
472
480
}
473
481
474
- private DataFlow:: CallNode hashAccess ( DataFlow:: Node recv , string key ) {
475
- result .asExpr ( ) instanceof ExprNodes:: ElementReferenceCfgNode and
476
- result .getArgument ( 0 ) .getConstantValue ( ) .isStringlikeValue ( key ) and
477
- result .getReceiver ( ) = recv
478
- }
479
-
480
- private DataFlow:: CallNode parameterAccess (
482
+ private DataFlow:: CallNode hashParameterAccess (
481
483
GraphqlFieldResolutionMethod method , HashSplatParameter param , GraphqlType type
482
484
) {
483
- exists ( GraphqlFieldArgumentDefinitionMethodCall def , string key |
485
+ exists (
486
+ DataFlow:: LocalSourceNode paramNode , GraphqlFieldArgumentDefinitionMethodCall def , string key
487
+ |
484
488
param = method .getAParameter ( ) and
489
+ paramNode .( DataFlow:: ParameterNode ) .getParameter ( ) = param and
485
490
def = method .getDefinition ( ) .getAnArgumentCall ( ) and
486
491
(
487
492
// Direct access to the params hash
488
493
[ def .getArgumentType ( ) , def .getArgumentElementType ( ) ] = type and
489
494
def .getArgumentName ( ) = key and
490
- exists ( DataFlow:: Node paramRead |
491
- paramRead .asExpr ( ) .getExpr ( ) = param .getVariable ( ) .getAnAccess ( ) .( VariableReadAccess ) and
492
- result = hashAccess ( paramRead , key )
493
- )
495
+ paramNode .flowsTo ( hashAccess ( result , key ) )
494
496
or
495
497
// Nested access
496
498
exists ( GraphqlType type2 |
497
- parameterAccess ( method , param , type2 )
499
+ hashParameterAccess ( method , param , type2 )
498
500
.( DataFlow:: LocalSourceNode )
499
- .flowsTo ( result .getReceiver ( ) ) and
500
- result = hashAccess ( _, key ) and
501
+ .flowsTo ( hashAccess ( result , key ) ) and
501
502
type2 .getFieldOrArgument ( key ) = type
502
503
)
503
504
)
504
505
)
505
506
}
506
507
508
+ private DataFlow:: Node parameterAccess (
509
+ GraphqlFieldResolutionMethod method , DataFlow:: LocalSourceNode param , GraphqlType type
510
+ ) {
511
+ param = getAGraphqlParameter ( method , type ) and
512
+ result = param
513
+ or
514
+ exists ( string key , GraphqlType type2 |
515
+ param = parameterAccess ( method , _, type2 ) and
516
+ param .flowsTo ( hashAccess ( result , key ) ) and
517
+ type2 .getFieldOrArgument ( key ) = type
518
+ )
519
+ }
520
+
521
+ private DataFlow:: ParameterNode getAGraphqlParameter (
522
+ GraphqlFieldResolutionMethod method , GraphqlType type
523
+ ) {
524
+ result .getCallable ( ) = method and
525
+ (
526
+ result .getParameter ( ) instanceof KeywordParameter and
527
+ exists ( GraphqlFieldArgumentDefinitionMethodCall c |
528
+ c = method .getDefinition ( ) .getArgumentCall ( result .getName ( ) )
529
+ |
530
+ type = [ c .getArgumentType ( ) , c .getArgumentElementType ( ) ]
531
+ )
532
+ or
533
+ result .getParameter ( ) instanceof SimpleParameter and
534
+ type = method .getDefinition ( ) .getFieldType ( )
535
+ )
536
+ }
537
+
538
+ /**
539
+ * Gets the receiver of the hash access `access` with key `key`.
540
+ * For example, in `h["foo"]` the receiver is `h`, the key is "foo"
541
+ * and `access` is the dataflow node for the whole expression.
542
+ */
543
+ private DataFlow:: Node hashAccess ( DataFlow:: CallNode access , string key ) {
544
+ access .asExpr ( ) instanceof ExprNodes:: ElementReferenceCfgNode and
545
+ access .getArgument ( 0 ) .getConstantValue ( ) .isStringlikeValue ( key ) and
546
+ access .getReceiver ( ) = result
547
+ }
548
+
507
549
private class GraphqlParameterAccess extends RemoteFlowSource:: Range {
508
550
GraphqlParameterAccess ( ) {
509
- exists ( GraphqlType type | this = parameterAccess ( _, _, type ) and type .isScalar ( ) )
551
+ exists ( GraphqlType type | type .isScalar ( ) |
552
+ this = hashParameterAccess ( _, _, type ) or this = parameterAccess ( _, _, type )
553
+ )
510
554
}
511
555
512
556
override string getSourceType ( ) { result = "GraphQL" }
0 commit comments