diff --git a/python/ql/lib/semmle/python/frameworks/data/internal/ApiGraphModelsSpecific.qll b/python/ql/lib/semmle/python/frameworks/data/internal/ApiGraphModelsSpecific.qll index 113bcc71314..d2de1f21724 100644 --- a/python/ql/lib/semmle/python/frameworks/data/internal/ApiGraphModelsSpecific.qll +++ b/python/ql/lib/semmle/python/frameworks/data/internal/ApiGraphModelsSpecific.qll @@ -60,6 +60,9 @@ API::Node getExtraSuccessorFromNode(API::Node node, AccessPathToken token) { or token.getName() = "Subclass" and result = node.getASubclass*() + or + token.getName() = "Method" and + result = node.getMember(token.getAnArgument()).getReturn() // Some features don't have MaD tokens yet, they would need to be added to API-graphs first. // - decorators ("DecoratedClass", "DecoratedMember", "DecoratedParameter") // - Array/Map elements ("ArrayElement", "Element", "MapKey", "MapValue") @@ -164,7 +167,7 @@ predicate isExtraValidNoArgumentTokenInIdentifyingAccessPath(string name) { */ bindingset[name, argument] predicate isExtraValidTokenArgumentInIdentifyingAccessPath(string name, string argument) { - name = ["Member"] and + name = ["Member", "Method"] and exists(argument) or name = ["Argument", "Parameter"] and diff --git a/python/ql/test/library-tests/frameworks/data/test.expected b/python/ql/test/library-tests/frameworks/data/test.expected index 93697631fb3..72600cd8be5 100644 --- a/python/ql/test/library-tests/frameworks/data/test.expected +++ b/python/ql/test/library-tests/frameworks/data/test.expected @@ -42,6 +42,7 @@ isSource | test.py:41:8:41:27 | ControlFlowNode for Attribute() | test-source | | test.py:46:7:46:16 | ControlFlowNode for SubClass() | test-source | | test.py:51:8:51:18 | ControlFlowNode for Sub2Class() | test-source | +| test.py:53:7:53:16 | ControlFlowNode for Attribute() | test-source | syntaxErrors | Member[foo | | Member[foo] .Member[bar] | diff --git a/python/ql/test/library-tests/frameworks/data/test.py b/python/ql/test/library-tests/frameworks/data/test.py index aa0c9f2a6fc..c53b6c55fbe 100644 --- a/python/ql/test/library-tests/frameworks/data/test.py +++ b/python/ql/test/library-tests/frameworks/data/test.py @@ -48,4 +48,6 @@ sub = SubClass() class Sub2Class (CommonTokens.Class): pass -sub2 = Sub2Class() \ No newline at end of file +sub2 = Sub2Class() + +val = inst.foo() \ No newline at end of file diff --git a/python/ql/test/library-tests/frameworks/data/test.ql b/python/ql/test/library-tests/frameworks/data/test.ql index bb19389bf9d..43549a36d8e 100644 --- a/python/ql/test/library-tests/frameworks/data/test.ql +++ b/python/ql/test/library-tests/frameworks/data/test.ql @@ -57,7 +57,6 @@ class Sinks extends ModelInput::SinkModelCsv { // TODO: Non-positional arguments (including Named parameters) // TODO: Any argument // TODO: Test taint steps. -// TODO: Should `instance()` be shorthand for `subClass*().getReturn()`? // TODO: // There are no API-graph edges for: ArrayElement, Element, MapKey, MapValue (remove from valid tokens list) class Sources extends ModelInput::SourceModelCsv { // package;type;path;kind @@ -74,6 +73,8 @@ class Sources extends ModelInput::SourceModelCsv { "testlib;;Member[CommonTokens].Member[makePromise].ReturnValue.Awaited;test-source", // "testlib;;Member[CommonTokens].Member[Class].Instance;test-source", // "testlib;;Member[CommonTokens].Member[Super].Subclass.Instance;test-source", // + // method + "testlib;;Member[CommonTokens].Member[Class].Instance.Method[foo];test-source", // ] } } diff --git a/python/ql/test/library-tests/frameworks/data/warnings.expected b/python/ql/test/library-tests/frameworks/data/warnings.expected index b8242f31a85..5cebb548358 100644 --- a/python/ql/test/library-tests/frameworks/data/warnings.expected +++ b/python/ql/test/library-tests/frameworks/data/warnings.expected @@ -2,11 +2,6 @@ | CSV type row should have 5 columns but has 8: test;TooManyColumns;;;Member[Foo].Instance;too;many;columns | | Invalid argument '0-1' in token 'Argument[0-1]' in access path: Method[foo].Argument[0-1] | | Invalid argument '*' in token 'Argument[*]' in access path: Method[foo].Argument[*] | -| Invalid argument 'foo' in token 'Method[foo]' in access path: Method[foo].Arg[0] | -| Invalid argument 'foo' in token 'Method[foo]' in access path: Method[foo].Argument | -| Invalid argument 'foo' in token 'Method[foo]' in access path: Method[foo].Argument[0-1] | -| Invalid argument 'foo' in token 'Method[foo]' in access path: Method[foo].Argument[*] | -| Invalid argument 'foo' in token 'Method[foo]' in access path: Method[foo].Member | | Invalid token 'Argument' is missing its arguments, in access path: Method[foo].Argument | | Invalid token 'Member' is missing its arguments, in access path: Method[foo].Member | | Invalid token name 'Arg' in access path: Method[foo].Arg[0] |