Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Python: Add models for builtins map, filter, zip, and enumerate. #18301

Open
wants to merge 6 commits into
base: main
Choose a base branch
from
Open
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
Add tests for zip and enumerate
  • Loading branch information
joefarebrother committed Jan 15, 2025
commit 6a6585e415c05e6869e16d6167192cae9c511b55
119 changes: 108 additions & 11 deletions python/ql/test/library-tests/dataflow/coverage/test_builtins.py
Original file line number Diff line number Diff line change
Expand Up @@ -430,22 +430,21 @@ def f(p1,p2):
SINK(rl[0][0]) #$ MISSING: flow="SOURCE, l:-10 -> rl[0][0]"
SINK_F(rl[0][1])

@expects(6)
@expects(4)
def test_map_multi_list():
l1 = [SOURCE]
l2 = [SOURCE]

def f(p1,p2):
SINK(p1) #$ flow="SOURCE, l:-4 -> p1"
SINK(p2) #$ flow="SOURCE, l:-4 -> p2"

return p1,p2

rl = list(map(f, l1, l2))
SINK(rl[0][0]) #$ flow="SOURCE, l:-10 -> rl[0][0]"
SINK(rl[0][1]) #$ flow="SOURCE, l:-10 -> rl[0][1]"
SINK(rl[0][0]) #$ flow="SOURCE, l:-9 -> rl[0][0]"
SINK(rl[0][1]) #$ flow="SOURCE, l:-9 -> rl[0][1]"

@expects(6)
@expects(4)
def test_map_multi_tuple():
l1 = (SOURCE,)
l2 = (SOURCE,)
Expand All @@ -456,8 +455,8 @@ def f(p1,p2):
return p1,p2

rl = list(map(f, l1, l2))
SINK(rl[0][0]) #$ flow="SOURCE, l:-10 -> rl[0][0]"
SINK(rl[0][1]) #$ MISSING: flow="SOURCE, l:-10 -> rl[0][1]"
SINK(rl[0][0]) #$ flow="SOURCE, l:-9 -> rl[0][0]"
SINK(rl[0][1]) #$ MISSING: flow="SOURCE, l:-9 -> rl[0][1]"

### filter

Expand Down Expand Up @@ -505,10 +504,108 @@ def f(p):
rl = list(filter(f,d))
SINK(rl[0]) #$ MISSING: flow="SOURCE, l:-7 -> rl[0]"

@expects(1)
def test_enumerate_list():
# TODO
pass
l = [SOURCE]

e = list(enumerate(l))

SINK(e[0][1]) #$ flow="SOURCE, l:-4 -> e[0][1]"

@expects(1)
def test_enumerate_set():
s = {SOURCE}

e = list(enumerate(s))

SINK(e[0][1]) #$ flow="SOURCE, l:-4 -> e[0][1]"

@expects(1)
def test_enumerate_tuple():
t = (SOURCE,)

e = list(enumerate(t))

SINK(e[0][1]) #$ flow="SOURCE, l:-4 -> e[0][1]"

@expects(2)
def test_enumerate_list_for():
l = [SOURCE]

for i, x in enumerate(l):
SINK(x) #$ flow="SOURCE, l:-3 -> x"

for t in enumerate(l):
SINK(t[1]) #$ flow="SOURCE, l:-6 -> t[1]"

@expects(1)
def test_enumerate_dict():
d = {SOURCE:"v"}

e = list(enumerate(d))

SINK(e[0][1]) # $ MISSING: flow="SOURCE, l:-4 -> e[0][1]"

@expects(8)
def test_zip_list():
# TODO
pass
l1 = [SOURCE, SOURCE]
l2 = [SOURCE, NONSOURCE]
l3 = [NONSOURCE, SOURCE]
l4 = [NONSOURCE, NONSOURCE]

z = list(zip(l1,l2,l3,l4))

SINK(z[0][0]) #$ flow="SOURCE, l:-7 -> z[0][0]"
SINK(z[0][1]) #$ flow="SOURCE, l:-7 -> z[0][1]"
SINK_F(z[0][2]) #$ SPURIOUS: flow="SOURCE, l:-7 -> z[0][2]"
SINK_F(z[0][3])
SINK(z[1][0]) #$ flow="SOURCE, l:-11 -> z[1][0]"
SINK_F(z[1][1]) #$ SPURIOUS: flow="SOURCE, l:-11 -> z[1][1]"
SINK(z[1][2]) #$ flow="SOURCE, l:-11 -> z[1][2]"
SINK_F(z[1][3])

@expects(4)
def test_zip_set():
s1 = {SOURCE}
s2 = {NONSOURCE}
s3 = {SOURCE}
s4 = {NONSOURCE}

z = list(zip(s1,s2,s3,s4))

SINK(z[0][0]) #$ flow="SOURCE, l:-11 -> z[0][0]"
SINK_F(z[0][1])
SINK(z[0][2]) #$ flow="SOURCE, l:-11 -> z[0][2]"
SINK_F(z[0][3])

@expects(8)
def test_zip_tuple():
t1 = (SOURCE, SOURCE)
t2 = (SOURCE, NONSOURCE)
t3 = (NONSOURCE, SOURCE)
t4 = (NONSOURCE, NONSOURCE)

z = list(zip(t1,t2,t3,t4))

SINK(z[0][0]) #$ flow="SOURCE, l:-7 -> z[0][0]"
SINK(z[0][1]) #$ flow="SOURCE, l:-7 -> z[0][1]"
SINK_F(z[0][2])
SINK_F(z[0][3])
SINK(z[1][0]) #$ flow="SOURCE, l:-11 -> z[1][0]"
SINK_F(z[1][1]) #$ SPURIOUS: flow="SOURCE, l:-11 -> z[1][1]"
SINK(z[1][2]) #$ MISSING: flow="SOURCE, l:-11 -> z[1][2]" # Tuple contents are not tracked beyond the first two arguments for performance.
SINK_F(z[1][3])

@expects(4)
def test_zip_dict():
d1 = {SOURCE: "v"}
d2 = {NONSOURCE: "v"}
d3 = {SOURCE: "v"}
d4 = {NONSOURCE: "v"}

z = list(zip(d1,d2,d3,d4))

SINK(z[0][0]) #$ MISSING: flow="SOURCE, l:-11 -> z[0][0]"
SINK_F(z[0][1])
SINK(z[0][2]) #$ MISSING: flow="SOURCE, l:-11 -> z[0][2]"
SINK_F(z[0][3])