mirror of
https://github.com/github/codeql.git
synced 2026-04-27 17:55:19 +02:00
Python: Add tests for deepcopy FPs
There are two issues with `deepcopy` here. Firstly, the `deepcopy` function itself has a mutable default value in its parameter `_nil` (set to the empty list by default). Now, this value is never actually returned from `deepcopy`, as it is only used as a sentinel, but our analysis is not clever enough to see this. Thus, it thinks that this mutable default is returned, and hence the result of any call to `deepcopy` is a potential source. To remedy this, I opted to simply exclude all sources that originate from within the standard library. It is very unlikely for any of the sources in the standard library to be legit. Secondly, `deepcopy` -- by virtue of being a function that we model as preserving values -- admits data-flow through its calls, but this is not correct for the mutable default query, as it is here the _identity_ of the default value in question that is important. Thus, we get spurious flow through `deepcopy` for this specific query.
This commit is contained in:
@@ -1,4 +1,18 @@
|
||||
edges
|
||||
| file:///usr/local/python/3.10.13/lib/python3.10/copy.py:128:14:128:14 | ControlFlowNode for x | file:///usr/local/python/3.10.13/lib/python3.10/copy.py:149:34:149:34 | ControlFlowNode for x |
|
||||
| file:///usr/local/python/3.10.13/lib/python3.10/copy.py:128:14:128:14 | ControlFlowNode for x | file:///usr/local/python/3.10.13/lib/python3.10/copy.py:170:21:170:21 | ControlFlowNode for y |
|
||||
| file:///usr/local/python/3.10.13/lib/python3.10/copy.py:128:28:128:31 | ControlFlowNode for _nil | file:///usr/local/python/3.10.13/lib/python3.10/copy.py:138:21:138:24 | ControlFlowNode for _nil |
|
||||
| file:///usr/local/python/3.10.13/lib/python3.10/copy.py:138:5:138:5 | ControlFlowNode for y | file:///usr/local/python/3.10.13/lib/python3.10/copy.py:140:16:140:16 | ControlFlowNode for y |
|
||||
| file:///usr/local/python/3.10.13/lib/python3.10/copy.py:138:9:138:25 | ControlFlowNode for Attribute() | file:///usr/local/python/3.10.13/lib/python3.10/copy.py:138:5:138:5 | ControlFlowNode for y |
|
||||
| file:///usr/local/python/3.10.13/lib/python3.10/copy.py:138:21:138:24 | ControlFlowNode for _nil | file:///usr/local/python/3.10.13/lib/python3.10/copy.py:138:9:138:25 | ControlFlowNode for Attribute() |
|
||||
| file:///usr/local/python/3.10.13/lib/python3.10/copy.py:140:16:140:16 | ControlFlowNode for y | test.py:213:9:213:20 | ControlFlowNode for deepcopy() |
|
||||
| file:///usr/local/python/3.10.13/lib/python3.10/copy.py:140:16:140:16 | ControlFlowNode for y | test.py:217:9:217:19 | ControlFlowNode for deepcopy() |
|
||||
| file:///usr/local/python/3.10.13/lib/python3.10/copy.py:149:13:149:13 | ControlFlowNode for y | file:///usr/local/python/3.10.13/lib/python3.10/copy.py:178:12:178:12 | ControlFlowNode for y |
|
||||
| file:///usr/local/python/3.10.13/lib/python3.10/copy.py:149:17:149:41 | ControlFlowNode for _deepcopy_atomic() | file:///usr/local/python/3.10.13/lib/python3.10/copy.py:149:13:149:13 | ControlFlowNode for y |
|
||||
| file:///usr/local/python/3.10.13/lib/python3.10/copy.py:149:34:149:34 | ControlFlowNode for x | file:///usr/local/python/3.10.13/lib/python3.10/copy.py:149:17:149:41 | ControlFlowNode for _deepcopy_atomic() |
|
||||
| file:///usr/local/python/3.10.13/lib/python3.10/copy.py:149:34:149:34 | ControlFlowNode for x | file:///usr/local/python/3.10.13/lib/python3.10/copy.py:182:22:182:22 | ControlFlowNode for x |
|
||||
| file:///usr/local/python/3.10.13/lib/python3.10/copy.py:170:21:170:21 | ControlFlowNode for y | file:///usr/local/python/3.10.13/lib/python3.10/copy.py:178:12:178:12 | ControlFlowNode for y |
|
||||
| file:///usr/local/python/3.10.13/lib/python3.10/copy.py:182:22:182:22 | ControlFlowNode for x | file:///usr/local/python/3.10.13/lib/python3.10/copy.py:183:12:183:12 | ControlFlowNode for x |
|
||||
| test.py:2:12:2:12 | ControlFlowNode for l | test.py:3:5:3:5 | ControlFlowNode for l |
|
||||
| test.py:7:11:7:11 | ControlFlowNode for l | test.py:8:5:8:5 | ControlFlowNode for l |
|
||||
| test.py:12:14:12:14 | ControlFlowNode for l | test.py:13:9:13:9 | ControlFlowNode for l |
|
||||
@@ -40,7 +54,27 @@ edges
|
||||
| test.py:195:28:195:28 | ControlFlowNode for x | test.py:181:28:181:28 | ControlFlowNode for x |
|
||||
| test.py:197:18:197:18 | ControlFlowNode for x | test.py:198:28:198:28 | ControlFlowNode for x |
|
||||
| test.py:198:28:198:28 | ControlFlowNode for x | test.py:181:28:181:28 | ControlFlowNode for x |
|
||||
| test.py:213:5:213:5 | ControlFlowNode for y | test.py:214:5:214:5 | ControlFlowNode for y |
|
||||
| test.py:213:9:213:20 | ControlFlowNode for deepcopy() | test.py:213:5:213:5 | ControlFlowNode for y |
|
||||
| test.py:216:30:216:30 | ControlFlowNode for x | test.py:217:18:217:18 | ControlFlowNode for x |
|
||||
| test.py:217:5:217:5 | ControlFlowNode for y | test.py:218:5:218:5 | ControlFlowNode for y |
|
||||
| test.py:217:9:217:19 | ControlFlowNode for deepcopy() | test.py:217:5:217:5 | ControlFlowNode for y |
|
||||
| test.py:217:18:217:18 | ControlFlowNode for x | file:///usr/local/python/3.10.13/lib/python3.10/copy.py:128:14:128:14 | ControlFlowNode for x |
|
||||
| test.py:217:18:217:18 | ControlFlowNode for x | test.py:217:9:217:19 | ControlFlowNode for deepcopy() |
|
||||
nodes
|
||||
| file:///usr/local/python/3.10.13/lib/python3.10/copy.py:128:14:128:14 | ControlFlowNode for x | semmle.label | ControlFlowNode for x |
|
||||
| file:///usr/local/python/3.10.13/lib/python3.10/copy.py:128:28:128:31 | ControlFlowNode for _nil | semmle.label | ControlFlowNode for _nil |
|
||||
| file:///usr/local/python/3.10.13/lib/python3.10/copy.py:138:5:138:5 | ControlFlowNode for y | semmle.label | ControlFlowNode for y |
|
||||
| file:///usr/local/python/3.10.13/lib/python3.10/copy.py:138:9:138:25 | ControlFlowNode for Attribute() | semmle.label | ControlFlowNode for Attribute() |
|
||||
| file:///usr/local/python/3.10.13/lib/python3.10/copy.py:138:21:138:24 | ControlFlowNode for _nil | semmle.label | ControlFlowNode for _nil |
|
||||
| file:///usr/local/python/3.10.13/lib/python3.10/copy.py:140:16:140:16 | ControlFlowNode for y | semmle.label | ControlFlowNode for y |
|
||||
| file:///usr/local/python/3.10.13/lib/python3.10/copy.py:149:13:149:13 | ControlFlowNode for y | semmle.label | ControlFlowNode for y |
|
||||
| file:///usr/local/python/3.10.13/lib/python3.10/copy.py:149:17:149:41 | ControlFlowNode for _deepcopy_atomic() | semmle.label | ControlFlowNode for _deepcopy_atomic() |
|
||||
| file:///usr/local/python/3.10.13/lib/python3.10/copy.py:149:34:149:34 | ControlFlowNode for x | semmle.label | ControlFlowNode for x |
|
||||
| file:///usr/local/python/3.10.13/lib/python3.10/copy.py:170:21:170:21 | ControlFlowNode for y | semmle.label | ControlFlowNode for y |
|
||||
| file:///usr/local/python/3.10.13/lib/python3.10/copy.py:178:12:178:12 | ControlFlowNode for y | semmle.label | ControlFlowNode for y |
|
||||
| file:///usr/local/python/3.10.13/lib/python3.10/copy.py:182:22:182:22 | ControlFlowNode for x | semmle.label | ControlFlowNode for x |
|
||||
| file:///usr/local/python/3.10.13/lib/python3.10/copy.py:183:12:183:12 | ControlFlowNode for x | semmle.label | ControlFlowNode for x |
|
||||
| test.py:2:12:2:12 | ControlFlowNode for l | semmle.label | ControlFlowNode for l |
|
||||
| test.py:3:5:3:5 | ControlFlowNode for l | semmle.label | ControlFlowNode for l |
|
||||
| test.py:7:11:7:11 | ControlFlowNode for l | semmle.label | ControlFlowNode for l |
|
||||
@@ -107,7 +141,17 @@ nodes
|
||||
| test.py:195:28:195:28 | ControlFlowNode for x | semmle.label | ControlFlowNode for x |
|
||||
| test.py:197:18:197:18 | ControlFlowNode for x | semmle.label | ControlFlowNode for x |
|
||||
| test.py:198:28:198:28 | ControlFlowNode for x | semmle.label | ControlFlowNode for x |
|
||||
| test.py:213:5:213:5 | ControlFlowNode for y | semmle.label | ControlFlowNode for y |
|
||||
| test.py:213:9:213:20 | ControlFlowNode for deepcopy() | semmle.label | ControlFlowNode for deepcopy() |
|
||||
| test.py:214:5:214:5 | ControlFlowNode for y | semmle.label | ControlFlowNode for y |
|
||||
| test.py:216:30:216:30 | ControlFlowNode for x | semmle.label | ControlFlowNode for x |
|
||||
| test.py:217:5:217:5 | ControlFlowNode for y | semmle.label | ControlFlowNode for y |
|
||||
| test.py:217:9:217:19 | ControlFlowNode for deepcopy() | semmle.label | ControlFlowNode for deepcopy() |
|
||||
| test.py:217:18:217:18 | ControlFlowNode for x | semmle.label | ControlFlowNode for x |
|
||||
| test.py:218:5:218:5 | ControlFlowNode for y | semmle.label | ControlFlowNode for y |
|
||||
subpaths
|
||||
| file:///usr/local/python/3.10.13/lib/python3.10/copy.py:149:34:149:34 | ControlFlowNode for x | file:///usr/local/python/3.10.13/lib/python3.10/copy.py:182:22:182:22 | ControlFlowNode for x | file:///usr/local/python/3.10.13/lib/python3.10/copy.py:183:12:183:12 | ControlFlowNode for x | file:///usr/local/python/3.10.13/lib/python3.10/copy.py:149:17:149:41 | ControlFlowNode for _deepcopy_atomic() |
|
||||
| test.py:217:18:217:18 | ControlFlowNode for x | file:///usr/local/python/3.10.13/lib/python3.10/copy.py:128:14:128:14 | ControlFlowNode for x | file:///usr/local/python/3.10.13/lib/python3.10/copy.py:178:12:178:12 | ControlFlowNode for y | test.py:217:9:217:19 | ControlFlowNode for deepcopy() |
|
||||
#select
|
||||
| test.py:3:5:3:5 | ControlFlowNode for l | test.py:2:12:2:12 | ControlFlowNode for l | test.py:3:5:3:5 | ControlFlowNode for l | This expression mutates a $@. | test.py:2:12:2:12 | ControlFlowNode for l | default value |
|
||||
| test.py:8:5:8:5 | ControlFlowNode for l | test.py:7:11:7:11 | ControlFlowNode for l | test.py:8:5:8:5 | ControlFlowNode for l | This expression mutates a $@. | test.py:7:11:7:11 | ControlFlowNode for l | default value |
|
||||
@@ -138,3 +182,6 @@ subpaths
|
||||
| test.py:185:9:185:9 | ControlFlowNode for x | test.py:197:18:197:18 | ControlFlowNode for x | test.py:185:9:185:9 | ControlFlowNode for x | This expression mutates a $@. | test.py:197:18:197:18 | ControlFlowNode for x | default value |
|
||||
| test.py:187:9:187:9 | ControlFlowNode for x | test.py:194:18:194:18 | ControlFlowNode for x | test.py:187:9:187:9 | ControlFlowNode for x | This expression mutates a $@. | test.py:194:18:194:18 | ControlFlowNode for x | default value |
|
||||
| test.py:187:9:187:9 | ControlFlowNode for x | test.py:197:18:197:18 | ControlFlowNode for x | test.py:187:9:187:9 | ControlFlowNode for x | This expression mutates a $@. | test.py:197:18:197:18 | ControlFlowNode for x | default value |
|
||||
| test.py:214:5:214:5 | ControlFlowNode for y | file:///usr/local/python/3.10.13/lib/python3.10/copy.py:128:28:128:31 | ControlFlowNode for _nil | test.py:214:5:214:5 | ControlFlowNode for y | This expression mutates a $@. | file:///usr/local/python/3.10.13/lib/python3.10/copy.py:128:28:128:31 | ControlFlowNode for _nil | default value |
|
||||
| test.py:218:5:218:5 | ControlFlowNode for y | file:///usr/local/python/3.10.13/lib/python3.10/copy.py:128:28:128:31 | ControlFlowNode for _nil | test.py:218:5:218:5 | ControlFlowNode for y | This expression mutates a $@. | file:///usr/local/python/3.10.13/lib/python3.10/copy.py:128:28:128:31 | ControlFlowNode for _nil | default value |
|
||||
| test.py:218:5:218:5 | ControlFlowNode for y | test.py:216:30:216:30 | ControlFlowNode for x | test.py:218:5:218:5 | ControlFlowNode for y | This expression mutates a $@. | test.py:216:30:216:30 | ControlFlowNode for x | default value |
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
semmle-extractor-options: --max-import-depth=2 --dont-split-graph
|
||||
@@ -204,3 +204,15 @@ def tuple_default(x=(1,2)):
|
||||
|
||||
def safe_method(x=[]):
|
||||
return x.count(42)
|
||||
|
||||
# Use of deepcopy:
|
||||
|
||||
from copy import deepcopy
|
||||
|
||||
def flow_from_within_deepcopy_fp():
|
||||
y = deepcopy([])
|
||||
y.append(1) #$ SPURIOUS: modification=y
|
||||
|
||||
def flow_through_deepcopy_fp(x=[]):
|
||||
y = deepcopy(x)
|
||||
y.append(1) #$ SPURIOUS: modification=y
|
||||
|
||||
@@ -1 +1 @@
|
||||
semmle-extractor-options: --max-import-depth=1 --dont-split-graph
|
||||
semmle-extractor-options: --max-import-depth=2 --dont-split-graph
|
||||
|
||||
Reference in New Issue
Block a user