@@ -4,7 +4,7 @@ import semmle.python.pointsto.Filters
44
55/** Holds if `open` is a call that returns a newly opened file */
66predicate call_to_open ( ControlFlowNode open ) {
7- exists ( FunctionObject f |
7+ exists ( FunctionValue f |
88 function_opens_file ( f ) and
99 f .getACall ( ) = open
1010 ) and
@@ -18,7 +18,8 @@ predicate expr_is_open(ControlFlowNode n, ControlFlowNode open) {
1818 or
1919 exists ( EssaVariable v |
2020 n instanceof NameNode and
21- var_is_open ( v , open ) |
21+ var_is_open ( v , open )
22+ |
2223 n = v .getAUse ( )
2324 or
2425 wraps_file ( n , v )
@@ -27,7 +28,7 @@ predicate expr_is_open(ControlFlowNode n, ControlFlowNode open) {
2728
2829/** Holds if `call` wraps the object referred to by `v` and returns it */
2930private predicate wraps_file ( CallNode call , EssaVariable v ) {
30- exists ( ClassObject cls |
31+ exists ( ClassValue cls |
3132 call = cls .getACall ( ) and
3233 call .getAnArg ( ) = v .getAUse ( )
3334 )
@@ -46,7 +47,8 @@ predicate passes_open_files(Variable v, ControlFlowNode test, boolean sense) {
4647 exists ( AttrNode closed |
4748 closed = test and
4849 closed .getObject ( "closed" ) = v .getAUse ( )
49- ) and sense = false
50+ ) and
51+ sense = false
5052 or
5153 // `if fd ==/is ...:` most commonly `if fd is None:`
5254 equality_test ( test , v .getAUse ( ) , sense .booleanNot ( ) , _)
@@ -56,29 +58,30 @@ predicate passes_open_files(Variable v, ControlFlowNode test, boolean sense) {
5658 or
5759 exists ( UnaryExprNode n |
5860 n = test and
59- n .getNode ( ) .getOp ( ) instanceof Not |
61+ n .getNode ( ) .getOp ( ) instanceof Not
62+ |
6063 passes_open_files ( v , n .getOperand ( ) , sense .booleanNot ( ) )
6164 )
6265}
6366
6467/* Helper for `def_is_open` to give better join order */
6568private predicate passes_open_files ( PyEdgeRefinement refinement ) {
66- passes_open_files ( refinement .getSourceVariable ( ) , refinement .getPredecessor ( ) .getLastNode ( ) , refinement .getSense ( ) )
69+ passes_open_files ( refinement .getSourceVariable ( ) , refinement .getPredecessor ( ) .getLastNode ( ) ,
70+ refinement .getSense ( ) )
6771}
6872
6973/** Holds if `def` refers to a file opened at `open` */
7074predicate def_is_open ( EssaDefinition def , ControlFlowNode open ) {
7175 expr_is_open ( def .( AssignmentDefinition ) .getValue ( ) , open )
7276 or
73- exists ( PyEdgeRefinement refinement |
74- refinement = def |
75- var_is_open ( refinement .getInput ( ) , open ) and
77+ exists ( PyEdgeRefinement refinement | refinement = def |
78+ var_is_open ( refinement .getInput ( ) , open ) and
7679 passes_open_files ( refinement )
7780 )
7881 or
79- exists ( PyNodeRefinement refinement |
80- refinement = def |
81- not closes_file ( def ) and not wraps_file ( refinement .getDefiningNode ( ) , refinement .getInput ( ) ) and
82+ exists ( PyNodeRefinement refinement | refinement = def |
83+ not closes_file ( def ) and
84+ not wraps_file ( refinement .getDefiningNode ( ) , refinement .getInput ( ) ) and
8285 var_is_open ( refinement .getInput ( ) , open )
8386 )
8487 or
@@ -88,16 +91,15 @@ predicate def_is_open(EssaDefinition def, ControlFlowNode open) {
8891/** Holds if `call` closes a file */
8992predicate closes_file ( EssaNodeRefinement call ) {
9093 closes_arg ( call .( ArgumentRefinement ) .getDefiningNode ( ) , call .getSourceVariable ( ) ) or
91- close_method_call ( call .( MethodCallsiteRefinement ) .getCall ( ) , call .getSourceVariable ( ) .( Variable ) .getAUse ( ) )
94+ close_method_call ( call .( MethodCallsiteRefinement ) .getCall ( ) ,
95+ call .getSourceVariable ( ) .( Variable ) .getAUse ( ) )
9296}
9397
9498/** Holds if `call` closes its argument, which is an open file referred to by `v` */
9599predicate closes_arg ( CallNode call , Variable v ) {
96100 call .getAnArg ( ) = v .getAUse ( ) and
97101 (
98- exists ( FunctionObject close |
99- call = close .getACall ( ) and function_closes_file ( close )
100- )
102+ exists ( FunctionValue close | call = close .getACall ( ) and function_closes_file ( close ) )
101103 or
102104 call .getFunction ( ) .( NameNode ) .getId ( ) = "close"
103105 )
@@ -106,17 +108,15 @@ predicate closes_arg(CallNode call, Variable v) {
106108/** Holds if `call` closes its 'self' argument, which is an open file referred to by `v` */
107109predicate close_method_call ( CallNode call , ControlFlowNode self ) {
108110 call .getFunction ( ) .( AttrNode ) .getObject ( ) = self and
109- exists ( FunctionObject close |
110- call = close .getACall ( ) and function_closes_file ( close )
111- )
111+ exists ( FunctionValue close | call = close .getACall ( ) and function_closes_file ( close ) )
112112 or
113113 call .getFunction ( ) .( AttrNode ) .getObject ( "close" ) = self
114114}
115115
116- predicate function_closes_file ( FunctionObject close ) {
117- close . hasLongName ( "os.close" )
116+ predicate function_closes_file ( FunctionValue close ) {
117+ close = Value :: named ( "os.close" )
118118 or
119- function_should_close_parameter ( close .getFunction ( ) )
119+ function_should_close_parameter ( close .getScope ( ) )
120120}
121121
122122predicate function_should_close_parameter ( Function func ) {
@@ -126,26 +126,25 @@ predicate function_should_close_parameter(Function func) {
126126 )
127127}
128128
129- predicate function_opens_file ( FunctionObject f ) {
130- f = Object :: builtin ( "open" )
129+ predicate function_opens_file ( FunctionValue f ) {
130+ f = Value :: named ( "open" )
131131 or
132- exists ( EssaVariable v , Return ret |
133- ret .getScope ( ) = f .getFunction ( ) |
134- ret .getValue ( ) .getAFlowNode ( ) = v .getAUse ( ) and
132+ exists ( EssaVariable v , Return ret | ret .getScope ( ) = f .getScope ( ) |
133+ ret .getValue ( ) .getAFlowNode ( ) = v .getAUse ( ) and
135134 var_is_open ( v , _)
136135 )
137136 or
138- exists ( Return ret , FunctionObject callee |
139- ret .getScope ( ) = f .getFunction ( ) |
140- ret .getValue ( ) .getAFlowNode ( ) = callee .getACall ( ) and
137+ exists ( Return ret , FunctionValue callee | ret .getScope ( ) = f .getScope ( ) |
138+ ret .getValue ( ) .getAFlowNode ( ) = callee .getACall ( ) and
141139 function_opens_file ( callee )
142140 )
143141}
144142
145143predicate file_is_returned ( EssaVariable v , ControlFlowNode open ) {
146144 exists ( NameNode n , Return ret |
147145 var_is_open ( v , open ) and
148- v .getAUse ( ) = n |
146+ v .getAUse ( ) = n
147+ |
149148 ret .getValue ( ) = n .getNode ( )
150149 or
151150 ret .getValue ( ) .( Tuple ) .getAnElt ( ) = n .getNode ( )
0 commit comments