24
24
use PhpParser \Node \Expr \ShellExec ;
25
25
use PhpParser \Node \Expr \Variable ;
26
26
use PhpParser \Node \Name ;
27
+ use PhpParser \Node \Name \FullyQualified ;
27
28
use PhpParser \Node \Scalar \LNumber ;
28
29
use PHPStan \Analyser \Scope ;
29
30
use PHPUnit \Framework \MockObject \MockObject ;
@@ -53,7 +54,7 @@ protected function setUp(): void
53
54
['type ' => 'Stmt_Echo ' ],
54
55
['type ' => 'Expr_Eval ' ],
55
56
['type ' => 'Expr_Exit ' ],
56
- ['type ' => 'Expr_FuncCall ' , 'functions ' => ['debug_backtrace ' , 'dump ' ]],
57
+ ['type ' => 'Expr_FuncCall ' , 'functions ' => ['debug_backtrace ' , 'dump ' , ' Safe\namespaced ' ]],
57
58
['type ' => 'Expr_Print ' ],
58
59
['type ' => 'Expr_ShellExec ' ],
59
60
]);
@@ -80,35 +81,73 @@ public function testProcessNodeWithUnhandledType(Expr $node): void
80
81
$ this ->assertCount (0 , $ this ->rule ->processNode ($ node , $ this ->scope ));
81
82
}
82
83
83
- /**
84
- * Tests processNode with banned/allowed functions.
85
- */
86
- public function testProcessNodeWithFunctions (): void
84
+ public function testProcessNodeWithBannedFunctions (): void
85
+ {
86
+ $ ruleWithoutLeadingSlashes = new BannedNodesRule ([
87
+ [
88
+ 'type ' => 'Expr_FuncCall ' ,
89
+ 'functions ' => [
90
+ 'root ' ,
91
+ 'Safe\namespaced ' ,
92
+ ]
93
+ ],
94
+ ]);
95
+
96
+ $ ruleWithLeadingSlashes = new BannedNodesRule ([
97
+ [
98
+ 'type ' => 'Expr_FuncCall ' ,
99
+ 'functions ' => [
100
+ '\root ' ,
101
+ '\Safe\namespaced ' ,
102
+ ]
103
+ ],
104
+ ]);
105
+
106
+ $ rootFunction = new FuncCall (new Name ('root ' ));
107
+ $ this ->assertNodeTriggersError ($ ruleWithoutLeadingSlashes , $ rootFunction );
108
+ $ this ->assertNodeTriggersError ($ ruleWithLeadingSlashes , $ rootFunction );
109
+
110
+ $ namespacedFunction = new FuncCall (new FullyQualified ('Safe\namespaced ' ));
111
+ $ this ->assertNodeTriggersError ($ ruleWithoutLeadingSlashes , $ namespacedFunction );
112
+ $ this ->assertNodeTriggersError ($ ruleWithLeadingSlashes , $ namespacedFunction );
113
+ }
114
+
115
+ protected function assertNodeTriggersError (BannedNodesRule $ rule , Node $ node ): void
87
116
{
88
- foreach ([ ' debug_backtrace ' , ' dump ' ] as $ bannedFunction ) {
89
- $ node = new FuncCall ( new Name ( $ bannedFunction ));
117
+ $ this -> assertCount ( 1 , $ rule -> processNode ( $ node , $ this -> scope ));
118
+ }
90
119
91
- $ this ->assertCount (1 , $ this ->rule ->processNode ($ node , $ this ->scope ));
92
- }
120
+ protected function assertNodePasses (BannedNodesRule $ rule , Node $ node ): void
121
+ {
122
+ $ this ->assertCount (0 , $ rule ->processNode ($ node , $ this ->scope ));
123
+ }
93
124
94
- foreach (['array_search ' , 'sprintf ' ] as $ allowedFunction ) {
95
- $ node = new FuncCall (new Name ($ allowedFunction ));
125
+ public function testProcessNodeWithAllowedFunctions (): void
126
+ {
127
+ $ rootFunction = new FuncCall (new Name ('allowed ' ));
128
+ $ this ->assertNodePasses ($ this ->rule , $ rootFunction );
96
129
97
- $ this ->assertCount (0 , $ this ->rule ->processNode ($ node , $ this ->scope ));
98
- }
130
+ $ namespacedFunction = new FuncCall (new FullyQualified ('Safe\allowed ' ));
131
+ $ this ->assertNodePasses ($ this ->rule , $ namespacedFunction );
132
+ }
99
133
134
+ public function testProcessNodeWithFunctionInClosure (): void
135
+ {
100
136
$ node = new FuncCall (new Variable ('myClosure ' ));
101
137
102
- $ this ->assertCount (0 , $ this ->rule ->processNode ($ node , $ this ->scope ));
138
+ $ this ->assertNodePasses ($ this ->rule , $ node );
139
+ }
103
140
141
+ public function testProcessNodeWithArrayDimFetch (): void
142
+ {
104
143
$ node = new FuncCall (
105
144
new Expr \ArrayDimFetch (
106
145
new Variable ('myArray ' ),
107
146
LNumber::fromString ('0 ' , ['kind ' => LNumber::KIND_DEC ])
108
147
)
109
148
);
110
149
111
- $ this ->assertCount ( 0 , $ this ->rule -> processNode ( $ node , $ this -> scope ) );
150
+ $ this ->assertNodePasses ( $ this ->rule , $ node );
112
151
}
113
152
114
153
/**
@@ -120,7 +159,7 @@ public function testProcessNodeWithFunctions(): void
120
159
*/
121
160
public function testProcessNodeWithHandledTypes (Expr $ node ): void
122
161
{
123
- $ this ->assertCount ( 1 , $ this ->rule -> processNode ( $ node , $ this -> scope ) );
162
+ $ this ->assertNodeTriggersError ( $ this ->rule , $ node );
124
163
}
125
164
126
165
/**
0 commit comments