From 34da698537c5360164ca14acc0a0e4640ee5441b Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Wed, 14 Sep 2022 16:01:45 +0200 Subject: [PATCH] FIX Import in upgrade when using a socialnetwork field. --- htdocs/core/db/Database.interface.php | 9 +++++++++ htdocs/core/db/mysqli.class.php | 12 ++++++++++++ htdocs/core/db/pgsql.class.php | 14 +++++++++++++- htdocs/core/db/sqlite3.class.php | 14 +++++++++++++- htdocs/core/lib/website.lib.php | 6 +++--- htdocs/core/modules/import/import_csv.modules.php | 12 ++++++++---- htdocs/core/modules/import/import_xlsx.modules.php | 8 ++++++-- htdocs/debugbar/class/TraceableDB.php | 12 ++++++++++++ 8 files changed, 76 insertions(+), 11 deletions(-) diff --git a/htdocs/core/db/Database.interface.php b/htdocs/core/db/Database.interface.php index 1d24b058614..faff7ff5172 100644 --- a/htdocs/core/db/Database.interface.php +++ b/htdocs/core/db/Database.interface.php @@ -182,9 +182,18 @@ interface Database * * @param string $stringtoencode String to escape * @return string String escaped + * @deprecated */ public function escapeunderscore($stringtoencode); + /** + * Escape a string to insert data into a like + * + * @param string $stringtoencode String to escape + * @return string String escaped + */ + public function escapeforlike($stringtoencode); + /** * Sanitize a string for SQL forging * diff --git a/htdocs/core/db/mysqli.class.php b/htdocs/core/db/mysqli.class.php index 29c2d30df2f..f2c5f9f3a03 100644 --- a/htdocs/core/db/mysqli.class.php +++ b/htdocs/core/db/mysqli.class.php @@ -479,12 +479,24 @@ class DoliDBMysqli extends DoliDB * * @param string $stringtoencode String to escape * @return string String escaped + * @deprecated */ public function escapeunderscore($stringtoencode) { return str_replace('_', '\_', (string) $stringtoencode); } + /** + * Escape a string to insert data into a like + * + * @param string $stringtoencode String to escape + * @return string String escaped + */ + public function escapeforlike($stringtoencode) + { + return str_replace(array('_', '\\', '%'), array('\_', '\\\\', '\%'), (string) $stringtoencode); + } + /** * Return generic error code of last operation. * diff --git a/htdocs/core/db/pgsql.class.php b/htdocs/core/db/pgsql.class.php index fe3269867a9..e259933cd07 100644 --- a/htdocs/core/db/pgsql.class.php +++ b/htdocs/core/db/pgsql.class.php @@ -726,10 +726,22 @@ class DoliDBPgsql extends DoliDB * * @param string $stringtoencode String to escape * @return string String escaped + * @deprecated */ public function escapeunderscore($stringtoencode) { - return str_replace('_', '\_', $stringtoencode); + return str_replace('_', '\_', (string) $stringtoencode); + } + + /** + * Escape a string to insert data into a like + * + * @param string $stringtoencode String to escape + * @return string String escaped + */ + public function escapeforlike($stringtoencode) + { + return str_replace(array('_', '\\', '%'), array('\_', '\\\\', '\%'), (string) $stringtoencode); } /** diff --git a/htdocs/core/db/sqlite3.class.php b/htdocs/core/db/sqlite3.class.php index 8d0141e8ca6..e31eeffe457 100644 --- a/htdocs/core/db/sqlite3.class.php +++ b/htdocs/core/db/sqlite3.class.php @@ -654,10 +654,22 @@ class DoliDBSqlite3 extends DoliDB * * @param string $stringtoencode String to escape * @return string String escaped + * @deprecated */ public function escapeunderscore($stringtoencode) { - return str_replace('_', '\_', $stringtoencode); + return str_replace('_', '\_', (string) $stringtoencode); + } + + /** + * Escape a string to insert data into a like + * + * @param string $stringtoencode String to escape + * @return string String escaped + */ + public function escapeforlike($stringtoencode) + { + return str_replace(array('_', '\\', '%'), array('\_', '\\\\', '\%'), (string) $stringtoencode); } /** diff --git a/htdocs/core/lib/website.lib.php b/htdocs/core/lib/website.lib.php index e9de957e4a8..e9ea4dbcf09 100644 --- a/htdocs/core/lib/website.lib.php +++ b/htdocs/core/lib/website.lib.php @@ -947,11 +947,11 @@ function getPagesFromSearchCriterias($type, $algo, $searchstring, $max = 25, $so $sql .= " AND ("; $searchalgo = ''; if (preg_match('/meta/', $algo)) { - $searchalgo .= ($searchalgo ? ' OR ' : '')."wp.title LIKE '%".$db->escapeunderscore($db->escape($searchstring))."%' OR wp.description LIKE '%".$db->escapeunderscore($db->escape($searchstring))."%'"; - $searchalgo .= ($searchalgo ? ' OR ' : '')."wp.keywords LIKE '".$db->escapeunderscore($db->escape($searchstring)).",%' OR wp.keywords LIKE '% ".$db->escapeunderscore($db->escape($searchstring))."%'"; // TODO Use a better way to scan keywords + $searchalgo .= ($searchalgo ? ' OR ' : '')."wp.title LIKE '%".$db->escapeforlike($db->escape($searchstring))."%' OR wp.description LIKE '%".$db->escapeforlike($db->escape($searchstring))."%'"; + $searchalgo .= ($searchalgo ? ' OR ' : '')."wp.keywords LIKE '".$db->escapeforlike($db->escape($searchstring)).",%' OR wp.keywords LIKE '% ".$db->escapeforlike($db->escape($searchstring))."%'"; // TODO Use a better way to scan keywords } if (preg_match('/content/', $algo)) { - $searchalgo .= ($searchalgo ? ' OR ' : '')."wp.content LIKE '%".$db->escapeunderscore($db->escape($searchstring))."%'"; + $searchalgo .= ($searchalgo ? ' OR ' : '')."wp.content LIKE '%".$db->escapeforlike($db->escape($searchstring))."%'"; } $sql .= $searchalgo; if (is_array($otherfilters) && !empty($otherfilters['category'])) { diff --git a/htdocs/core/modules/import/import_csv.modules.php b/htdocs/core/modules/import/import_csv.modules.php index 32284a2cbd1..0bea7d1d739 100644 --- a/htdocs/core/modules/import/import_csv.modules.php +++ b/htdocs/core/modules/import/import_csv.modules.php @@ -835,8 +835,8 @@ class ImportCsv extends ModeleImports $sqlSelect = "SELECT ".$fname." FROM ".$tablename; $data = array_combine($listfields, $listvalues); - $where = array(); - $filters = array(); + $where = array(); // filters to forge SQL request + $filters = array(); // filters to forge output error message foreach ($updatekeys as $key) { $col = $objimport->array_import_updatekeys[0][$key]; $key = preg_replace('/^.*\./i', '', $key); @@ -846,8 +846,12 @@ class ImportCsv extends ModeleImports $socialnetwork = $tmp[1]; $jsondata = $data[$key]; $json = json_decode($jsondata); - $where[] = $key." LIKE '%\"".$socialnetwork."\":\"".$this->db->escape($json->$socialnetwork)."\"%'"; - $filters[] = $col." LIKE '%\"".$socialnetwork."\":\"".$this->db->escape($json->$socialnetwork)."\"%'"; + $stringtosearch = json_encode($socialnetwork).':'.json_encode($json->$socialnetwork); + //var_dump($stringtosearch); + //var_dump($this->db->escape($stringtosearch)); // This provide a value for sql string (but not for a like) + $where[] = $key." LIKE '%".$this->db->escapeforlike($this->db->escape($stringtosearch))."%'"; + $filters[] = $col." LIKE '%".$this->db->escapeforlike($this->db->escape($stringtosearch))."%'"; + //var_dump($where[1]); // This provide a value for sql string inside a like } else { $where[] = $key.' = '.$data[$key]; $filters[] = $col.' = '.$data[$key]; diff --git a/htdocs/core/modules/import/import_xlsx.modules.php b/htdocs/core/modules/import/import_xlsx.modules.php index d8a9d77a98e..8652f106ca2 100644 --- a/htdocs/core/modules/import/import_xlsx.modules.php +++ b/htdocs/core/modules/import/import_xlsx.modules.php @@ -891,8 +891,12 @@ class ImportXlsx extends ModeleImports $socialnetwork = $tmp[1]; $jsondata = $data[$key]; $json = json_decode($jsondata); - $where[] = $key." LIKE '%\"".$socialnetwork."\":\"".$this->db->escape($json->$socialnetwork)."\"%'"; - $filters[] = $col." LIKE '%\"".$socialnetwork."\":\"".$this->db->escape($json->$socialnetwork)."\"%'"; + $stringtosearch = json_encode($socialnetwork).':'.json_encode($json->$socialnetwork); + //var_dump($stringtosearch); + //var_dump($this->db->escape($stringtosearch)); // This provide a value for sql string (but not for a like) + $where[] = $key." LIKE '%".$this->db->escapeforlike($this->db->escape($stringtosearch))."%'"; + $filters[] = $col." LIKE '%".$this->db->escapeforlike($this->db->escape($stringtosearch))."%'"; + //var_dump($where[1]); // This provide a value for sql string inside a like } else { $where[] = $key.' = '.$data[$key]; $filters[] = $col.' = '.$data[$key]; diff --git a/htdocs/debugbar/class/TraceableDB.php b/htdocs/debugbar/class/TraceableDB.php index 082e45e4f43..785af37fc94 100644 --- a/htdocs/debugbar/class/TraceableDB.php +++ b/htdocs/debugbar/class/TraceableDB.php @@ -255,12 +255,24 @@ class TraceableDB extends DoliDB * * @param string $stringtoencode String to escape * @return string String escaped + * @deprecated */ public function escapeunderscore($stringtoencode) { return $this->db->escapeunderscore($stringtoencode); } + /** + * Escape a string to insert data into a like + * + * @param string $stringtoencode String to escape + * @return string String escaped + */ + public function escapeforlike($stringtoencode) + { + return str_replace(array('_', '\\', '%'), array('\_', '\\\\', '\%'), (string) $stringtoencode); + } + // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps /** * Get last ID after an insert INSERT