diff --git a/src/Illuminate/Database/Query/Builder.php b/src/Illuminate/Database/Query/Builder.php index 4152b1bb57e9..1be0d07795c6 100755 --- a/src/Illuminate/Database/Query/Builder.php +++ b/src/Illuminate/Database/Query/Builder.php @@ -1517,6 +1517,13 @@ public function whereDate($column, $operator, $value = null, $boolean = 'and') $value, $operator, func_num_args() === 2 ); + // If the given operator is not found in the list of valid operators we will + // assume that the developer is just short-cutting the '=' operators and + // we will set the operators to '=' and set the values appropriately. + if ($this->invalidOperator($operator)) { + [$value, $operator] = [$operator, '=']; + } + $value = $this->flattenValue($value); if ($value instanceof DateTimeInterface) { @@ -1558,6 +1565,13 @@ public function whereTime($column, $operator, $value = null, $boolean = 'and') $value, $operator, func_num_args() === 2 ); + // If the given operator is not found in the list of valid operators we will + // assume that the developer is just short-cutting the '=' operators and + // we will set the operators to '=' and set the values appropriately. + if ($this->invalidOperator($operator)) { + [$value, $operator] = [$operator, '=']; + } + $value = $this->flattenValue($value); if ($value instanceof DateTimeInterface) { @@ -1599,6 +1613,13 @@ public function whereDay($column, $operator, $value = null, $boolean = 'and') $value, $operator, func_num_args() === 2 ); + // If the given operator is not found in the list of valid operators we will + // assume that the developer is just short-cutting the '=' operators and + // we will set the operators to '=' and set the values appropriately. + if ($this->invalidOperator($operator)) { + [$value, $operator] = [$operator, '=']; + } + $value = $this->flattenValue($value); if ($value instanceof DateTimeInterface) { @@ -1644,6 +1665,13 @@ public function whereMonth($column, $operator, $value = null, $boolean = 'and') $value, $operator, func_num_args() === 2 ); + // If the given operator is not found in the list of valid operators we will + // assume that the developer is just short-cutting the '=' operators and + // we will set the operators to '=' and set the values appropriately. + if ($this->invalidOperator($operator)) { + [$value, $operator] = [$operator, '=']; + } + $value = $this->flattenValue($value); if ($value instanceof DateTimeInterface) { @@ -1689,6 +1717,13 @@ public function whereYear($column, $operator, $value = null, $boolean = 'and') $value, $operator, func_num_args() === 2 ); + // If the given operator is not found in the list of valid operators we will + // assume that the developer is just short-cutting the '=' operators and + // we will set the operators to '=' and set the values appropriately. + if ($this->invalidOperator($operator)) { + [$value, $operator] = [$operator, '=']; + } + $value = $this->flattenValue($value); if ($value instanceof DateTimeInterface) { @@ -2114,6 +2149,13 @@ public function whereJsonLength($column, $operator, $value = null, $boolean = 'a $value, $operator, func_num_args() === 2 ); + // If the given operator is not found in the list of valid operators we will + // assume that the developer is just short-cutting the '=' operators and + // we will set the operators to '=' and set the values appropriately. + if ($this->invalidOperator($operator)) { + [$value, $operator] = [$operator, '=']; + } + $this->wheres[] = compact('type', 'column', 'operator', 'value', 'boolean'); if (! $value instanceof ExpressionContract) { diff --git a/src/Illuminate/Foundation/EnvironmentDetector.php b/src/Illuminate/Foundation/EnvironmentDetector.php index b2747bc6800e..8fa61bd2e983 100644 --- a/src/Illuminate/Foundation/EnvironmentDetector.php +++ b/src/Illuminate/Foundation/EnvironmentDetector.php @@ -65,7 +65,7 @@ protected function getEnvironmentArgument(array $args) return $args[$i + 1] ?? null; } - if (str_starts_with($value, '--env')) { + if (str_starts_with($value, '--env=')) { return head(array_slice(explode('=', $value), 1)); } } diff --git a/tests/Foundation/FoundationEnvironmentDetectorTest.php b/tests/Foundation/FoundationEnvironmentDetectorTest.php index d302c375bf50..c06a8ac386dd 100644 --- a/tests/Foundation/FoundationEnvironmentDetectorTest.php +++ b/tests/Foundation/FoundationEnvironmentDetectorTest.php @@ -46,4 +46,34 @@ public function testConsoleEnvironmentDetectionWithNoValue() }, ['--env']); $this->assertSame('foobar', $result); } + + public function testConsoleEnvironmentDetectionDoesNotUseArgumentThatStartsWithEnv() + { + $env = new EnvironmentDetector; + + $result = $env->detect(function () { + return 'foobar'; + }, ['--envelope=mail']); + $this->assertSame('foobar', $result); + } + + public function testConsoleEnvironmentDetectionDoesNotUseArgumentThatStartsWithEnvSeparatedWithSpace() + { + $env = new EnvironmentDetector; + + $result = $env->detect(function () { + return 'foobar'; + }, ['--envelope', 'mail']); + $this->assertSame('foobar', $result); + } + + public function testConsoleEnvironmentDetectionDoesNotUseArgumentThatStartsWithEnvWithNoValue() + { + $env = new EnvironmentDetector; + + $result = $env->detect(function () { + return 'foobar'; + }, ['--envelope']); + $this->assertSame('foobar', $result); + } } diff --git a/tests/Integration/Database/QueryBuilderTest.php b/tests/Integration/Database/QueryBuilderTest.php index 98ae0792b212..c323ff0e1513 100644 --- a/tests/Integration/Database/QueryBuilderTest.php +++ b/tests/Integration/Database/QueryBuilderTest.php @@ -9,6 +9,9 @@ use Illuminate\Support\Carbon; use Illuminate\Support\Facades\DB; use Illuminate\Support\Facades\Schema; +use Illuminate\Testing\Assert as PHPUnit; +use Orchestra\Testbench\Attributes\DefineEnvironment; +use PDOException; class QueryBuilderTest extends DatabaseTestCase { @@ -305,12 +308,52 @@ public function testWhereDate() $this->assertSame(1, DB::table('posts')->whereDate('created_at', new Carbon('2018-01-02'))->count()); } + #[DefineEnvironment('defineEnvironmentWouldThrowsPDOException')] + public function testWhereDateWithInvalidOperator() + { + $sql = DB::table('posts')->whereDate('created_at', '? OR 1=1', '2018-01-02'); + + PHPUnit::assertArraySubset([ + [ + 'column' => 'created_at', + 'type' => 'Date', + 'value' => '? OR 1=1', + 'boolean' => 'and', + ], + ], $sql->wheres); + + $this->assertSame(0, $sql->count()); + } + public function testOrWhereDate() { $this->assertSame(2, DB::table('posts')->where('id', 1)->orWhereDate('created_at', '2018-01-02')->count()); $this->assertSame(2, DB::table('posts')->where('id', 1)->orWhereDate('created_at', new Carbon('2018-01-02'))->count()); } + #[DefineEnvironment('defineEnvironmentWouldThrowsPDOException')] + public function testOrWhereDateWithInvalidOperator() + { + $sql = DB::table('posts')->where('id', 1)->orWhereDate('created_at', '? OR 1=1', '2018-01-02'); + + PHPUnit::assertArraySubset([ + [ + 'column' => 'id', + 'type' => 'Basic', + 'value' => 1, + 'boolean' => 'and', + ], + [ + 'column' => 'created_at', + 'type' => 'Date', + 'value' => '? OR 1=1', + 'boolean' => 'or', + ], + ], $sql->wheres); + + $this->assertSame(1, $sql->count()); + } + public function testWhereDay() { $this->assertSame(1, DB::table('posts')->whereDay('created_at', '02')->count()); @@ -318,6 +361,22 @@ public function testWhereDay() $this->assertSame(1, DB::table('posts')->whereDay('created_at', new Carbon('2018-01-02'))->count()); } + public function testWhereDayWithInvalidOperator() + { + $sql = DB::table('posts')->whereDay('created_at', '? OR 1=1', '02'); + + PHPUnit::assertArraySubset([ + [ + 'column' => 'created_at', + 'type' => 'Day', + 'value' => '00', + 'boolean' => 'and', + ], + ], $sql->wheres); + + $this->assertSame(0, $sql->count()); + } + public function testOrWhereDay() { $this->assertSame(2, DB::table('posts')->where('id', 1)->orWhereDay('created_at', '02')->count()); @@ -325,6 +384,28 @@ public function testOrWhereDay() $this->assertSame(2, DB::table('posts')->where('id', 1)->orWhereDay('created_at', new Carbon('2018-01-02'))->count()); } + public function testOrWhereDayWithInvalidOperator() + { + $sql = DB::table('posts')->where('id', 1)->orWhereDay('created_at', '? OR 1=1', '02'); + + PHPUnit::assertArraySubset([ + [ + 'column' => 'id', + 'type' => 'Basic', + 'value' => 1, + 'boolean' => 'and', + ], + [ + 'column' => 'created_at', + 'type' => 'Day', + 'value' => '00', + 'boolean' => 'or', + ], + ], $sql->wheres); + + $this->assertSame(1, $sql->count()); + } + public function testWhereMonth() { $this->assertSame(1, DB::table('posts')->whereMonth('created_at', '01')->count()); @@ -332,6 +413,22 @@ public function testWhereMonth() $this->assertSame(1, DB::table('posts')->whereMonth('created_at', new Carbon('2018-01-02'))->count()); } + public function testWhereMonthWithInvalidOperator() + { + $sql = DB::table('posts')->whereMonth('created_at', '? OR 1=1', '01'); + + PHPUnit::assertArraySubset([ + [ + 'column' => 'created_at', + 'type' => 'Month', + 'value' => '00', + 'boolean' => 'and', + ], + ], $sql->wheres); + + $this->assertSame(0, $sql->count()); + } + public function testOrWhereMonth() { $this->assertSame(2, DB::table('posts')->where('id', 1)->orWhereMonth('created_at', '01')->count()); @@ -339,6 +436,28 @@ public function testOrWhereMonth() $this->assertSame(2, DB::table('posts')->where('id', 1)->orWhereMonth('created_at', new Carbon('2018-01-02'))->count()); } + public function testOrWhereMonthWithInvalidOperator() + { + $sql = DB::table('posts')->where('id', 1)->orWhereMonth('created_at', '? OR 1=1', '01'); + + PHPUnit::assertArraySubset([ + [ + 'column' => 'id', + 'type' => 'Basic', + 'value' => 1, + 'boolean' => 'and', + ], + [ + 'column' => 'created_at', + 'type' => 'Month', + 'value' => '00', + 'boolean' => 'or', + ], + ], $sql->wheres); + + $this->assertSame(1, $sql->count()); + } + public function testWhereYear() { $this->assertSame(1, DB::table('posts')->whereYear('created_at', '2018')->count()); @@ -346,6 +465,23 @@ public function testWhereYear() $this->assertSame(1, DB::table('posts')->whereYear('created_at', new Carbon('2018-01-02'))->count()); } + #[DefineEnvironment('defineEnvironmentWouldThrowsPDOException')] + public function testWhereYearWithInvalidOperator() + { + $sql = DB::table('posts')->whereYear('created_at', '? OR 1=1', '2018'); + + PHPUnit::assertArraySubset([ + [ + 'column' => 'created_at', + 'type' => 'Year', + 'value' => '? OR 1=1', + 'boolean' => 'and', + ], + ], $sql->wheres); + + $this->assertSame(0, $sql->count()); + } + public function testOrWhereYear() { $this->assertSame(2, DB::table('posts')->where('id', 1)->orWhereYear('created_at', '2018')->count()); @@ -353,18 +489,81 @@ public function testOrWhereYear() $this->assertSame(2, DB::table('posts')->where('id', 1)->orWhereYear('created_at', new Carbon('2018-01-02'))->count()); } + #[DefineEnvironment('defineEnvironmentWouldThrowsPDOException')] + public function testOrWhereYearWithInvalidOperator() + { + $sql = DB::table('posts')->where('id', 1)->orWhereYear('created_at', '? OR 1=1', '2018'); + + PHPUnit::assertArraySubset([ + [ + 'column' => 'id', + 'type' => 'Basic', + 'value' => 1, + 'boolean' => 'and', + ], + [ + 'column' => 'created_at', + 'type' => 'Year', + 'value' => '? OR 1=1', + 'boolean' => 'or', + ], + ], $sql->wheres); + + $this->assertSame(1, $sql->count()); + } + public function testWhereTime() { $this->assertSame(1, DB::table('posts')->whereTime('created_at', '03:04:05')->count()); $this->assertSame(1, DB::table('posts')->whereTime('created_at', new Carbon('2018-01-02 03:04:05'))->count()); } + #[DefineEnvironment('defineEnvironmentWouldThrowsPDOException')] + public function testWhereTimeWithInvalidOperator() + { + $sql = DB::table('posts')->whereTime('created_at', '? OR 1=1', '03:04:05'); + + PHPUnit::assertArraySubset([ + [ + 'column' => 'created_at', + 'type' => 'Time', + 'value' => '? OR 1=1', + 'boolean' => 'and', + ], + ], $sql->wheres); + + $this->assertSame(0, $sql->count()); + } + public function testOrWhereTime() { $this->assertSame(2, DB::table('posts')->where('id', 1)->orWhereTime('created_at', '03:04:05')->count()); $this->assertSame(2, DB::table('posts')->where('id', 1)->orWhereTime('created_at', new Carbon('2018-01-02 03:04:05'))->count()); } + #[DefineEnvironment('defineEnvironmentWouldThrowsPDOException')] + public function testOrWhereTimeWithInvalidOperator() + { + $sql = DB::table('posts')->where('id', 1)->orWhereTime('created_at', '? OR 1=1', '03:04:05'); + + PHPUnit::assertArraySubset([ + [ + 'column' => 'id', + 'type' => 'Basic', + 'value' => 1, + 'boolean' => 'and', + ], + [ + 'column' => 'created_at', + 'type' => 'Time', + 'value' => '? OR 1=1', + 'boolean' => 'or', + ], + ], $sql->wheres); + + $this->assertSame(1, $sql->count()); + } + public function testWhereNested() { $results = DB::table('posts')->where('content', 'Lorem Ipsum.')->whereNested(function ($query) { @@ -436,4 +635,13 @@ public function testPluck() 'Lorem Ipsum.' => 'Bar Post', ], DB::table('posts')->pluck('title', 'content')->toArray()); } + + protected function defineEnvironmentWouldThrowsPDOException($app) + { + $this->afterApplicationCreated(function () { + if (in_array($this->driver, ['pgsql', 'sqlsrv'])) { + $this->expectException(PDOException::class); + } + }); + } }