summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAndrey Andreev <narf@bofh.bg>2012-07-08 21:43:22 +0200
committerAndrey Andreev <narf@bofh.bg>2012-07-08 21:43:22 +0200
commitadedaf05449112a5ede4a3bc722a9a153b4aa2a3 (patch)
treed9e6a538e140b5076a926151bbe261a960e84417
parentbd6116a63899c5efcf35e175b3db14b1f05c60a9 (diff)
parent0db81b6c82c2f86a6e9da26ab5501ba65cb4c4e1 (diff)
Merge branch 'develop' of github.com:EllisLab/CodeIgniter into feature/db_subdrivers
-rw-r--r--system/database/DB_driver.php6
-rw-r--r--system/database/DB_query_builder.php10
-rw-r--r--system/database/DB_result.php24
-rw-r--r--system/database/drivers/cubrid/cubrid_result.php5
-rw-r--r--system/database/drivers/ibase/ibase_result.php18
-rw-r--r--system/database/drivers/mssql/mssql_result.php20
-rw-r--r--system/database/drivers/mysql/mysql_result.php5
-rw-r--r--system/database/drivers/mysqli/mysqli_result.php5
-rw-r--r--system/database/drivers/oci8/oci8_result.php21
-rw-r--r--system/database/drivers/odbc/odbc_result.php18
-rw-r--r--system/database/drivers/pdo/pdo_result.php5
-rw-r--r--system/database/drivers/postgre/postgre_result.php5
-rw-r--r--system/database/drivers/sqlite/sqlite_result.php11
-rw-r--r--system/database/drivers/sqlite3/sqlite3_result.php29
-rw-r--r--system/database/drivers/sqlsrv/sqlsrv_result.php5
-rw-r--r--system/libraries/Form_validation.php6
-rw-r--r--tests/codeigniter/database/query_builder/join_test.php20
-rw-r--r--user_guide_src/source/changelog.rst2
-rw-r--r--user_guide_src/source/helpers/form_helper.rst4
19 files changed, 164 insertions, 55 deletions
diff --git a/system/database/DB_driver.php b/system/database/DB_driver.php
index eca2e68a7..e9efc8914 100644
--- a/system/database/DB_driver.php
+++ b/system/database/DB_driver.php
@@ -971,7 +971,7 @@ abstract class CI_DB_driver {
*/
public function escape_identifiers($item)
{
- if ($this->_escape_char === '')
+ if ($this->_escape_char === '' OR empty($item))
{
return $item;
}
@@ -984,8 +984,8 @@ abstract class CI_DB_driver {
return $item;
}
- // Avoid breaking functions inside queries
- elseif (strpos($item, '(') !== FALSE)
+ // Avoid breaking functions and literal values inside queries
+ elseif (ctype_digit($item) OR $item[0] === "'" OR strpos($item, '(') !== FALSE)
{
return $item;
}
diff --git a/system/database/DB_query_builder.php b/system/database/DB_query_builder.php
index 79e67e0c0..479b7f24a 100644
--- a/system/database/DB_query_builder.php
+++ b/system/database/DB_query_builder.php
@@ -350,18 +350,18 @@ abstract class CI_DB_query_builder extends CI_DB_driver {
is_bool($escape) OR $escape = $this->_protect_identifiers;
// Split multiple conditions
- if ($escape === TRUE && preg_match_all('/\sAND\s|\sOR\s/i', $cond, $m, PREG_SET_ORDER | PREG_OFFSET_CAPTURE))
+ if ($escape === TRUE && preg_match_all('/\sAND\s|\sOR\s/i', $cond, $m, PREG_OFFSET_CAPTURE))
{
$newcond = '';
$m[0][] = array('', strlen($cond));
for ($i = 0, $c = count($m[0]), $s = 0;
$i < $c;
- $s += $m[0][$i][1] + strlen($m[0][$i][0]), $i++)
+ $s = $m[0][$i][1] + strlen($m[0][$i][0]), $i++)
{
- $temp = substr($cond, $s, $m[0][$i][1]);
+ $temp = substr($cond, $s, ($m[0][$i][1] - $s));
- $newcond .= preg_match('/([\[\w\.-]+)([\W\s]+)(.+)/i', $temp, $match)
+ $newcond .= preg_match("/([\[\]\w\.'-]+)(\s*[^\"\[`'\w]+\s*)(.+)/i", $temp, $match)
? $this->protect_identifiers($match[1]).$match[2].$this->protect_identifiers($match[3])
: $temp;
@@ -371,7 +371,7 @@ abstract class CI_DB_query_builder extends CI_DB_driver {
$cond = ' ON '.$newcond;
}
// Split apart the condition and protect the identifiers
- elseif ($escape === TRUE && preg_match('/([\[\w\.-]+)([\W\s]+)(.+)/i', $cond, $match))
+ elseif ($escape === TRUE && preg_match("/([\[\]\w\.'-]+)(\s*[^\"\[`'\w]+\s*)(.+)/i", $cond, $match))
{
$cond = ' ON '.$this->protect_identifiers($match[1]).$match[2].$this->protect_identifiers($match[3]);
}
diff --git a/system/database/DB_result.php b/system/database/DB_result.php
index ee0b61201..d44df6c02 100644
--- a/system/database/DB_result.php
+++ b/system/database/DB_result.php
@@ -144,7 +144,7 @@ class CI_DB_result {
{
$this->custom_result_object[$class_name][$i] = new $class_name();
- foreach ($this->$_data as $key => $value)
+ foreach ($this->{$_data}[$i] as $key => $value)
{
$this->custom_result_object[$class_name][$i]->$key = $value;
}
@@ -156,15 +156,9 @@ class CI_DB_result {
$this->_data_seek(0);
$this->custom_result_object[$class_name] = array();
- while ($row = $this->_fetch_object())
+ while ($row = $this->_fetch_object($class_name))
{
- $object = new $class_name();
- foreach ($row as $key => $value)
- {
- $object->$key = $value;
- }
-
- $custom_result_object[$class_name][] = $object;
+ $this->custom_result_object[$class_name][] = $row;
}
return $this->custom_result_object[$class_name];
@@ -461,11 +455,21 @@ class CI_DB_result {
/**
* Returns an unbuffered row and move pointer to next row
*
+ * @param string 'array', 'object' or a custom class name
* @return mixed either a result object or array
*/
public function unbuffered_row($type = 'object')
{
- return ($type !== 'array') ? $this->_fetch_object() : $this->_fetch_assoc();
+ if ($type === 'array')
+ {
+ return $this->_fetch_assoc();
+ }
+ elseif ($type === 'object')
+ {
+ return $this->_fetch_object();
+ }
+
+ return $this->_fetch_object($type);
}
// --------------------------------------------------------------------
diff --git a/system/database/drivers/cubrid/cubrid_result.php b/system/database/drivers/cubrid/cubrid_result.php
index 4c3978163..4a06a2d39 100644
--- a/system/database/drivers/cubrid/cubrid_result.php
+++ b/system/database/drivers/cubrid/cubrid_result.php
@@ -160,11 +160,12 @@ class CI_DB_cubrid_result extends CI_DB_result {
*
* Returns the result set as an object
*
+ * @param string
* @return object
*/
- protected function _fetch_object()
+ protected function _fetch_object($class_name = 'stdClass')
{
- return cubrid_fetch_object($this->result_id);
+ return cubrid_fetch_object($this->result_id, $class_name);
}
}
diff --git a/system/database/drivers/ibase/ibase_result.php b/system/database/drivers/ibase/ibase_result.php
index fdf74096f..95e55710b 100644
--- a/system/database/drivers/ibase/ibase_result.php
+++ b/system/database/drivers/ibase/ibase_result.php
@@ -128,11 +128,25 @@ class CI_DB_ibase_result extends CI_DB_result {
*
* Returns the result set as an object
*
+ * @param string
* @return object
*/
- protected function _fetch_object()
+ protected function _fetch_object($class_name = 'stdClass')
{
- return @ibase_fetch_object($this->result_id, IBASE_FETCH_BLOBS);
+ $row = @ibase_fetch_object($this->result_id, IBASE_FETCH_BLOBS);
+
+ if ($class_name === 'stdClass' OR ! $row)
+ {
+ return $row;
+ }
+
+ $class_name = new $class_name();
+ foreach ($row as $key => $value)
+ {
+ $class_name->$key = $value;
+ }
+
+ return $class_name;
}
}
diff --git a/system/database/drivers/mssql/mssql_result.php b/system/database/drivers/mssql/mssql_result.php
index 62996aac1..aeede3f4b 100644
--- a/system/database/drivers/mssql/mssql_result.php
+++ b/system/database/drivers/mssql/mssql_result.php
@@ -26,7 +26,7 @@
*/
/**
- * MS SQL Result Class
+ * MSSQL Result Class
*
* This class extends the parent result class: CI_DB_result
*
@@ -161,11 +161,25 @@ class CI_DB_mssql_result extends CI_DB_result {
*
* Returns the result set as an object
*
+ * @param string
* @return object
*/
- protected function _fetch_object()
+ protected function _fetch_object($class_name = 'stdClass')
{
- return mssql_fetch_object($this->result_id);
+ $row = @mssql_fetch_object($this->result_id);
+
+ if ($class_name === 'stdClass' OR ! $row)
+ {
+ return $row;
+ }
+
+ $class_name = new $class_name();
+ foreach ($row as $key => $value)
+ {
+ $class_name->$key = $value;
+ }
+
+ return $class_name;
}
}
diff --git a/system/database/drivers/mysql/mysql_result.php b/system/database/drivers/mysql/mysql_result.php
index a75cfad1f..7fbb65496 100644
--- a/system/database/drivers/mysql/mysql_result.php
+++ b/system/database/drivers/mysql/mysql_result.php
@@ -176,11 +176,12 @@ class CI_DB_mysql_result extends CI_DB_result {
*
* Returns the result set as an object
*
+ * @param string
* @return object
*/
- protected function _fetch_object()
+ protected function _fetch_object($class_name = 'stdClass')
{
- return mysql_fetch_object($this->result_id);
+ return mysql_fetch_object($this->result_id, $class_name);
}
}
diff --git a/system/database/drivers/mysqli/mysqli_result.php b/system/database/drivers/mysqli/mysqli_result.php
index bf96ed9d4..c1ec4da76 100644
--- a/system/database/drivers/mysqli/mysqli_result.php
+++ b/system/database/drivers/mysqli/mysqli_result.php
@@ -160,11 +160,12 @@ class CI_DB_mysqli_result extends CI_DB_result {
*
* Returns the result set as an object
*
+ * @param string
* @return object
*/
- protected function _fetch_object()
+ protected function _fetch_object($class_name = 'stdClass')
{
- return $this->result_id->fetch_object();
+ return $this->result_id->fetch_object($class_name);
}
}
diff --git a/system/database/drivers/oci8/oci8_result.php b/system/database/drivers/oci8/oci8_result.php
index faa295e2a..a2b600e6c 100644
--- a/system/database/drivers/oci8/oci8_result.php
+++ b/system/database/drivers/oci8/oci8_result.php
@@ -167,12 +167,27 @@ class CI_DB_oci8_result extends CI_DB_result {
*
* Returns the result set as an object
*
+ * @param string
* @return object
*/
- protected function _fetch_object()
+ protected function _fetch_object($class_name = 'stdClass')
{
- $id = ($this->curs_id) ? $this->curs_id : $this->stmt_id;
- return oci_fetch_object($id);
+ $row = ($this->curs_id)
+ ? oci_fetch_object($this->curs_id)
+ : oci_fetch_object($this->stmt_id);
+
+ if ($class_name === 'stdClass' OR ! $row)
+ {
+ return $row;
+ }
+
+ $class_name = new $class_name();
+ foreach ($row as $key => $value)
+ {
+ $class_name->$key = $value;
+ }
+
+ return $class_name;
}
// --------------------------------------------------------------------
diff --git a/system/database/drivers/odbc/odbc_result.php b/system/database/drivers/odbc/odbc_result.php
index 1d998bea8..48dc48dd9 100644
--- a/system/database/drivers/odbc/odbc_result.php
+++ b/system/database/drivers/odbc/odbc_result.php
@@ -165,11 +165,25 @@ class CI_DB_odbc_result extends CI_DB_result {
*
* Returns the result set as an object
*
+ * @param string
* @return object
*/
- protected function _fetch_object()
+ protected function _fetch_object($class_name = 'stdClass')
{
- return odbc_fetch_object($this->result_id);
+ $row = odbc_fetch_object($this->result_id);
+
+ if ($class_name === 'stdClass' OR ! $row)
+ {
+ return $row;
+ }
+
+ $class_name = new $class_name();
+ foreach ($row as $key => $value)
+ {
+ $class_name->$key = $value;
+ }
+
+ return $class_name;
}
}
diff --git a/system/database/drivers/pdo/pdo_result.php b/system/database/drivers/pdo/pdo_result.php
index b45e74195..444406986 100644
--- a/system/database/drivers/pdo/pdo_result.php
+++ b/system/database/drivers/pdo/pdo_result.php
@@ -205,11 +205,12 @@ class CI_DB_pdo_result extends CI_DB_result {
*
* Returns the result set as an object
*
+ * @param string
* @return object
*/
- protected function _fetch_object()
+ protected function _fetch_object($class_name = 'stdClass')
{
- return $this->result_id->fetch(PDO::FETCH_OBJ);
+ return $this->result_id->fetchObject($class_name);
}
}
diff --git a/system/database/drivers/postgre/postgre_result.php b/system/database/drivers/postgre/postgre_result.php
index 515acd20f..eb9d647e7 100644
--- a/system/database/drivers/postgre/postgre_result.php
+++ b/system/database/drivers/postgre/postgre_result.php
@@ -159,11 +159,12 @@ class CI_DB_postgre_result extends CI_DB_result {
*
* Returns the result set as an object
*
+ * @param string
* @return object
*/
- protected function _fetch_object()
+ protected function _fetch_object($class_name = 'stdClass')
{
- return pg_fetch_object($this->result_id);
+ return pg_fetch_object($this->result_id, NULL, $class_name);
}
}
diff --git a/system/database/drivers/sqlite/sqlite_result.php b/system/database/drivers/sqlite/sqlite_result.php
index 307dec5a9..eef9787a1 100644
--- a/system/database/drivers/sqlite/sqlite_result.php
+++ b/system/database/drivers/sqlite/sqlite_result.php
@@ -143,17 +143,12 @@ class CI_DB_sqlite_result extends CI_DB_result {
*
* Returns the result set as an object
*
+ * @param string
* @return object
*/
- protected function _fetch_object()
+ protected function _fetch_object($class_name = 'stdClass')
{
- if (function_exists('sqlite_fetch_object'))
- {
- return sqlite_fetch_object($this->result_id);
- }
-
- $arr = sqlite_fetch_array($this->result_id, SQLITE_ASSOC);
- return is_array($arr) ? (object) $arr : FALSE;
+ return sqlite_fetch_object($this->result_id, $class_name);
}
}
diff --git a/system/database/drivers/sqlite3/sqlite3_result.php b/system/database/drivers/sqlite3/sqlite3_result.php
index 4d59bb08a..8e9b9c15f 100644
--- a/system/database/drivers/sqlite3/sqlite3_result.php
+++ b/system/database/drivers/sqlite3/sqlite3_result.php
@@ -26,13 +26,13 @@
*/
/**
- * SQLite Result Class
+ * SQLite3 Result Class
*
* This class extends the parent result class: CI_DB_result
*
* @category Database
- * @author Andrey Andreev
- * @link http://codeigniter.com/user_guide/database/
+ * @author Andrey Andreev
+ * @link http://codeigniter.com/user_guide/database/
* @since 3.0
*/
class CI_DB_sqlite3_result extends CI_DB_result {
@@ -134,13 +134,28 @@ class CI_DB_sqlite3_result extends CI_DB_result {
*
* Returns the result set as an object
*
+ * @param string
* @return object
*/
- protected function _fetch_object()
+ protected function _fetch_object($class_name = 'stdClass')
{
- // No native support for fetching as an object
- $row = $this->_fetch_assoc();
- return ($row !== FALSE) ? (object) $row : FALSE;
+ // No native support for fetching rows as objects
+ if (($row = $this->result_id->fetchArray(SQLITE3_ASSOC)) === FALSE)
+ {
+ return FALSE;
+ }
+ elseif ($class_name === 'stdClass')
+ {
+ return (object) $row;
+ }
+
+ $class_name = new $class_name();
+ foreach (array_keys($row) as $key)
+ {
+ $class_name->$key = $row[$key];
+ }
+
+ return $class_name;
}
// --------------------------------------------------------------------
diff --git a/system/database/drivers/sqlsrv/sqlsrv_result.php b/system/database/drivers/sqlsrv/sqlsrv_result.php
index d469ff470..fb7a68647 100644
--- a/system/database/drivers/sqlsrv/sqlsrv_result.php
+++ b/system/database/drivers/sqlsrv/sqlsrv_result.php
@@ -145,11 +145,12 @@ class CI_DB_sqlsrv_result extends CI_DB_result {
*
* Returns the result set as an object
*
+ * @param string
* @return object
*/
- protected function _fetch_object()
+ protected function _fetch_object($class_name = 'stdClass')
{
- return sqlsrv_fetch_object($this->result_id);
+ return sqlsrv_fetch_object($this->result_id, $class_name);
}
}
diff --git a/system/libraries/Form_validation.php b/system/libraries/Form_validation.php
index 353624100..b490a34ca 100644
--- a/system/libraries/Form_validation.php
+++ b/system/libraries/Form_validation.php
@@ -460,6 +460,12 @@ class CI_Form_validation {
$this->_field_data[$field]['postdata'] = $validation_array[$field];
}
+ // Don't try to validate if we have no rules set
+ if (empty($row['rules']))
+ {
+ continue;
+ }
+
$this->_execute($row, explode('|', $row['rules']), $this->_field_data[$field]['postdata']);
}
diff --git a/tests/codeigniter/database/query_builder/join_test.php b/tests/codeigniter/database/query_builder/join_test.php
index b8cf2a822..25bd4accb 100644
--- a/tests/codeigniter/database/query_builder/join_test.php
+++ b/tests/codeigniter/database/query_builder/join_test.php
@@ -35,4 +35,24 @@ class Join_test extends CI_TestCase {
$this->assertEquals('Developer', $job_user[0]['job_name']);
}
+ // ------------------------------------------------------------------------
+
+ public function test_join_escape_multiple_conditions()
+ {
+ // We just need a valid query produced, not one that makes sense
+ $fields = array($this->db->protect_identifiers('table1.field1'), $this->db->protect_identifiers('table2.field2'));
+
+ $expected = 'SELECT '.implode(', ', $fields)
+ ."\nFROM ".$this->db->escape_identifiers('table1')
+ ."\nLEFT JOIN ".$this->db->escape_identifiers('table2').' ON '.implode(' = ', $fields)
+ .' AND '.$fields[0]." = 'foo' AND ".$fields[1].' = 0';
+
+ $result = $this->db->select('table1.field1, table2.field2')
+ ->from('table1')
+ ->join('table2', "table1.field1 = table2.field2 AND table1.field1 = 'foo' AND table2.field2 = 0", 'LEFT')
+ ->get_compiled_select();
+
+ $this->assertEquals($expected, $result);
+ }
+
} \ No newline at end of file
diff --git a/user_guide_src/source/changelog.rst b/user_guide_src/source/changelog.rst
index 8117bc677..f02892419 100644
--- a/user_guide_src/source/changelog.rst
+++ b/user_guide_src/source/changelog.rst
@@ -168,6 +168,7 @@ Release Date: Not Released
- Removed method is_numeric() as it exists as a native PHP function and _execute() will find and use that (the 'is_numeric' rule itself is deprecated since 1.6.1).
- Native PHP functions used as rules can now accept an additional parameter, other than the data itself.
- Updated set_rules() to accept an array of rules as well as a string.
+ - Fields that have empty rules set no longer run through validation (and therefore are not considered erroneous).
- Changed the :doc:`Session Library <libraries/sessions>` to select only one row when using database sessions.
- Added all_flashdata() method to session class. Returns an associative array of only flashdata.
- Allowed for setting table class defaults in a config file.
@@ -308,6 +309,7 @@ Bug fixes for 3.0
- Fixed a bug (#427) - :doc:`Form Validation Library <libraries/form_validation>` method ``strip_image_tags()`` was an alias to a non-existent method.
- Fixed a bug (#1545) - :doc:`Query Builder <database/query_builder>` method ``limit()`` wasn't executed properly under Oracle.
- Fixed a bug (#1551) - :doc:`Date Helper <helpers/date_helper>` function ``standard_date()`` didn't properly format *W3C* and *ATOM* standard dates.
+- Fixed a bug in :doc:`Query Builder <database/query_builder>` method join() where literal values were escaped as if they were fields.
Version 2.1.2
=============
diff --git a/user_guide_src/source/helpers/form_helper.rst b/user_guide_src/source/helpers/form_helper.rst
index a110f3c14..fa7b3dbf9 100644
--- a/user_guide_src/source/helpers/form_helper.rst
+++ b/user_guide_src/source/helpers/form_helper.rst
@@ -543,3 +543,7 @@ This function is identical to the **set_checkbox()** function above.
<input type="radio" name="myradio" value="1" <?php echo set_radio('myradio', '1', TRUE); ?> />
<input type="radio" name="myradio" value="2" <?php echo set_radio('myradio', '2'); ?> />
+.. note:: If you are using the Form Validation class, you must always specify a rule for your field,
+ even if empty, in order for the set_*() functions to work. This is because if a Form Validation object
+ is defined, the control for set_*() is handed over to a method of the class instead of the generic helper
+ function. \ No newline at end of file