Skip to content

Commit d532daa

Browse files
authored
Merge pull request #40 from angelej/link-sink
Add link() sink
2 parents 2dd41e4 + 4d68848 commit d532daa

File tree

5 files changed

+77
-0
lines changed

5 files changed

+77
-0
lines changed

Diff for: README.md

+1
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,7 @@ The higher the level, the more selective the analysis.
8282
### File Write
8383
- [`copy()`](https://www.php.net/manual/en/function.copy)
8484
- [`file_put_contents()`](https://www.php.net/manual/en/function.file-put-contents)
85+
- [`link()`](https://www.php.net/manual/en/function.link)
8586
- [`move_uploaded_file()`](https://www.php.net/manual/en/function.move-uploaded-file)
8687
- [`symlink()`](https://www.php.net/manual/en/function.symlink)
8788

Diff for: src/SinkDetector.php

+1
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ class SinkDetector extends NodeVisitorAbstract {
2626
Sinks\FileRead\ReadfileSink::class,
2727
Sinks\FileWrite\CopySink::class,
2828
Sinks\FileWrite\FilePutContentsSink::class,
29+
Sinks\FileWrite\LinkSink::class,
2930
Sinks\FileWrite\MoveUploadedFileSink::class,
3031
Sinks\FileWrite\SymlinkSink::class,
3132
Sinks\InformationDisclosure\PhpinfoSink::class

Diff for: src/Sinks/FileWrite/LinkSink.php

+31
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
<?php declare(strict_types=1);
2+
3+
namespace Angelej\PhpInsider\Sinks\FileWrite;
4+
5+
use PhpParser\Node;
6+
use Angelej\PhpInsider\Level;
7+
use Angelej\PhpInsider\Sinks\Sink;
8+
use Angelej\PhpInsider\NodeHelper;
9+
10+
class LinkSink extends Sink {
11+
12+
/**
13+
* @param \PhpParser\Node $node
14+
* @return \Angelej\PhpInsider\Level|null
15+
*/
16+
public static function is(Node $node): ?Level {
17+
18+
$level = null;
19+
20+
if(NodeHelper::isFunctionCall($node, 'link')){
21+
22+
$level = Level::ZERO;
23+
24+
if(NodeHelper::isDynamic($node->args[0] ?? null)
25+
|| NodeHelper::isDynamic($node->args[1] ?? null)){
26+
$level = Level::ONE;
27+
}
28+
}
29+
return $level;
30+
}
31+
}

Diff for: tests/Unit/Sinks/FileWrite/LinkTest.php

+36
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
<?php declare(strict_types=1);
2+
3+
use Angelej\PhpInsider\File;
4+
use Angelej\PhpInsider\Level;
5+
use Angelej\PhpInsider\Analyser;
6+
use Angelej\PhpInsider\Sinks\FileWrite\LinkSink;
7+
8+
it('detects "link()" tokens (file write)', function(){
9+
10+
$file = new File(__DIR__ . '/../../files/Sinks/FileWrite/LinkFile.php');
11+
$sinks = (new Analyser())->analyse($file);
12+
13+
expect($sinks->inFile($file)
14+
->inLine(5)
15+
->ofLevel(Level::ONE)
16+
->first()
17+
)->toBeInstanceOf(LinkSink::class);
18+
19+
expect($sinks->inFile($file)
20+
->inLine(6)
21+
->ofLevel(Level::ONE)
22+
->first()
23+
)->toBeInstanceOf(LinkSink::class);
24+
25+
expect($sinks->inFile($file)
26+
->inLine(7)
27+
->ofLevel(Level::ONE)
28+
->first()
29+
)->toBeInstanceOf(LinkSink::class);
30+
31+
expect($sinks->inFile($file)
32+
->inLine(8)
33+
->ofLevel(Level::ZERO)
34+
->first()
35+
)->toBeInstanceOf(LinkSink::class);
36+
});

Diff for: tests/Unit/files/Sinks/FileWrite/LinkFile.php

+8
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
<?php declare(strict_types=1);
2+
3+
$link = 'link';
4+
$target = 'target.txt';
5+
link($target, $link);
6+
link($target, 'link');
7+
link('target.txt', $link);
8+
link('target.txt', 'link');

0 commit comments

Comments
 (0)