Skip to content

Commit 50d3592

Browse files
committed
Python: Add more complete tests of os module
I went through https://docs.python.org/3.10/library/os.html in order, and added all the functions that works on paths. `lstat` and `statvfs` were already modeled, but did not have any tests.
1 parent a91208f commit 50d3592

File tree

1 file changed

+156
-0
lines changed

1 file changed

+156
-0
lines changed

python/ql/test/library-tests/frameworks/stdlib/FileSystemAccess.py

Lines changed: 156 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import builtins
22
import io
33
import os
4+
import stat
45

56
open("file") # $ getAPathArgument="file"
67
open(file="file") # $ getAPathArgument="file"
@@ -60,5 +61,160 @@ def through_function(open_file):
6061
genericpath.exists(path="path") # $ getAPathArgument="path"
6162

6263
# os
64+
65+
def test_fsencode_fsdecode():
66+
# notice that this does not make a file system access, but performs encoding/decoding.
67+
os.fsencode("filename") # $ MISSING: encodeInput="filename" encodeOutput=os.fsencode(..) encodeFormat=filesystem
68+
os.fsencode(filename="filename") # $ MISSING: encodeInput="filename" encodeOutput=os.fsencode(..) encodeFormat=filesystem
69+
70+
os.fsdecode("filename") # $ MISSING: decodeInput="filename" decodeOutput=os.fsdecode(..) decodeFormat=filesystem
71+
os.fsdecode(filename="filename") # $ MISSING: decodeInput="filename" decodeOutput=os.fsdecode(..) decodeFormat=filesystem
72+
73+
def test_fspath():
74+
# notice that this does not make a file system access, but returns the path
75+
# representation of a path-like object.
76+
77+
ensure_tainted(
78+
TAINTED_STRING, # $ tainted
79+
os.fspath(TAINTED_STRING), # $ MISSING: tainted
80+
os.fspath(path=TAINTED_STRING), # $ MISSING: tainted
81+
)
82+
83+
os.open("path", os.O_RDONLY) # $ MISSING: getAPathArgument="path"
84+
os.open(path="path", flags=os.O_RDONLY) # $ MISSING: getAPathArgument="path"
85+
86+
os.access("path", os.R_OK) # $ MISSING: getAPathArgument="path"
87+
os.access(path="path", mode=os.R_OK) # $ MISSING: getAPathArgument="path"
88+
89+
os.chdir("path") # $ MISSING: getAPathArgument="path"
90+
os.chdir(path="path") # $ MISSING: getAPathArgument="path"
91+
92+
os.chflags("path", stat.UF_NODUMP) # $ MISSING: getAPathArgument="path"
93+
os.chflags(path="path", flags=stat.UF_NODUMP) # $ MISSING: getAPathArgument="path"
94+
95+
os.chmod("path", 0o700) # $ MISSING: getAPathArgument="path"
96+
os.chmod(path="path", mode=0o700) # $ MISSING: getAPathArgument="path"
97+
98+
os.chown("path", -1, -1) # $ MISSING: getAPathArgument="path"
99+
os.chown(path="path", uid=-1, gid=-1) # $ MISSING: getAPathArgument="path"
100+
101+
# unix only
102+
os.chroot("path") # $ MISSING: getAPathArgument="path"
103+
os.chroot(path="path") # $ MISSING: getAPathArgument="path"
104+
105+
# unix only
106+
os.lchflags("path", stat.UF_NODUMP) # $ MISSING: getAPathArgument="path"
107+
os.lchflags(path="path", flags=stat.UF_NODUMP) # $ MISSING: getAPathArgument="path"
108+
109+
# unix only
110+
os.lchmod("path", 0o700) # $ MISSING: getAPathArgument="path"
111+
os.lchmod(path="path", mode=0o700) # $ MISSING: getAPathArgument="path"
112+
113+
# unix only
114+
os.lchown("path", -1, -1) # $ MISSING: getAPathArgument="path"
115+
os.lchown(path="path", uid=-1, gid=-1) # $ MISSING: getAPathArgument="path"
116+
117+
os.link("src", "dst") # $ MISSING: getAPathArgument="src" getAPathArgument="dst"
118+
os.link(src="src", dst="dst") # $ MISSING: getAPathArgument="src" getAPathArgument="dst"
119+
120+
os.listdir("path") # $ MISSING: getAPathArgument="path"
121+
os.listdir(path="path") # $ MISSING: getAPathArgument="path"
122+
123+
os.lstat("path") # $ getAPathArgument="path"
124+
os.lstat(path="path") # $ getAPathArgument="path"
125+
126+
os.mkdir("path") # $ MISSING: getAPathArgument="path"
127+
os.mkdir(path="path") # $ MISSING: getAPathArgument="path"
128+
129+
os.makedirs("name") # $ MISSING: getAPathArgument="name"
130+
os.makedirs(name="name") # $ MISSING: getAPathArgument="name"
131+
132+
os.mkfifo("path") # $ MISSING: getAPathArgument="path"
133+
os.mkfifo(path="path") # $ MISSING: getAPathArgument="path"
134+
135+
os.mknod("path") # $ MISSING: getAPathArgument="path"
136+
os.mknod(path="path") # $ MISSING: getAPathArgument="path"
137+
138+
os.pathconf("path", "name") # $ MISSING: getAPathArgument="path"
139+
os.pathconf(path="path", name="name") # $ MISSING: getAPathArgument="path"
140+
141+
os.readlink("path") # $ MISSING: getAPathArgument="path"
142+
os.readlink(path="path") # $ MISSING: getAPathArgument="path"
143+
144+
os.remove("path") # $ MISSING: getAPathArgument="path"
145+
os.remove(path="path") # $ MISSING: getAPathArgument="path"
146+
147+
os.removedirs("name") # $ MISSING: getAPathArgument="name"
148+
os.removedirs(name="name") # $ MISSING: getAPathArgument="name"
149+
150+
os.rename("src", "dst") # $ MISSING: getAPathArgument="src" getAPathArgument="dst"
151+
os.rename(src="src", dst="dst") # $ MISSING: getAPathArgument="src" getAPathArgument="dst"
152+
153+
os.renames("old", "new") # $ MISSING: getAPathArgument="old" getAPathArgument="new"
154+
os.renames(old="old", new="new") # $ MISSING: getAPathArgument="old" getAPathArgument="new"
155+
156+
os.replace("src", "dst") # $ MISSING: getAPathArgument="src" getAPathArgument="dst"
157+
os.replace(src="src", dst="dst") # $ MISSING: getAPathArgument="src" getAPathArgument="dst"
158+
159+
os.rmdir("path") # $ MISSING: getAPathArgument="path"
160+
os.rmdir(path="path") # $ MISSING: getAPathArgument="path"
161+
162+
os.scandir("path") # $ MISSING: getAPathArgument="path"
163+
os.scandir(path="path") # $ MISSING: getAPathArgument="path"
164+
63165
os.stat("path") # $ getAPathArgument="path"
64166
os.stat(path="path") # $ getAPathArgument="path"
167+
168+
os.statvfs("path") # $ getAPathArgument="path"
169+
os.statvfs(path="path") # $ getAPathArgument="path"
170+
171+
os.symlink("src", "dst") # $ MISSING: getAPathArgument="src" getAPathArgument="dst"
172+
os.symlink(src="src", dst="dst") # $ MISSING: getAPathArgument="src" getAPathArgument="dst"
173+
174+
os.truncate("path", 42) # $ MISSING: getAPathArgument="path"
175+
os.truncate(path="path", length=42) # $ MISSING: getAPathArgument="path"
176+
177+
os.unlink("path") # $ MISSING: getAPathArgument="path"
178+
os.unlink(path="path") # $ MISSING: getAPathArgument="path"
179+
180+
os.utime("path") # $ MISSING: getAPathArgument="path"
181+
os.utime(path="path") # $ MISSING: getAPathArgument="path"
182+
183+
os.walk("top") # $ MISSING: getAPathArgument="top"
184+
os.walk(top="top") # $ MISSING: getAPathArgument="top"
185+
186+
os.fwalk("top") # $ MISSING: getAPathArgument="top"
187+
os.fwalk(top="top") # $ MISSING: getAPathArgument="top"
188+
189+
# Linux only
190+
os.getxattr("path", "attribute") # $ MISSING: getAPathArgument="path"
191+
os.getxattr(path="path", attribute="attribute") # $ MISSING: getAPathArgument="path"
192+
193+
# Linux only
194+
os.listxattr("path") # $ MISSING: getAPathArgument="path"
195+
os.listxattr(path="path") # $ MISSING: getAPathArgument="path"
196+
197+
# Linux only
198+
os.removexattr("path", "attribute") # $ MISSING: getAPathArgument="path"
199+
os.removexattr(path="path", attribute="attribute") # $ MISSING: getAPathArgument="path"
200+
201+
# Linux only
202+
os.setxattr("path", "attribute", "value") # $ MISSING: getAPathArgument="path"
203+
os.setxattr(path="path", attribute="attribute", value="value") # $ MISSING: getAPathArgument="path"
204+
205+
# Windows only
206+
os.add_dll_directory("path") # $ MISSING: getAPathArgument="path"
207+
os.add_dll_directory(path="path") # $ MISSING: getAPathArgument="path"
208+
209+
# TODO: os.exec* calls all take a path as first argument
210+
# TODO: os.spawn* calls all take a path as second argument
211+
# TODO: os.posix_spawn calls
212+
213+
# TODO: Maybe these should not be considered a command injection sink?
214+
# since `os.execlp("bash -c 'echo hello'", "bash")`
215+
# raises exception: `FileNotFoundError: [Errno 2] No such file or directory`
216+
# and you're not able to execute arbitrary commands, but change what file is being run.
217+
218+
# Windows only
219+
os.startfile("path") # $ MISSING: getAPathArgument="path"
220+
os.startfile(path="path") # $ MISSING: getAPathArgument="path"

0 commit comments

Comments
 (0)