diff options
author | Andrey Andreev <narf@bofh.bg> | 2012-10-22 18:41:55 +0200 |
---|---|---|
committer | Andrey Andreev <narf@bofh.bg> | 2012-10-22 18:41:55 +0200 |
commit | 082aa4025ff5764cf10d429903bf48f66a65ce9e (patch) | |
tree | 864f5721407a4af994bf7c4243647860368c0fb8 /system/database | |
parent | e0874d247de8106c1a4e05ac3fd1645ae6be2045 (diff) |
Fix where() & having() escaping/prefixing literal values containing a period
Diffstat (limited to 'system/database')
-rw-r--r-- | system/database/DB_query_builder.php | 44 |
1 files changed, 40 insertions, 4 deletions
diff --git a/system/database/DB_query_builder.php b/system/database/DB_query_builder.php index 4f89d78d0..1ab165835 100644 --- a/system/database/DB_query_builder.php +++ b/system/database/DB_query_builder.php @@ -2067,7 +2067,7 @@ abstract class CI_DB_query_builder extends CI_DB_driver { for ($ci = 0, $cc = count($conditions); $ci < $cc; $ci++) { if (($op = $this->_get_operator($conditions[$ci])) === FALSE - OR ! preg_match('/^(\(?)(.*)('.preg_quote($op).')(.*(?<!\)))?(\)?)$/i', $conditions[$ci], $matches)) + OR ! preg_match('/^(\(?)(.*)('.preg_quote($op).')\s*(.*(?<!\)))?(\)?)$/i', $conditions[$ci], $matches)) { continue; } @@ -2080,7 +2080,13 @@ abstract class CI_DB_query_builder extends CI_DB_driver { // 4 => 'foo', /* optional, if $op is e.g. 'IS NULL' */ // 5 => ')' /* optional */ // ); - empty($matches[4]) OR $matches[4] = ' '.$this->protect_identifiers(trim($matches[4])); + + if ( ! empty($matches[4])) + { + $this->_is_literal($matches[4]) OR $matches[4] = $this->protect_identifiers(trim($matches[4])); + $matches[4] = ' '.$matches[4]; + } + $conditions[$ci] = $matches[1].$this->protect_identifiers(trim($matches[2])) .' '.trim($matches[3]).$matches[4].$matches[5]; } @@ -2114,7 +2120,7 @@ abstract class CI_DB_query_builder extends CI_DB_driver { { for ($i = 0, $c = count($this->qb_groupby); $i < $c; $i++) { - $this->qb_groupby[$i] = ($this->qb_groupby[$i]['escape'] === FALSE) + $this->qb_groupby[$i] = ($this->qb_groupby[$i]['escape'] === FALSE OR $this->_is_literal($this->qb_groupby[$i]['field'])) ? $this->qb_groupby[$i]['field'] : $this->protect_identifiers($this->qb_groupby[$i]['field']); } @@ -2146,7 +2152,7 @@ abstract class CI_DB_query_builder extends CI_DB_driver { for ($i = 0, $c = count($this->qb_orderby); $i < $c; $i++) { - if ($this->qb_orderby[$i]['escape'] !== FALSE) + if ($this->qb_orderby[$i]['escape'] !== FALSE && ! $this->_is_literal($this->qb_orderby[$i]['field'])) { $this->qb_orderby[$i]['field'] = $this->protect_identifiers($this->qb_orderby[$i]['field']); } @@ -2324,6 +2330,36 @@ abstract class CI_DB_query_builder extends CI_DB_driver { // -------------------------------------------------------------------- /** + * Is literal + * + * Determines if a string represents a literal value or a field name + * + * @param string + * @return bool + */ + protected function _is_literal($str) + { + $str = trim($str); + + if (empty($str)) + { + return TRUE; + } + + static $_str; + + if (empty($_str)) + { + $_str = ($this->_escape_char !== '"') + ? array('"', "'") : array("'"); + } + + return (ctype_digit($str) OR in_array($str[0], $_str, TRUE)); + } + + // -------------------------------------------------------------------- + + /** * Reset Query Builder values. * * Publicly-visible method to reset the QB values. |