diff --git a/src/Records/Record.php b/src/Records/Record.php index b131bc4..90990fa 100644 --- a/src/Records/Record.php +++ b/src/Records/Record.php @@ -78,11 +78,18 @@ public function __call(string $name, array $arguments) protected static function lineToArray(string $line, ?int $limit = null): array { - return explode( - ' ', - preg_replace('/\s+/', ' ', $line), - $limit - ); + // Match non-space characters, escaped quotes within quotes, or characters within quotes + preg_match_all('/(?:\\\\["]|[^"\\s]+|"[^"\\\\]*(?:\\\\.[^"\\\\]*)*")+/u', $line, $matches); + $parts = $matches[0]; + + // If a limit is defined, handle it manually because preg_match_all doesn't support limit + if ($limit !== null && count($parts) > $limit) { + $lastPart = implode(' ', array_slice($parts, $limit - 1)); + $parts = array_slice($parts, 0, $limit - 1); + $parts[] = $lastPart; + } + + return $parts; } protected function cast(string $attribute, $value) @@ -108,7 +115,11 @@ protected function prepareInt($value): int protected function prepareText(string $value): string { - return str_replace('" "', '', trim($value, '"')); + if (str_starts_with($value, '"') && str_ends_with($value, '"')) { + $value = substr($value, 1, -1); + } + + return str_replace('" "', '', $value); } protected function castHost(string $value): string diff --git a/tests/DnsTest.php b/tests/DnsTest.php index a1acc21..355b9f7 100644 --- a/tests/DnsTest.php +++ b/tests/DnsTest.php @@ -129,7 +129,7 @@ public function it_can_fetch_ptr_record() 'class' => 'IN', 'ttl' => 3600, 'type' => 'PTR', - 'target' => 'ae0.452.fra.as205948.creoline.net.', + 'target' => 'ae0.452.fra1.de.creoline.net.', ]); $this->assertSame( diff --git a/tests/Records/TXTTest.php b/tests/Records/TXTTest.php index 18f4ec7..8c462af 100644 --- a/tests/Records/TXTTest.php +++ b/tests/Records/TXTTest.php @@ -79,4 +79,26 @@ public function it_return_null_for_to_few_attributes() $this->assertNull($record); } + /** @test */ + public function it_can_parse_a_string_with_double_space() + { + $record = TXT::parse('spatie.be. 594 IN TXT "test 2 7"'); + + $this->assertSame('spatie.be', $record->host()); + $this->assertSame(594, $record->ttl()); + $this->assertSame('IN', $record->class()); + $this->assertSame('TXT', $record->type()); + $this->assertSame('test 2 7', $record->txt()); + } + /** @test */ + public function it_can_parse_a_string_with_a_double_quote() + { + $record = TXT::parse('spatie.be. 594 IN TXT "test \""'); + + $this->assertSame('spatie.be', $record->host()); + $this->assertSame(594, $record->ttl()); + $this->assertSame('IN', $record->class()); + $this->assertSame('TXT', $record->type()); + $this->assertSame('test \\"', $record->txt()); + } }