Skip to content

Commit 6c50177

Browse files
committed
Merge remote-tracking branch 'origin/6.x'
2 parents 9f9ecb8 + ac118a9 commit 6c50177

File tree

6 files changed

+73
-1
lines changed

6 files changed

+73
-1
lines changed

config.xsd

+8
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
<xs:element name="stubs" type="StubsType" minOccurs="0" maxOccurs="1" />
1818
<xs:element name="plugins" type="PluginsType" minOccurs="0" maxOccurs="1" />
1919
<xs:element name="forbiddenFunctions" type="ExitFunctionsType" minOccurs="0" maxOccurs="1" />
20+
<xs:element name="forbiddenConstants" type="ConstantType" minOccurs="0" maxOccurs="1" />
2021
<xs:element name="issueHandlers" type="IssueHandlersType" minOccurs="0" maxOccurs="1" />
2122
<xs:element name="ignoreExceptions" type="ExceptionsType" minOccurs="0" maxOccurs="1" />
2223
<xs:element name="globals" type="GlobalsType" minOccurs="0" maxOccurs="1" />
@@ -179,6 +180,13 @@
179180
<xs:anyAttribute processContents="skip" />
180181
</xs:complexType>
181182

183+
<xs:complexType name="ConstantType">
184+
<xs:sequence>
185+
<xs:element name="constant" maxOccurs="unbounded" type="NameAttributeType" />
186+
</xs:sequence>
187+
<xs:anyAttribute processContents="skip" />
188+
</xs:complexType>
189+
182190
<xs:complexType name="PluginsType">
183191
<xs:choice minOccurs="0" maxOccurs="unbounded">
184192
<xs:element name="plugin">

docs/running_psalm/configuration.md

+9
Original file line numberDiff line numberDiff line change
@@ -655,6 +655,15 @@ Optional. Allows you to specify a list of functions that should emit the [`Forbi
655655
</forbiddenFunctions>
656656
```
657657

658+
#### &lt;forbiddenConstants&gt;
659+
Optional. Allows you to specify a list of constants that should emit the [`ForbiddenCode`](issues/ForbiddenCode.md) issue type.
660+
661+
```xml
662+
<forbiddenConstants>
663+
<constant name="FILTER_VALIDATE_URL" />
664+
</forbiddenConstants>
665+
```
666+
658667
## Accessing Psalm configuration in plugins
659668

660669
Plugins can access or modify the global configuration in plugins using

docs/running_psalm/issues/ForbiddenCode.md

+5-1
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ Emitted when Psalm encounters a var_dump, exec or similar expression that may ma
88
var_dump("bah");
99
```
1010

11-
This functions list can be extended by configuring `forbiddenFunctions` in `psalm.xml`
11+
This functions list can be extended by configuring `forbiddenFunctions` or `forbiddenConstants` in `psalm.xml`
1212

1313
```xml
1414
<?xml version="1.0"?>
@@ -19,5 +19,9 @@ This functions list can be extended by configuring `forbiddenFunctions` in `psal
1919
<function name="dd"/>
2020
<function name="var_dump"/>
2121
</forbiddenFunctions>
22+
23+
<forbiddenConstants>
24+
<constant name="FILTER_VALIDATE_URL" />
25+
</forbiddenConstants>
2226
</psalm>
2327
```

src/Psalm/Config.php

+11
Original file line numberDiff line numberDiff line change
@@ -371,6 +371,10 @@ final class Config
371371
* @var array<lowercase-string, bool>
372372
*/
373373
public array $forbidden_functions = [];
374+
/**
375+
* @var array<string, bool>
376+
*/
377+
public array $forbidden_constants = [];
374378

375379
public bool $find_unused_code = true;
376380

@@ -1299,6 +1303,13 @@ private static function fromXmlAndPaths(
12991303
}
13001304
}
13011305

1306+
if (isset($config_xml->forbiddenConstants) && isset($config_xml->forbiddenConstants->constant)) {
1307+
/** @var SimpleXMLElement $forbidden_function */
1308+
foreach ($config_xml->forbiddenConstants->constant as $forbidden_function) {
1309+
$config->forbidden_constants[(string) $forbidden_function['name']] = true;
1310+
}
1311+
}
1312+
13021313
if (isset($config_xml->stubs) && isset($config_xml->stubs->file)) {
13031314
/** @var SimpleXMLElement $stub_file */
13041315
foreach ($config_xml->stubs->file as $stub_file) {

src/Psalm/Internal/Analyzer/Statements/Expression/Fetch/ConstFetchAnalyzer.php

+13
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
use Psalm\Internal\Analyzer\Statements\ExpressionAnalyzer;
1616
use Psalm\Internal\Analyzer\StatementsAnalyzer;
1717
use Psalm\Internal\Provider\NodeDataProvider;
18+
use Psalm\Issue\ForbiddenCode;
1819
use Psalm\Issue\UndefinedConstant;
1920
use Psalm\IssueBuffer;
2021
use Psalm\Type;
@@ -58,6 +59,18 @@ public static function analyze(
5859
break;
5960

6061
default:
62+
if (isset($statements_analyzer->getCodebase()->config->forbidden_constants[$const_name])) {
63+
IssueBuffer::maybeAdd(
64+
new ForbiddenCode(
65+
'You have forbidden the use of ' . $const_name,
66+
new CodeLocation($statements_analyzer->getSource(), $stmt),
67+
),
68+
$statements_analyzer->getSuppressedIssues(),
69+
);
70+
71+
return;
72+
}
73+
6174
$const_type = self::getConstType(
6275
$statements_analyzer,
6376
$const_name,

tests/ForbiddenCodeTest.php

+27
Original file line numberDiff line numberDiff line change
@@ -120,6 +120,33 @@ public function testForbiddenCodeFunctionViaFunctions(): void
120120
$this->analyzeFile($file_path, new Context());
121121
}
122122

123+
public function testForbiddenCodeConstantViaConstant(): void
124+
{
125+
$this->expectExceptionMessage('ForbiddenCode');
126+
$this->expectException(CodeException::class);
127+
$this->project_analyzer = $this->getProjectAnalyzerWithConfig(
128+
TestConfig::loadFromXML(
129+
dirname(__DIR__, 2),
130+
'<?xml version="1.0"?>
131+
<psalm>
132+
<forbiddenConstants>
133+
<constant name="FILTER_VALIDATE_URL" />
134+
</forbiddenConstants>
135+
</psalm>',
136+
),
137+
);
138+
139+
$file_path = (string) getcwd() . '/src/somefile.php';
140+
141+
$this->addFile(
142+
$file_path,
143+
'<?php
144+
filter_var("http://example.com/image.jpg", FILTER_VALIDATE_URL);',
145+
);
146+
147+
$this->analyzeFile($file_path, new Context());
148+
}
149+
123150
public function testAllowedPrintFunction(): void
124151
{
125152
$this->project_analyzer = $this->getProjectAnalyzerWithConfig(

0 commit comments

Comments
 (0)