@@ -460,10 +460,26 @@ private CallCfgNode getSuperCall() {
460460 )
461461}
462462
463+ /**
464+ * Holds if the file `f` should be ignored when computing the call-graph.
465+ *
466+ * We currently see a performance problem when analyzing the `sympy` PyPI package,
467+ * which can be part of the database when dependencies are installed and extracted.
468+ * From what we can understand, SymPy is using Python in a exotic way, so the fact that
469+ * our analysis currently does not handle this project has nothing to say about our
470+ * ability to handle normal Python code. Furthermore, SymPy does not look to be relevant
471+ * in a security context, so we should not loose out on any security results by doing
472+ * this.
473+ */
474+ private predicate ignoreForCallGraph ( File f ) {
475+ f .getAbsolutePath ( ) .matches ( "%/site-packages/sympy/%" )
476+ }
477+
463478/**
464479 * Gets a reference to the function `func`.
465480 */
466481private TypeTrackingNode functionTracker ( TypeTracker t , Function func ) {
482+ not ignoreForCallGraph ( result .getLocation ( ) .getFile ( ) ) and
467483 t .start ( ) and
468484 (
469485 result .asExpr ( ) = func .getDefinition ( )
@@ -473,6 +489,7 @@ private TypeTrackingNode functionTracker(TypeTracker t, Function func) {
473489 result .asExpr ( ) = func .getDefinition ( ) .( FunctionExpr ) .getADecoratorCall ( )
474490 )
475491 or
492+ not ignoreForCallGraph ( result .getLocation ( ) .getFile ( ) ) and
476493 exists ( TypeTracker t2 | result = functionTracker ( t2 , func ) .track ( t2 , t ) )
477494}
478495
@@ -485,6 +502,7 @@ Node functionTracker(Function func) { functionTracker(TypeTracker::end(), func).
485502 * Gets a reference to the class `cls`.
486503 */
487504private TypeTrackingNode classTracker ( TypeTracker t , Class cls ) {
505+ not ignoreForCallGraph ( result .getLocation ( ) .getFile ( ) ) and
488506 t .start ( ) and
489507 (
490508 result .asExpr ( ) = cls .getParent ( )
@@ -498,6 +516,7 @@ private TypeTrackingNode classTracker(TypeTracker t, Class cls) {
498516 result .( CallCfgNode ) .getArg ( 0 ) = classInstanceTracker ( cls )
499517 )
500518 or
519+ not ignoreForCallGraph ( result .getLocation ( ) .getFile ( ) ) and
501520 exists ( TypeTracker t2 | result = classTracker ( t2 , cls ) .track ( t2 , t ) ) and
502521 not result .( ParameterNodeImpl ) .isParameterOf ( _, any ( ParameterPosition pp | pp .isSelf ( ) ) )
503522}
@@ -511,16 +530,19 @@ Node classTracker(Class cls) { classTracker(TypeTracker::end(), cls).flowsTo(res
511530 * Gets a reference to an instance of the class `cls`.
512531 */
513532private TypeTrackingNode classInstanceTracker ( TypeTracker t , Class cls ) {
533+ not ignoreForCallGraph ( result .getLocation ( ) .getFile ( ) ) and
514534 t .start ( ) and
515535 resolveClassCall ( result .( CallCfgNode ) .asCfgNode ( ) , cls )
516536 or
517537 // result of `super().__new__` as used in a `__new__` method implementation
538+ not ignoreForCallGraph ( result .getLocation ( ) .getFile ( ) ) and
518539 t .start ( ) and
519540 exists ( Class classUsedInSuper |
520541 fromSuperNewCall ( result .( CallCfgNode ) .asCfgNode ( ) , classUsedInSuper , _, _) and
521542 classUsedInSuper = getADirectSuperclass * ( cls )
522543 )
523544 or
545+ not ignoreForCallGraph ( result .getLocation ( ) .getFile ( ) ) and
524546 exists ( TypeTracker t2 | result = classInstanceTracker ( t2 , cls ) .track ( t2 , t ) ) and
525547 not result .( ParameterNodeImpl ) .isParameterOf ( _, any ( ParameterPosition pp | pp .isSelf ( ) ) )
526548}
@@ -537,6 +559,7 @@ Node classInstanceTracker(Class cls) {
537559 * The method cannot be a `staticmethod` or `classmethod`.
538560 */
539561private TypeTrackingNode selfTracker ( TypeTracker t , Class classWithMethod ) {
562+ not ignoreForCallGraph ( result .getLocation ( ) .getFile ( ) ) and
540563 t .start ( ) and
541564 exists ( Function func |
542565 func = classWithMethod .getAMethod ( ) and
@@ -546,6 +569,7 @@ private TypeTrackingNode selfTracker(TypeTracker t, Class classWithMethod) {
546569 result .asExpr ( ) = func .getArg ( 0 )
547570 )
548571 or
572+ not ignoreForCallGraph ( result .getLocation ( ) .getFile ( ) ) and
549573 exists ( TypeTracker t2 | result = selfTracker ( t2 , classWithMethod ) .track ( t2 , t ) ) and
550574 not result .( ParameterNodeImpl ) .isParameterOf ( _, any ( ParameterPosition pp | pp .isSelf ( ) ) )
551575}
@@ -564,6 +588,7 @@ Node selfTracker(Class classWithMethod) {
564588 * from a normal method.
565589 */
566590private TypeTrackingNode clsArgumentTracker ( TypeTracker t , Class classWithMethod ) {
591+ not ignoreForCallGraph ( result .getLocation ( ) .getFile ( ) ) and
567592 t .start ( ) and
568593 (
569594 exists ( Function func |
@@ -578,6 +603,7 @@ private TypeTrackingNode clsArgumentTracker(TypeTracker t, Class classWithMethod
578603 result .( CallCfgNode ) .getArg ( 0 ) = selfTracker ( classWithMethod )
579604 )
580605 or
606+ not ignoreForCallGraph ( result .getLocation ( ) .getFile ( ) ) and
581607 exists ( TypeTracker t2 | result = clsArgumentTracker ( t2 , classWithMethod ) .track ( t2 , t ) ) and
582608 not result .( ParameterNodeImpl ) .isParameterOf ( _, any ( ParameterPosition pp | pp .isSelf ( ) ) )
583609}
@@ -596,6 +622,7 @@ Node clsArgumentTracker(Class classWithMethod) {
596622 * call happened in the method `func` (either a method or a classmethod).
597623 */
598624private TypeTrackingNode superCallNoArgumentTracker ( TypeTracker t , Function func ) {
625+ not ignoreForCallGraph ( result .getLocation ( ) .getFile ( ) ) and
599626 t .start ( ) and
600627 not isStaticmethod ( func ) and
601628 exists ( CallCfgNode call | result = call |
@@ -604,6 +631,7 @@ private TypeTrackingNode superCallNoArgumentTracker(TypeTracker t, Function func
604631 call .getScope ( ) = func
605632 )
606633 or
634+ not ignoreForCallGraph ( result .getLocation ( ) .getFile ( ) ) and
607635 exists ( TypeTracker t2 | result = superCallNoArgumentTracker ( t2 , func ) .track ( t2 , t ) ) and
608636 not result .( ParameterNodeImpl ) .isParameterOf ( _, any ( ParameterPosition pp | pp .isSelf ( ) ) )
609637}
@@ -621,13 +649,15 @@ Node superCallNoArgumentTracker(Function func) {
621649 * first is a reference to the class `cls`, and the second argument is `obj`.
622650 */
623651private TypeTrackingNode superCallTwoArgumentTracker ( TypeTracker t , Class cls , Node obj ) {
652+ not ignoreForCallGraph ( result .getLocation ( ) .getFile ( ) ) and
624653 t .start ( ) and
625654 exists ( CallCfgNode call | result = call |
626655 call = getSuperCall ( ) and
627656 call .getArg ( 0 ) = classTracker ( cls ) and
628657 call .getArg ( 1 ) = obj
629658 )
630659 or
660+ not ignoreForCallGraph ( result .getLocation ( ) .getFile ( ) ) and
631661 exists ( TypeTracker t2 | result = superCallTwoArgumentTracker ( t2 , cls , obj ) .track ( t2 , t ) ) and
632662 not result .( ParameterNodeImpl ) .isParameterOf ( _, any ( ParameterPosition pp | pp .isSelf ( ) ) )
633663}
0 commit comments