Skip to content

Commit c5f7327

Browse files
fix(#351): remove invalid or non-PostgreSQL-compliant test cases; ensure edge cases for backslashes, quotes, special characters, and NULL handling are covered (#385)
1 parent 05a0afe commit c5f7327

File tree

2 files changed

+35
-27
lines changed

2 files changed

+35
-27
lines changed

src/MartinGeorgiev/Utils/PostgresArrayToPHPArrayTransformer.php

Lines changed: 14 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -218,44 +218,32 @@ private static function unescapeString(string $value): string
218218
$result = '';
219219
$len = \strlen($value);
220220
$i = 0;
221-
$backslashCount = 0;
222-
223221
while ($i < $len) {
224222
if ($value[$i] === '\\') {
225-
$backslashCount++;
226-
$i++;
227-
228-
continue;
229-
}
223+
$start = $i;
224+
while ($i < $len && $value[$i] === '\\') {
225+
$i++;
226+
}
230227

231-
if ($backslashCount > 0) {
232-
if ($value[$i] === '"') {
233-
// This is an escaped quote
234-
$result .= \str_repeat('\\', (int) ($backslashCount / 2));
235-
if ($backslashCount % 2 === 1) {
236-
$result .= '"';
237-
} else {
238-
$result .= '\"';
228+
$slashCount = $i - $start;
229+
$nextChar = $i < $len ? $value[$i] : '';
230+
if ($nextChar === '"' || $nextChar === '\\') {
231+
$result .= \str_repeat('\\', \intdiv($slashCount, 2));
232+
if ($slashCount % 2 === 1) {
233+
$result .= $nextChar;
234+
$i++;
239235
}
240236
} else {
241-
// These are literal backslashes
242-
$result .= \str_repeat('\\', $backslashCount);
243-
$result .= $value[$i];
237+
$result .= \str_repeat('\\', $slashCount);
244238
}
245239

246-
$backslashCount = 0;
247-
} else {
248-
$result .= $value[$i];
240+
continue;
249241
}
250242

243+
$result .= $value[$i];
251244
$i++;
252245
}
253246

254-
// Handle any trailing backslashes
255-
if ($backslashCount > 0) {
256-
$result .= \str_repeat('\\', $backslashCount);
257-
}
258-
259247
return $result;
260248
}
261249
}

tests/Unit/MartinGeorgiev/Utils/PostgresArrayToPHPArrayTransformerTest.php

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -142,6 +142,26 @@ public static function provideValidTransformations(): array
142142
'phpValue' => ['', ''],
143143
'postgresValue' => '{"",""}',
144144
],
145+
'github #351 regression: string with special characters and backslash' => [
146+
'phpValue' => ["!@#\\$%^&*()_+=-}{[]|\":;'\\?><,./"],
147+
'postgresValue' => '{"!@#\$%^&*()_+=-}{[]|\":;\'\?><,./"}',
148+
],
149+
'backslash before backslash' => [
150+
'phpValue' => ['a\b'],
151+
'postgresValue' => '{"a\\\b"}', // a\\b
152+
],
153+
'single backslash before non-escape char' => [
154+
'phpValue' => ['a\$b'],
155+
'postgresValue' => '{"a\$b"}', // a\$b
156+
],
157+
'element with curly braces and comma' => [
158+
'phpValue' => ['{foo,bar}'],
159+
'postgresValue' => '{"{foo,bar}"}',
160+
],
161+
'element with whitespace' => [
162+
'phpValue' => [' foo '],
163+
'postgresValue' => '{" foo "}',
164+
],
145165
];
146166
}
147167

@@ -198,7 +218,7 @@ public static function provideManualParsingArrays(): array
198218
public function can_transform_escaped_quotes_with_backslashes(): void
199219
{
200220
$postgresArray = '{"\\\"quoted\\\""}';
201-
self::assertSame(['\\\"quoted\\\"'], PostgresArrayToPHPArrayTransformer::transformPostgresArrayToPHPArray($postgresArray));
221+
self::assertSame(['\"quoted\"'], PostgresArrayToPHPArrayTransformer::transformPostgresArrayToPHPArray($postgresArray));
202222
}
203223

204224
#[Test]

0 commit comments

Comments
 (0)