diff --git a/python/ql/lib/semmle/python/ApiGraphs.qll b/python/ql/lib/semmle/python/ApiGraphs.qll index 77574ab44ad..e8fc14d90fd 100644 --- a/python/ql/lib/semmle/python/ApiGraphs.qll +++ b/python/ql/lib/semmle/python/ApiGraphs.qll @@ -349,8 +349,8 @@ module API { result.getAnImmediateUse() = this } - /** Gets the number of arguments of this call. */ - int getNumArgument() { result = count(this.getArg(_)) } + /** Gets the number of arguments of this call. Both positional and named arguments are counted. */ + int getNumArgument() { result = count([this.getArg(_), this.getArgByName(_)]) } } /** diff --git a/python/ql/test/library-tests/frameworks/data/test.expected b/python/ql/test/library-tests/frameworks/data/test.expected index 721854dad37..8fb6efc0f95 100644 --- a/python/ql/test/library-tests/frameworks/data/test.expected +++ b/python/ql/test/library-tests/frameworks/data/test.expected @@ -46,6 +46,8 @@ isSink | test.py:85:8:85:53 | ControlFlowNode for Attribute() | test-sink | | test.py:86:8:86:60 | ControlFlowNode for Attribute() | test-sink | | test.py:87:8:87:67 | ControlFlowNode for Attribute() | test-sink | +| test.py:89:21:89:23 | ControlFlowNode for one | test-source | +| test.py:90:25:90:27 | ControlFlowNode for one | test-source | isSource | test.py:3:5:3:15 | ControlFlowNode for getSource() | test-source | | test.py:9:8:9:14 | ControlFlowNode for alias() | test-source | diff --git a/python/ql/test/library-tests/frameworks/data/test.py b/python/ql/test/library-tests/frameworks/data/test.py index db8e8c98e91..96f09c51598 100644 --- a/python/ql/test/library-tests/frameworks/data/test.py +++ b/python/ql/test/library-tests/frameworks/data/test.py @@ -84,4 +84,9 @@ mySink(Steps.preserveArgZeroAndTwo("foo", "bar", getSource())) # FLOW mySink(Steps.preserveAllButFirstArgument(getSource())) # NO FLOW mySink(Steps.preserveAllButFirstArgument("foo", getSource())) # FLOW -mySink(Steps.preserveAllButFirstArgument("foo", "bar", getSource())) # FLOW \ No newline at end of file +mySink(Steps.preserveAllButFirstArgument("foo", "bar", getSource())) # FLOW + +CallFilter.arityOne(one) # match +CallFilter.arityOne(one=one) # match +CallFilter.arityOne(one, two=two) # NO match +CallFilter.arityOne(one=one, two=two) # NO match diff --git a/python/ql/test/library-tests/frameworks/data/test.ql b/python/ql/test/library-tests/frameworks/data/test.ql index d694837b253..2558631cec6 100644 --- a/python/ql/test/library-tests/frameworks/data/test.ql +++ b/python/ql/test/library-tests/frameworks/data/test.ql @@ -41,7 +41,7 @@ class Sinks extends ModelInput::SinkModelCsv { "testlib;;Member[Args].Member[lastarg].Argument[N-1];test-source", // "testlib;;Member[Args].Member[nonFist].Argument[1..];test-source", // // callsite filter. - "testlib;;Member[CallFilter].Member[arityOne].WithArity[1].Argument[0..];test-source", // + "testlib;;Member[CallFilter].Member[arityOne].WithArity[1].Argument[any];test-source", // "testlib;;Member[CallFilter].Member[twoOrMore].WithArity[2..].Argument[0..];test-source", // // testing non-positional arguments "testlib;;Member[ArgPos].Member[selfThing].Argument[self];test-source", //