diff --git a/src/Solutions/MakeViewVariableOptionalSolution.php b/src/Solutions/MakeViewVariableOptionalSolution.php index 5e4164de..3a685d0b 100644 --- a/src/Solutions/MakeViewVariableOptionalSolution.php +++ b/src/Solutions/MakeViewVariableOptionalSolution.php @@ -4,6 +4,7 @@ use Facade\IgnitionContracts\RunnableSolution; use Illuminate\Support\Facades\Blade; +use Illuminate\Support\Str; class MakeViewVariableOptionalSolution implements RunnableSolution { @@ -70,8 +71,24 @@ public function run(array $parameters = []) } } + protected function isSafePath(string $path): bool + { + if (!Str::startsWith($path, ['/', './'])) { + return false; + } + if (!Str::endsWith($path, '.blade.php')) { + return false; + } + + return true; + } + public function makeOptional(array $parameters = []) { + if (!$this->isSafePath($parameters['viewFile'])) { + return false; + } + $originalContents = file_get_contents($parameters['viewFile']); $newContents = str_replace('$'.$parameters['variableName'], '$'.$parameters['variableName']." ?? ''", $originalContents); diff --git a/tests/Solutions/MakeViewVariableOptionalSolutionTest.php b/tests/Solutions/MakeViewVariableOptionalSolutionTest.php new file mode 100644 index 00000000..9c28023e --- /dev/null +++ b/tests/Solutions/MakeViewVariableOptionalSolutionTest.php @@ -0,0 +1,53 @@ +app->bind( + ComposerClassMap::class, + function () { + return new ComposerClassMap(__DIR__.'/../../vendor/autoload.php'); + } + ); + } + + /** @test */ + public function it_does_not_open_scheme_paths() + { + $solution = $this->getSolutionForPath('php://filter/resource=./tests/stubs/views/blade-exception.blade.php'); + $this->assertFalse($solution->isRunnable()); + } + + /** @test */ + public function it_does_open_relative_paths() + { + $solution = $this->getSolutionForPath('./tests/stubs/views/blade-exception.blade.php'); + $this->assertTrue($solution->isRunnable()); + } + + /** @test */ + public function it_does_not_open_other_extentions() + { + $solution = $this->getSolutionForPath('./tests/stubs/views/php-exception.php'); + $this->assertFalse($solution->isRunnable()); + } + + protected function getSolutionForPath($path): MakeViewVariableOptionalSolution + { + return new MakeViewVariableOptionalSolution('notSet', $path); + } +}