Fix regex for $$ PostgresSQL string in convert placeholder

This commit is contained in:
Clemens Schwaighofer
2025-04-07 19:44:18 +09:00
parent 2d30d1d160
commit 37367db878
2 changed files with 37 additions and 1 deletions

View File

@@ -135,6 +135,7 @@ final class CoreLibsDBIOTest extends TestCase
}
// check if they already exist, drop them
if ($db->dbShowTableMetaData('table_with_primary_key') !== false) {
$db->dbExec("CREATE EXTENSION IF NOT EXISTS pgcrypto");
$db->dbExec("DROP TABLE table_with_primary_key");
$db->dbExec("DROP TABLE table_without_primary_key");
$db->dbExec("DROP TABLE test_meta");
@@ -5309,6 +5310,38 @@ final class CoreLibsDBIOTest extends TestCase
'count' => 2,
'convert' => false,
],
// special $$ string case
'text string, with $ placehoders that could be seen as $$ string' => [
'query' => <<<SQL
SELECT row_int
FROM table_with_primary_key
WHERE
row_bytea = digest($3::VARCHAR, $4) OR
row_varchar = encode(digest($3, $4), 'hex') OR
row_bytea = hmac($3, $5, $4) OR
row_varchar = encode(hmac($3, $5, $4), 'hex') OR
row_bytea = pgp_sym_encrypt($3, $6) OR
row_varchar = encode(pgp_sym_encrypt($1, $6), 'hex') OR
row_varchar = CASE WHEN row_int = 1 THEN $1 ELSE $2 END
SQL,
'count' => 6,
'convert' => false,
],
// NOTE, in SQL heredoc we cannot write $$ strings parts
'text string, with $ placehoders are in $$ strings' => [
'query' => '
SELECT row_int
FROM table_with_primary_key
WHERE
row_varchar = $$some string$$ OR
row_varchar = $tag$some string$tag$ OR
row_varchar = $btag$some $1 string$btag$ OR
row_varchar = $btag$some $1 $subtag$ something $subtag$string$btag$ OR
row_varchar = $1
',
'count' => 1,
'convert' => false,
],
// a text string with escaped quite
'text string, with escaped quote' => [
'query' => <<<SQL
@@ -5324,6 +5357,9 @@ final class CoreLibsDBIOTest extends TestCase
'convert' => false,
]
];
$string = <<<SQL
'''
SQL;
}
/**

View File

@@ -21,7 +21,7 @@ class ConvertPlaceholder
/** @var string text block in SQL, dollar quoted
* NOTE: if this is added everything shifts by one lookup number
*/
private const PATTERN_TEXT_BLOCK_DOLLAR = '(?:\$([^$]*)\$.*?\$\1\$)';
private const PATTERN_TEXT_BLOCK_DOLLAR = '(?:\$(\w*)\$.*?\$\1\$)';
/** @var string comment regex
* anything that starts with -- and ends with a line break but any character that is not line break inbetween
* this is the FIRST thing in the line and will skip any further lookups */