diff --git a/src/Parser.php b/src/Parser.php index 62ec5559..0d8d46a5 100644 --- a/src/Parser.php +++ b/src/Parser.php @@ -134,6 +134,8 @@ private static function parseValue($value) case self::ESCAPE_STATE: if ($char === $value[0] || $char === '\\') { return [$data[0].$char, self::QUOTED_STATE]; + } elseif (in_array($char, ['f', 'n', 'r', 't', 'v'], true)) { + return [$data[0].stripcslashes('\\' . $char), self::QUOTED_STATE]; } else { throw new InvalidFileException( self::getErrorMessage('an unexpected escape sequence', $value) diff --git a/tests/Dotenv/DotenvTest.php b/tests/Dotenv/DotenvTest.php index 53eeb5d7..63184f4c 100644 --- a/tests/Dotenv/DotenvTest.php +++ b/tests/Dotenv/DotenvTest.php @@ -229,6 +229,9 @@ public function testMutlilineLoading() $dotenv = Dotenv::create($this->fixturesFolder, 'multiline.env'); $dotenv->load(); $this->assertSame("test\n test\"test\"\n test", getenv('TEST')); + $this->assertSame("test\ntest", getenv('TEST_ND')); + $this->assertSame("test\ntest", getenv('TEST_NS')); + $this->assertSame('https://vision.googleapis.com/v1/images:annotate?key=', getenv('TEST_EQD')); $this->assertSame('https://vision.googleapis.com/v1/images:annotate?key=', getenv('TEST_EQS')); } diff --git a/tests/Dotenv/LinesTest.php b/tests/Dotenv/LinesTest.php index 12a8e1fa..5a0fb349 100644 --- a/tests/Dotenv/LinesTest.php +++ b/tests/Dotenv/LinesTest.php @@ -30,6 +30,8 @@ public function testProcessQuotes() $expected = [ "TEST=\"test\n test\\\"test\\\"\n test\"", + "TEST_ND=\"test\\ntest\"", + 'TEST_NS=\'test\\ntest\'', 'TEST_EQD="https://vision.googleapis.com/v1/images:annotate?key="', 'TEST_EQS=\'https://vision.googleapis.com/v1/images:annotate?key=\'', ]; diff --git a/tests/Dotenv/ParserTest.php b/tests/Dotenv/ParserTest.php index d3a0ba03..2543b150 100644 --- a/tests/Dotenv/ParserTest.php +++ b/tests/Dotenv/ParserTest.php @@ -15,6 +15,35 @@ public function testQuotesParse() $this->assertSame(['FOO', "BAR \n"], Parser::parse("FOO=\"BAR \n\"")); } + public function testNewlineParse() + { + $this->assertSame(['FOO', "\n"], Parser::parse('FOO="\n"')); + } + + public function testTabParse() + { + $this->assertSame(['FOO', "\t"], Parser::parse('FOO=\'\t\'')); + } + + public function testNonEscapeParse1() + { + $this->assertSame(['FOO', '\n\v'], Parser::parse('FOO=\n\v')); + } + + public function testNonEscapeParse2() + { + $this->assertSame(['FOO', '\q'], Parser::parse('FOO=\q')); + } + + /** + * @expectedException \Dotenv\Exception\InvalidFileException + * @expectedExceptionMessage Failed to parse dotenv file due to an unexpected escape sequence. Failed at ["\q"]. + */ + public function testBadEscapeParse() + { + Parser::parse('FOO="\q"'); + } + public function testWhitespaceParse() { $this->assertSame(['FOO', "\n"], Parser::parse("FOO=\"\n\"")); @@ -62,19 +91,19 @@ public function testParseInvalidName() /** * @expectedException \Dotenv\Exception\InvalidFileException - * @expectedExceptionMessage Failed to parse dotenv file due to an unexpected escape sequence. Failed at ["iiiiviiiixiiiiviiii\n"]. + * @expectedExceptionMessage Failed to parse dotenv file due to an unexpected escape sequence. Failed at ["iiiiviiiixiiiiviiii\a"]. */ public function testParserEscapingDouble() { - Parser::parse('FOO_BAD="iiiiviiiixiiiiviiii\\n"'); + Parser::parse('FOO_BAD="iiiiviiiixiiiiviiii\\a"'); } /** * @expectedException \Dotenv\Exception\InvalidFileException - * @expectedExceptionMessage Failed to parse dotenv file due to an unexpected escape sequence. Failed at ['iiiiviiiixiiiiviiii\n']. + * @expectedExceptionMessage Failed to parse dotenv file due to an unexpected escape sequence. Failed at ['iiiiviiiixiiiiviiii\a']. */ public function testParserEscapingSingle() { - Parser::parse('FOO_BAD=\'iiiiviiiixiiiiviiii\\n\''); + Parser::parse('FOO_BAD=\'iiiiviiiixiiiiviiii\\a\''); } } diff --git a/tests/fixtures/env/multiline.env b/tests/fixtures/env/multiline.env index 4d95ac81..5ea54b09 100644 --- a/tests/fixtures/env/multiline.env +++ b/tests/fixtures/env/multiline.env @@ -2,5 +2,8 @@ TEST="test test\"test\" test" +TEST_ND="test\ntest" +TEST_NS='test\ntest' + TEST_EQD="https://vision.googleapis.com/v1/images:annotate?key=" TEST_EQS='https://vision.googleapis.com/v1/images:annotate?key='