From 53df486a06ac41d7215359af74fabacc5a02a9b5 Mon Sep 17 00:00:00 2001 From: Peter Knut Date: Sat, 21 Sep 2024 00:39:51 +0200 Subject: [PATCH] MySQL, PostgreSQL: Fix queries splitting and string constants Thanks to alxivnov (https://github.com/vrana/adminer/pull/490). --- adminer/drivers/mssql.inc.php | 4 ++++ adminer/drivers/mysql.inc.php | 10 ++++++++++ adminer/drivers/oracle.inc.php | 4 ++++ adminer/drivers/pgsql.inc.php | 11 +++++++++++ adminer/drivers/sqlite.inc.php | 4 ++++ adminer/sql.inc.php | 11 ++++++++++- 6 files changed, 43 insertions(+), 1 deletion(-) diff --git a/adminer/drivers/mssql.inc.php b/adminer/drivers/mssql.inc.php index 2a1ca1594..e2b9755c1 100644 --- a/adminer/drivers/mssql.inc.php +++ b/adminer/drivers/mssql.inc.php @@ -637,6 +637,10 @@ function is_strict_mode() { return false; } + function is_c_style_escapes() { + return true; + } + function show_status() { return array(); } diff --git a/adminer/drivers/mysql.inc.php b/adminer/drivers/mysql.inc.php index 744ac5b9b..3cce38881 100644 --- a/adminer/drivers/mysql.inc.php +++ b/adminer/drivers/mysql.inc.php @@ -1074,6 +1074,16 @@ function is_strict_mode() { return $strictMode; } + function is_c_style_escapes() { + static $c_style = null; + + if ($c_style === null) { + $c_style = strpos(get_key_vals("SHOW VARIABLES LIKE 'sql_mode'")["sql_mode"], 'NO_BACKSLASH_ESCAPES') === false; + } + + return $c_style; + } + /** Get process list * @return array ($row) */ diff --git a/adminer/drivers/oracle.inc.php b/adminer/drivers/oracle.inc.php index ba1cfa8bc..b8c2e830c 100644 --- a/adminer/drivers/oracle.inc.php +++ b/adminer/drivers/oracle.inc.php @@ -493,6 +493,10 @@ function is_strict_mode() { return false; } + function is_c_style_escapes() { + return true; + } + function process_list() { return get_rows('SELECT sess.process AS "process", sess.username AS "user", sess.schemaname AS "schema", sess.status AS "status", sess.wait_class AS "wait_class", sess.seconds_in_wait AS "seconds_in_wait", sql.sql_text AS "sql_text", sess.machine AS "machine", sess.port AS "port" FROM v$session sess LEFT OUTER JOIN v$sql sql diff --git a/adminer/drivers/pgsql.inc.php b/adminer/drivers/pgsql.inc.php index 5b67e4905..4f22d95a2 100644 --- a/adminer/drivers/pgsql.inc.php +++ b/adminer/drivers/pgsql.inc.php @@ -885,6 +885,16 @@ function is_strict_mode() { return false; } + function is_c_style_escapes() { + static $c_style = null; + + if ($c_style === null) { + $c_style = get_vals("SHOW standard_conforming_strings")[0] == "off"; + } + + return $c_style; + } + function process_list() { return get_rows("SELECT * FROM pg_stat_activity ORDER BY " . (min_version(9.2) ? "pid" : "procpid")); } @@ -949,6 +959,7 @@ function driver_config() { "char|text" => "||", ) ), + 'c_style_escapes' => true, ); } } diff --git a/adminer/drivers/sqlite.inc.php b/adminer/drivers/sqlite.inc.php index f80301af5..2f68bdefa 100644 --- a/adminer/drivers/sqlite.inc.php +++ b/adminer/drivers/sqlite.inc.php @@ -771,6 +771,10 @@ function is_strict_mode() { return false; } + function is_c_style_escapes() { + return true; + } + function show_status() { $return = array(); foreach (get_vals("PRAGMA compile_options") as $option) { diff --git a/adminer/sql.inc.php b/adminer/sql.inc.php index 526f8c065..edb892344 100644 --- a/adminer/sql.inc.php +++ b/adminer/sql.inc.php @@ -81,7 +81,16 @@ $offset = $pos + strlen($found); if ($found && rtrim($found) != $delimiter) { // find matching quote or comment end - while (preg_match('(' . ($found == '/*' ? '\*/' : ($found == '[' ? ']' : (preg_match('~^-- |^#~', $found) ? "\n" : preg_quote($found) . "|\\\\."))) . '|$)s', $query, $match, PREG_OFFSET_CAPTURE, $offset)) { //! respect sql_mode NO_BACKSLASH_ESCAPES + $c_style_escape = is_c_style_escapes() || ($jush == "pgsql" && ($pos > 0 && strtolower($query[$pos - 1]) == "e")); + + $pattern = '(' . + ($found == '/*' ? '\*/' : + ($found == '[' ? ']' : + (preg_match('~^-- |^#~', $found) ? "\n" : + (preg_quote($found) . ($c_style_escape ? "|\\\\." : ""))))) . + '|$)s'; + + while (preg_match($pattern, $query, $match, PREG_OFFSET_CAPTURE, $offset)) { $s = $match[0][0]; if (!$s && $fp && !feof($fp)) { $query .= fread($fp, 1e5);