Skip to content

Commit f8a0b1c

Browse files
Update docs, precision, and deprecate old library
1 parent f750e22 commit f8a0b1c

File tree

5 files changed

+34
-33
lines changed

5 files changed

+34
-33
lines changed

python/ql/src/Resources/FileNotAlwaysClosed.py

Lines changed: 0 additions & 15 deletions
This file was deleted.

python/ql/src/Resources/FileNotAlwaysClosed.qhelp

Lines changed: 9 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -4,32 +4,27 @@
44
<qhelp>
55

66
<overview>
7-
<p> If a file is opened then it should always be closed again, even if an
8-
exception is raised.
9-
Failing to ensure that all files are closed may result in failure due to too
10-
many open files.</p>
7+
<p>When a file is opened, it should always be closed. Failure to close files could result in loss of data or resource leaks.</p>
118

129
</overview>
1310
<recommendation>
1411

15-
<p>Ensure that if you open a file it is always closed on exiting the method.
16-
Wrap the code between the <code>open()</code> and <code>close()</code>
17-
functions in a <code>with</code> statement or use a <code>try...finally</code>
18-
statement. Using a <code>with</code> statement is preferred as it is shorter
19-
and more readable.</p>
12+
<p>Ensure that opened files are always closed, including when an exception could be raised.
13+
The best practice is to use a <code>with</code> statement to automatically clean up resources.
14+
Otherwise, ensure that <code>.close()</code> is called in a <code>try...except</code> or <code>try...finally</code>
15+
block to handle any possible exceptions.
16+
</p>
2017

2118
</recommendation>
2219
<example>
23-
<p>The following code shows examples of different ways of closing a file. In the first example, the
24-
file is closed only if the method is exited successfully. In the other examples, the file is always
25-
closed on exiting the method.</p>
20+
<p>In the following examples, in the case marked BAD, the file may not be closed if an exception is raised. In the cases marked GOOD, the file is always closed.</p>
2621

27-
<sample src="FileNotAlwaysClosed.py" />
22+
<sample src="examples/FileNotAlwaysClosed.py" />
2823

2924
</example>
3025
<references>
3126

32-
27+
<li>Python Documentation: <a href="https://docs.python.org/3/tutorial/inputoutput.html#reading-and-writing-files">Reading and writing files</a>.</li>
3328
<li>Python Language Reference: <a href="http://docs.python.org/reference/compound_stmts.html#the-with-statement">The with statement</a>,
3429
<a href="http://docs.python.org/reference/compound_stmts.html#the-try-statement">The try statement</a>.</li>
3530
<li>Python PEP 343: <a href="http://www.python.org/dev/peps/pep-0343">The "with" Statement</a>.</li>

python/ql/src/Resources/FileNotAlwaysClosed.ql

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,14 @@
11
/**
22
* @name File is not always closed
3-
* @description Opening a file without ensuring that it is always closed may cause resource leaks.
3+
* @description Opening a file without ensuring that it is always closed may cause data loss or resource leaks.
44
* @kind problem
55
* @tags efficiency
66
* correctness
77
* resources
88
* external/cwe/cwe-772
99
* @problem.severity warning
1010
* @sub-severity high
11-
* @precision medium
11+
* @precision high
1212
* @id py/file-not-closed
1313
*/
1414

@@ -21,5 +21,5 @@ where
2121
msg = "File is opened but is not closed."
2222
or
2323
fileMayNotBeClosedOnException(fo, _) and
24-
msg = "File may not be closed if an exception is raised"
24+
msg = "File may not be closed if an exception is raised."
2525
select fo.getLocalSource(), msg

python/ql/src/Resources/FileOpen.qll

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,8 @@
1-
/** Contains predicates concerning when and where files are opened and closed. */
1+
/**
2+
* DEPRECATED: Use FileNotAlwaysClosedQuery instead.
3+
* Contains predicates concerning when and where files are opened and closed.
4+
*/
5+
deprecated module;
26

37
import python
48
import semmle.python.pointsto.Filters
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
def bad():
2+
f = open("filename", "w")
3+
f.write("could raise exception") # BAD: This call could raise an exception, leading to the file not being closed.
4+
f.close()
5+
6+
7+
def good1():
8+
with open("filename", "w") as f:
9+
f.write("always closed") # GOOD: The `with` statement ensures the file is always closed.
10+
11+
def good2():
12+
f = open("filename", "w")
13+
try:
14+
f.write("always closed")
15+
finally:
16+
f.close() # GOOD: The `finally` block always ensures the file is closed.
17+

0 commit comments

Comments
 (0)