Skip to content

Commit f5f8171

Browse files
committed
Prevent PHP errors using more strict filters
1 parent 00bd689 commit f5f8171

9 files changed

Lines changed: 162 additions & 26 deletions

File tree

src/FilterIn/BooleanFilterIn.php

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
namespace Arachne\EntityLoader\FilterIn;
1212

1313
use Arachne\EntityLoader\FilterInInterface;
14+
use Nette\Application\BadRequestException;
1415

1516
/**
1617
* @author Jáchym Toušek <enumag@gmail.com>
@@ -22,6 +23,10 @@ class BooleanFilterIn implements FilterInInterface
2223
*/
2324
public function filterIn($value)
2425
{
26+
if (!is_string($value)) {
27+
throw new BadRequestException();
28+
}
29+
2530
return (bool) $value;
2631
}
2732
}

src/FilterIn/FloatFilterIn.php

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
namespace Arachne\EntityLoader\FilterIn;
1212

1313
use Arachne\EntityLoader\FilterInInterface;
14+
use Nette\Application\BadRequestException;
1415

1516
/**
1617
* @author Jáchym Toušek <enumag@gmail.com>
@@ -22,6 +23,10 @@ class FloatFilterIn implements FilterInInterface
2223
*/
2324
public function filterIn($value)
2425
{
26+
if (!is_string($value)) {
27+
throw new BadRequestException();
28+
}
29+
2530
return (float) $value;
2631
}
2732
}

src/FilterIn/IntegerFilterIn.php

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
namespace Arachne\EntityLoader\FilterIn;
1212

1313
use Arachne\EntityLoader\FilterInInterface;
14+
use Nette\Application\BadRequestException;
1415

1516
/**
1617
* @author Jáchym Toušek <enumag@gmail.com>
@@ -22,6 +23,10 @@ class IntegerFilterIn implements FilterInInterface
2223
*/
2324
public function filterIn($value)
2425
{
26+
if (!is_string($value)) {
27+
throw new BadRequestException();
28+
}
29+
2530
return (int) $value;
2631
}
2732
}

src/FilterIn/StringFilterIn.php

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
namespace Arachne\EntityLoader\FilterIn;
1212

1313
use Arachne\EntityLoader\FilterInInterface;
14+
use Nette\Application\BadRequestException;
1415

1516
/**
1617
* @author Jáchym Toušek <enumag@gmail.com>
@@ -22,6 +23,10 @@ class StringFilterIn implements FilterInInterface
2223
*/
2324
public function filterIn($value)
2425
{
25-
return (string) $value;
26+
if (!is_string($value)) {
27+
throw new BadRequestException();
28+
}
29+
30+
return $value;
2631
}
2732
}

tests/functional/config/config.neon

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ extensions:
1111
oops.cachefactory: Oops\CacheFactory\DI\CacheFactoryExtension
1212

1313
nette.application:
14-
catchExceptions: null
14+
catchExceptions: false
1515
mapping:
1616
*: Tests\Functional\Fixtures\*Presenter
1717

tests/functional/src/Fixtures/ArticlePresenter.php

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,14 +18,35 @@ public function actionUntyped($parameter)
1818
{
1919
}
2020

21+
public function actionEntity(Article $parameter)
22+
{
23+
}
24+
2125
/**
2226
* @param int $parameter
2327
*/
2428
public function actionInt($parameter = 1)
2529
{
2630
}
2731

28-
public function actionEntity(Article $parameter)
32+
/**
33+
* @param bool $parameter
34+
*/
35+
public function actionBool($parameter)
36+
{
37+
}
38+
39+
/**
40+
* @param float $parameter
41+
*/
42+
public function actionFloat($parameter)
43+
{
44+
}
45+
46+
/**
47+
* @param string $parameter
48+
*/
49+
public function actionString($parameter)
2950
{
3051
}
3152
}

tests/functional/src/Fixtures/RouterFactory.php

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -29,9 +29,12 @@ public function __construct(RequestEntityUnloader $unloader)
2929
public function create()
3030
{
3131
$router = new RouteList();
32-
$router[] = new Route('/<action>[/<parameter>]', [
33-
'presenter' => 'Article',
34-
]);
32+
$router[] = new Route(
33+
'/<action>',
34+
[
35+
'presenter' => 'Article',
36+
]
37+
);
3538

3639
return new RouterWrapper($router, $this->unloader);
3740
}

tests/functional/src/RequestEntityLoaderTest.php

Lines changed: 111 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44

55
use Codeception\TestCase\Test;
66
use Nette\Application\Application;
7+
use Nette\Application\UI\Presenter;
78
use Tests\Functional\Fixtures\Article;
89

910
/**
@@ -17,36 +18,127 @@ class RequestEntityLoaderTest extends Test
1718
*/
1819
public function testUntyped()
1920
{
20-
$this->tester->amOnPage('/untyped/5');
21+
$this->tester->amOnPage('/untyped?parameter=5');
22+
}
23+
24+
public function testEntity()
25+
{
26+
$this->tester->amOnPage('/entity?parameter=5');
27+
$presenter = $this->tester->grabService(Application::class)->getPresenter();
28+
self::assertInstanceOf(Presenter::class, $presenter);
29+
$request = $presenter->getRequest();
30+
self::assertEquals(
31+
[
32+
'action' => 'entity',
33+
'parameter' => new Article(5),
34+
],
35+
$request->getParameters()
36+
);
2137
}
2238

2339
public function testInt()
2440
{
25-
$this->tester->amOnPage('/int/5');
26-
$request = $this->tester->grabService(Application::class)->getPresenter()->getRequest();
27-
$this->assertSame([
28-
'action' => 'int',
29-
'parameter' => 5,
30-
], $request->getParameters());
41+
$this->tester->amOnPage('/int?parameter=5');
42+
$presenter = $this->tester->grabService(Application::class)->getPresenter();
43+
self::assertInstanceOf(Presenter::class, $presenter);
44+
$request = $presenter->getRequest();
45+
self::assertSame(
46+
[
47+
'action' => 'int',
48+
'parameter' => 5,
49+
],
50+
$request->getParameters()
51+
);
3152
}
3253

3354
public function testIntWithDefault()
3455
{
3556
$this->tester->amOnPage('/int');
36-
$request = $this->tester->grabService(Application::class)->getPresenter()->getRequest();
37-
$this->assertSame([
38-
'action' => 'int',
39-
'parameter' => null,
40-
], $request->getParameters());
57+
$presenter = $this->tester->grabService(Application::class)->getPresenter();
58+
self::assertInstanceOf(Presenter::class, $presenter);
59+
$request = $presenter->getRequest();
60+
self::assertSame(
61+
[
62+
'action' => 'int',
63+
],
64+
$request->getParameters()
65+
);
4166
}
4267

43-
public function testEntity()
68+
/**
69+
* @expectedException Nette\Application\BadRequestException
70+
*/
71+
public function testIntError()
72+
{
73+
$this->tester->amOnPage('/int?parameter[]=0');
74+
}
75+
76+
public function testBool()
77+
{
78+
$this->tester->amOnPage('/bool?parameter=1');
79+
$presenter = $this->tester->grabService(Application::class)->getPresenter();
80+
self::assertInstanceOf(Presenter::class, $presenter);
81+
$request = $presenter->getRequest();
82+
self::assertSame(
83+
[
84+
'action' => 'bool',
85+
'parameter' => true,
86+
],
87+
$request->getParameters()
88+
);
89+
}
90+
91+
/**
92+
* @expectedException Nette\Application\BadRequestException
93+
*/
94+
public function testBoolError()
95+
{
96+
$this->tester->amOnPage('/bool?parameter[]=0');
97+
}
98+
99+
public function testFloat()
100+
{
101+
$this->tester->amOnPage('/float?parameter=1');
102+
$presenter = $this->tester->grabService(Application::class)->getPresenter();
103+
self::assertInstanceOf(Presenter::class, $presenter);
104+
$request = $presenter->getRequest();
105+
self::assertSame(
106+
[
107+
'action' => 'float',
108+
'parameter' => 1.0,
109+
],
110+
$request->getParameters()
111+
);
112+
}
113+
114+
/**
115+
* @expectedException Nette\Application\BadRequestException
116+
*/
117+
public function testFloatError()
118+
{
119+
$this->tester->amOnPage('/float?parameter[]=0');
120+
}
121+
122+
public function testString()
123+
{
124+
$this->tester->amOnPage('/string?parameter=1');
125+
$presenter = $this->tester->grabService(Application::class)->getPresenter();
126+
self::assertInstanceOf(Presenter::class, $presenter);
127+
$request = $presenter->getRequest();
128+
self::assertSame(
129+
[
130+
'action' => 'string',
131+
'parameter' => '1',
132+
],
133+
$request->getParameters()
134+
);
135+
}
136+
137+
/**
138+
* @expectedException Nette\Application\BadRequestException
139+
*/
140+
public function testStringError()
44141
{
45-
$this->tester->amOnPage('/entity/5');
46-
$request = $this->tester->grabService(Application::class)->getPresenter()->getRequest();
47-
$this->assertEquals([
48-
'action' => 'entity',
49-
'parameter' => new Article(5),
50-
], $request->getParameters());
142+
$this->tester->amOnPage('/string?parameter[]=0');
51143
}
52144
}

tests/functional/src/RequestEntityUnloaderTest.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,6 @@ public function testLink()
1515
{
1616
$this->tester->amOnPage('/default');
1717
$presenter = $this->tester->grabService(Application::class)->getPresenter();
18-
$this->assertSame('/entity/5', $presenter->link('Article:entity', new Article(5)));
18+
$this->assertSame('/entity?parameter=5', $presenter->link('Article:entity', new Article(5)));
1919
}
2020
}

0 commit comments

Comments
 (0)