summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--system/core/Security.php24
-rw-r--r--system/database/DB_forge.php36
-rw-r--r--system/database/DB_query_builder.php2
-rw-r--r--system/database/drivers/mysql/mysql_forge.php30
-rw-r--r--system/database/drivers/mysqli/mysqli_forge.php30
-rw-r--r--system/database/drivers/pdo/subdrivers/pdo_mysql_forge.php30
-rw-r--r--system/database/drivers/sqlsrv/sqlsrv_driver.php37
-rw-r--r--system/database/drivers/sqlsrv/sqlsrv_result.php32
-rw-r--r--system/helpers/directory_helper.php2
-rw-r--r--system/libraries/Profiler.php2
-rw-r--r--system/libraries/Session/Session.php89
-rw-r--r--tests/codeigniter/libraries/Session_test.php20
-rw-r--r--user_guide_src/source/changelog.rst38
-rw-r--r--user_guide_src/source/database/forge.rst9
-rw-r--r--user_guide_src/source/installation/upgrade_300.rst15
-rw-r--r--user_guide_src/source/libraries/sessions.rst4
16 files changed, 298 insertions, 102 deletions
diff --git a/system/core/Security.php b/system/core/Security.php
index 95957a3d8..d6356f869 100644
--- a/system/core/Security.php
+++ b/system/core/Security.php
@@ -62,6 +62,17 @@ class CI_Security {
);
/**
+ * HTML5 entities
+ *
+ * @var array
+ */
+ public $html5_entities = array(
+ ':' => ':',
+ '(' => '(',
+ ')' => ')'
+ );
+
+ /**
* XSS Hash
*
* Random Hash for protecting URLs.
@@ -134,7 +145,7 @@ class CI_Security {
'(document|(document\.)?window)\.(location|on\w*)',
'expression\s*(\(|&\#40;)', // CSS and IE
'vbscript\s*:', // IE, surprise!
- 'Redirect\s+302',
+ 'Redirect\s+30\d',
"([\"'])?data\s*:[^\\1]*?base64[^\\1]*?,[^\\1]*?\\1?"
);
@@ -456,7 +467,7 @@ class CI_Security {
* So this: <blink>
* Becomes: &lt;blink&gt;
*/
- $naughty = 'alert|applet|audio|basefont|base|behavior|bgsound|blink|body|embed|expression|form|frameset|frame|head|html|ilayer|iframe|input|isindex|layer|link|meta|object|plaintext|style|script|textarea|title|video|xml|xss';
+ $naughty = 'alert|applet|audio|basefont|base|behavior|bgsound|blink|body|embed|expression|form|frameset|frame|head|html|ilayer|iframe|input|button|isindex|layer|link|meta|object|plaintext|style|script|textarea|title|video|xml|xss';
$str = preg_replace_callback('#<(/*\s*)('.$naughty.')([^><]*)([><]*)#is', array($this, '_sanitize_naughty_html'), $str);
/*
@@ -810,7 +821,14 @@ class CI_Security {
*/
protected function _decode_entity($match)
{
- return $this->entity_decode($match[0], strtoupper(config_item('charset')));
+ // entity_decode() won't convert dangerous HTML5 entities
+ // (it could, but ENT_HTML5 is only available since PHP 5.4),
+ // so we'll do that here
+ return str_ireplace(
+ array_keys($this->html5_entities),
+ array_values($this->html5_entities),
+ $this->entity_decode($match[0], strtoupper(config_item('charset')))
+ );
}
// --------------------------------------------------------------------
diff --git a/system/database/DB_forge.php b/system/database/DB_forge.php
index 1cebb189c..fc4a9230f 100644
--- a/system/database/DB_forge.php
+++ b/system/database/DB_forge.php
@@ -314,9 +314,10 @@ abstract class CI_DB_forge {
*
* @param string $table Table name
* @param bool $if_not_exists Whether to add IF NOT EXISTS condition
+ * @param array $attributes Associative array of table attributes
* @return bool
*/
- public function create_table($table = '', $if_not_exists = FALSE)
+ public function create_table($table = '', $if_not_exists = FALSE, array $attributes = array())
{
if ($table === '')
{
@@ -332,7 +333,7 @@ abstract class CI_DB_forge {
show_error('Field information is required.');
}
- $sql = $this->_create_table($table, $if_not_exists);
+ $sql = $this->_create_table($table, $if_not_exists, $attributes);
if (is_bool($sql))
{
@@ -368,9 +369,10 @@ abstract class CI_DB_forge {
*
* @param string $table Table name
* @param bool $if_not_exists Whether to add 'IF NOT EXISTS' condition
+ * @param array $attributes Associative array of table attributes
* @return mixed
*/
- protected function _create_table($table, $if_not_exists)
+ protected function _create_table($table, $if_not_exists, $attributes)
{
if ($if_not_exists === TRUE && $this->_create_table_if === FALSE)
{
@@ -406,10 +408,11 @@ abstract class CI_DB_forge {
}
// _create_table will usually have the following format: "%s %s (%s\n)"
- $sql = sprintf($this->_create_table.';',
+ $sql = sprintf($this->_create_table.'%s;',
$sql,
$this->db->escape_identifiers($table),
- $columns
+ $columns,
+ $this->_create_table_attr($attributes)
);
return $sql;
@@ -418,6 +421,29 @@ abstract class CI_DB_forge {
// --------------------------------------------------------------------
/**
+ * CREATE TABLE attributes
+ *
+ * @param array $attributes Associative array of table attributes
+ * @return string
+ */
+ protected function _create_table_attr($attributes)
+ {
+ $sql = '';
+
+ foreach (array_keys($attributes) as $key)
+ {
+ if (is_string($key))
+ {
+ $sql .= ' '.strtoupper($key).' '.$attributes[$key];
+ }
+ }
+
+ return $sql;
+ }
+
+ // --------------------------------------------------------------------
+
+ /**
* Drop Table
*
* @param string $table_name Table name
diff --git a/system/database/DB_query_builder.php b/system/database/DB_query_builder.php
index c543e1584..8223baac1 100644
--- a/system/database/DB_query_builder.php
+++ b/system/database/DB_query_builder.php
@@ -2367,7 +2367,7 @@ abstract class CI_DB_query_builder extends CI_DB_driver {
for ($i = 0, $c = count($this->qb_groupby); $i < $c; $i++)
{
// Is it already compiled?
- if (is_string($this->qb_groupby))
+ if (is_string($this->qb_groupby[$i]))
{
continue;
}
diff --git a/system/database/drivers/mysql/mysql_forge.php b/system/database/drivers/mysql/mysql_forge.php
index e251c0ea6..3b3cbdee0 100644
--- a/system/database/drivers/mysql/mysql_forge.php
+++ b/system/database/drivers/mysql/mysql_forge.php
@@ -82,16 +82,34 @@ class CI_DB_mysql_forge extends CI_DB_forge {
// --------------------------------------------------------------------
/**
- * Class constructor
+ * CREATE TABLE attributes
*
- * @param object &$db Database object
- * @return void
+ * @param array $attributes Associative array of table attributes
+ * @return string
*/
- public function __construct(&$db)
+ protected function _create_table_attr($attributes)
{
- parent::__construct($db);
+ $sql = '';
+
+ foreach (array_keys($attributes) as $key)
+ {
+ if (is_string($key))
+ {
+ $sql .= ' '.strtoupper($key).' = '.$attributes[$key];
+ }
+ }
- $this->_create_table .= ' DEFAULT CHARSET '.$this->db->char_set.' COLLATE '.$this->db->dbcollat;
+ if ( ! empty($this->db->char_set) && ! strpos($sql, 'CHARACTER SET') && ! strpos($sql, 'CHARSET'))
+ {
+ $sql .= ' DEFAULT CHARACTER SET = '.$this->db->char_set;
+ }
+
+ if ( ! empty($this->db->dbcollat) && ! strpos($sql, 'COLLATE'))
+ {
+ $sql .= ' COLLATE = '.$this->db->dbcollat;
+ }
+
+ return $sql;
}
// --------------------------------------------------------------------
diff --git a/system/database/drivers/mysqli/mysqli_forge.php b/system/database/drivers/mysqli/mysqli_forge.php
index d1e5e20ff..1a568ccd9 100644
--- a/system/database/drivers/mysqli/mysqli_forge.php
+++ b/system/database/drivers/mysqli/mysqli_forge.php
@@ -82,16 +82,34 @@ class CI_DB_mysqli_forge extends CI_DB_forge {
// --------------------------------------------------------------------
/**
- * Class constructor
+ * CREATE TABLE attributes
*
- * @param object &$db Database object
- * @return void
+ * @param array $attributes Associative array of table attributes
+ * @return string
*/
- public function __construct(&$db)
+ protected function _create_table_attr($attributes)
{
- parent::__construct($db);
+ $sql = '';
+
+ foreach (array_keys($attributes) as $key)
+ {
+ if (is_string($key))
+ {
+ $sql .= ' '.strtoupper($key).' = '.$attributes[$key];
+ }
+ }
- $this->_create_table .= ' DEFAULT CHARSET '.$this->db->char_set.' COLLATE '.$this->db->dbcollat;
+ if ( ! empty($this->db->char_set) && ! strpos($sql, 'CHARACTER SET') && ! strpos($sql, 'CHARSET'))
+ {
+ $sql .= ' DEFAULT CHARACTER SET = '.$this->db->char_set;
+ }
+
+ if ( ! empty($this->db->dbcollat) && ! strpos($sql, 'COLLATE'))
+ {
+ $sql .= ' COLLATE = '.$this->db->dbcollat;
+ }
+
+ return $sql;
}
// --------------------------------------------------------------------
diff --git a/system/database/drivers/pdo/subdrivers/pdo_mysql_forge.php b/system/database/drivers/pdo/subdrivers/pdo_mysql_forge.php
index 74689d91e..3ac98e6c3 100644
--- a/system/database/drivers/pdo/subdrivers/pdo_mysql_forge.php
+++ b/system/database/drivers/pdo/subdrivers/pdo_mysql_forge.php
@@ -96,16 +96,34 @@ class CI_DB_pdo_mysql_forge extends CI_DB_pdo_forge {
// --------------------------------------------------------------------
/**
- * Class constructor
+ * CREATE TABLE attributes
*
- * @param object &$db Database object
- * @return void
+ * @param array $attributes Associative array of table attributes
+ * @return string
*/
- public function __construct(&$db)
+ protected function _create_table_attr($attributes)
{
- parent::__construct($db);
+ $sql = '';
+
+ foreach (array_keys($attributes) as $key)
+ {
+ if (is_string($key))
+ {
+ $sql .= ' '.strtoupper($key).' = '.$attributes[$key];
+ }
+ }
- $this->_create_table .= ' DEFAULT CHARSET '.$this->db->char_set.' COLLATE '.$this->db->dbcollat;
+ if ( ! empty($this->db->char_set) && ! strpos($sql, 'CHARACTER SET') && ! strpos($sql, 'CHARSET'))
+ {
+ $sql .= ' DEFAULT CHARACTER SET = '.$this->db->char_set;
+ }
+
+ if ( ! empty($this->db->dbcollat) && ! strpos($sql, 'COLLATE'))
+ {
+ $sql .= ' COLLATE = '.$this->db->dbcollat;
+ }
+
+ return $sql;
}
// --------------------------------------------------------------------
diff --git a/system/database/drivers/sqlsrv/sqlsrv_driver.php b/system/database/drivers/sqlsrv/sqlsrv_driver.php
index 09e6b8c9a..2759bac0b 100644
--- a/system/database/drivers/sqlsrv/sqlsrv_driver.php
+++ b/system/database/drivers/sqlsrv/sqlsrv_driver.php
@@ -48,6 +48,18 @@ class CI_DB_sqlsrv_driver extends CI_DB {
*/
public $dbdriver = 'sqlsrv';
+ /**
+ * Scrollable flag
+ *
+ * Determines what cursor type to use when executing queries.
+ *
+ * FALSE or SQLSRV_CURSOR_FORWARD would increase performance,
+ * but would disable num_rows() (and possibly insert_id())
+ *
+ * @var mixed
+ */
+ public $scrollable;
+
// --------------------------------------------------------------------
/**
@@ -70,6 +82,27 @@ class CI_DB_sqlsrv_driver extends CI_DB {
// --------------------------------------------------------------------
/**
+ * Class constructor
+ *
+ * @param array $params
+ * @return void
+ */
+ public function __construct($params)
+ {
+ parent::__construct($params);
+
+ // This is only supported as of SQLSRV 3.0
+ if ($this->scrollable === NULL)
+ {
+ $this->scrollable = defined('SQLSRV_CURSOR_CLIENT_BUFFERED')
+ ? SQLSRV_CURSOR_CLIENT_BUFFERED
+ : FALSE;
+ }
+ }
+
+ // --------------------------------------------------------------------
+
+ /**
* Database connection
*
* @param bool $pooling
@@ -154,9 +187,9 @@ class CI_DB_sqlsrv_driver extends CI_DB {
*/
protected function _execute($sql)
{
- return ($this->is_write_type($sql) && stripos($sql, 'INSERT') === FALSE)
+ return ($this->scrollable === FALSE OR $this->is_write_type($sql))
? sqlsrv_query($this->conn_id, $sql)
- : sqlsrv_query($this->conn_id, $sql, NULL, array('Scrollable' => SQLSRV_CURSOR_STATIC));
+ : sqlsrv_query($this->conn_id, $sql, NULL, array('Scrollable' => $this->scrollable));
}
// --------------------------------------------------------------------
diff --git a/system/database/drivers/sqlsrv/sqlsrv_result.php b/system/database/drivers/sqlsrv/sqlsrv_result.php
index 3c8148f1b..ba38f7454 100644
--- a/system/database/drivers/sqlsrv/sqlsrv_result.php
+++ b/system/database/drivers/sqlsrv/sqlsrv_result.php
@@ -39,15 +39,45 @@ defined('BASEPATH') OR exit('No direct script access allowed');
class CI_DB_sqlsrv_result extends CI_DB_result {
/**
+ * Scrollable flag
+ *
+ * @var mixed
+ */
+ public $scrollable;
+
+ // --------------------------------------------------------------------
+
+ /**
+ * Constructor
+ *
+ * @param object $driver_object
+ * @return void
+ */
+ public function __construct(&$driver_object)
+ {
+ parent::__construct($driver_object);
+
+ $this->scrollable = $driver_object->scrollable;
+ }
+
+ // --------------------------------------------------------------------
+
+ /**
* Number of rows in the result set
*
* @return int
*/
public function num_rows()
{
+ // sqlsrv_num_rows() doesn't work with the FORWARD and DYNAMIC cursors (FALSE is the same as FORWARD)
+ if ( ! in_array($this->scrollable, array(FALSE, SQLSRV_CURSOR_FORWARD, SQLSRV_CURSOR_DYNAMIC), TRUE))
+ {
+ return parent::num_rows();
+ }
+
return is_int($this->num_rows)
? $this->num_rows
- : $this->num_rows = @sqlsrv_num_rows($this->result_id);
+ : $this->num_rows = sqlsrv_num_rows($this->result_id);
}
// --------------------------------------------------------------------
diff --git a/system/helpers/directory_helper.php b/system/helpers/directory_helper.php
index 81ffd1579..6f9251720 100644
--- a/system/helpers/directory_helper.php
+++ b/system/helpers/directory_helper.php
@@ -69,7 +69,7 @@ if ( ! function_exists('directory_map'))
continue;
}
- @is_dir($source_dir.$file) AND $file .= DIRECTORY_SEPARATOR;
+ @is_dir($source_dir.$file) && $file .= DIRECTORY_SEPARATOR;
if (($directory_depth < 1 OR $new_depth > 0) && @is_dir($source_dir.$file))
{
diff --git a/system/libraries/Profiler.php b/system/libraries/Profiler.php
index 4e556b23d..4796e8416 100644
--- a/system/libraries/Profiler.php
+++ b/system/libraries/Profiler.php
@@ -516,7 +516,7 @@ class CI_Profiler {
.'<legend style="color:#000;">&nbsp;&nbsp;'.$this->CI->lang->line('profiler_session_data').'&nbsp;&nbsp;(<span style="cursor: pointer;" onclick="var s=document.getElementById(\'ci_profiler_session_data\').style;s.display=s.display==\'none\'?\'\':\'none\';this.innerHTML=this.innerHTML==\''.$this->CI->lang->line('profiler_section_show').'\'?\''.$this->CI->lang->line('profiler_section_hide').'\':\''.$this->CI->lang->line('profiler_section_show').'\';">'.$this->CI->lang->line('profiler_section_show').'</span>)</legend>'
.'<table style="width:100%;display:none;" id="ci_profiler_session_data">';
- foreach ($this->CI->session->all_userdata() as $key => $val)
+ foreach ($this->CI->session->userdata() as $key => $val)
{
if (is_array($val) OR is_object($val))
{
diff --git a/system/libraries/Session/Session.php b/system/libraries/Session/Session.php
index ac97b944c..d9f2f506f 100644
--- a/system/libraries/Session/Session.php
+++ b/system/libraries/Session/Session.php
@@ -238,9 +238,14 @@ class CI_Session extends CI_Driver_Library {
* @param string Item key
* @return string Item value or NULL if not found
*/
- public function userdata($item)
+ public function userdata($item = NULL)
{
- return isset($this->userdata[$item]) ? $this->userdata[$item] : NULL;
+ if (isset($item))
+ {
+ return isset($this->userdata[$item]) ? $this->userdata[$item] : NULL;
+ }
+
+ return isset($this->userdata) ? $this->userdata : array();
}
// ------------------------------------------------------------------------
@@ -248,35 +253,12 @@ class CI_Session extends CI_Driver_Library {
/**
* Fetch all session data
*
+ * @deprecated 3.0.0 Use userdata() with no parameters instead
* @return array User data array
*/
public function all_userdata()
{
- return isset($this->userdata) ? $this->userdata : NULL;
- }
-
- // ------------------------------------------------------------------------
-
- /**
- * Fetch all flashdata
- *
- * @return array Flash data array
- */
- public function all_flashdata()
- {
- $out = array();
-
- // loop through all userdata
- foreach ($this->all_userdata() as $key => $val)
- {
- // if it contains flashdata, add it
- if (strpos($key, self::FLASHDATA_KEY.self::FLASHDATA_OLD) !== FALSE)
- {
- $key = str_replace(self::FLASHDATA_KEY.self::FLASHDATA_OLD, '', $key);
- $out[$key] = $val;
- }
- }
- return $out;
+ return isset($this->userdata) ? $this->userdata : array();
}
// ------------------------------------------------------------------------
@@ -417,11 +399,25 @@ class CI_Session extends CI_Driver_Library {
* @param string Item key
* @return string
*/
- public function flashdata($key)
+ public function flashdata($key = NULL)
{
- // Prepend key and retrieve value
- $flashdata_key = self::FLASHDATA_KEY.self::FLASHDATA_OLD.$key;
- return $this->userdata($flashdata_key);
+ if (isset($key))
+ {
+ return $this->userdata(self::FLASHDATA_KEY.self::FLASHDATA_OLD.$key);
+ }
+
+ // Get our flashdata items from userdata
+ $out = array();
+ foreach ($this->userdata() as $key => $val)
+ {
+ if (strpos($key, self::FLASHDATA_KEY.self::FLASHDATA_OLD) !== FALSE)
+ {
+ $key = str_replace(self::FLASHDATA_KEY.self::FLASHDATA_OLD, '', $key);
+ $out[$key] = $val;
+ }
+ }
+
+ return $out;
}
// ------------------------------------------------------------------------
@@ -514,11 +510,25 @@ class CI_Session extends CI_Driver_Library {
* @param string Item key
* @return string
*/
- public function tempdata($key)
+ public function tempdata($key = NULL)
{
- // Prepend key and return value
- $tempdata_key = self::FLASHDATA_KEY.self::FLASHDATA_EXP.$key;
- return $this->userdata($tempdata_key);
+ if (isset($key))
+ {
+ return $this->userdata(self::FLASHDATA_KEY.self::FLASHDATA_EXP.$key);
+ }
+
+ // Get our tempdata items from userdata
+ $out = array();
+ foreach ($this->userdata() as $key => $val)
+ {
+ if (strpos($key, self::FLASHDATA_KEY.self::FLASHDATA_EXP) !== FALSE)
+ {
+ $key = str_replace(self::FLASHDATA_KEY.self::FLASHDATA_EXP, '', $key);
+ $out[$key] = $val;
+ }
+ }
+
+ return $out;
}
// ------------------------------------------------------------------------
@@ -531,13 +541,12 @@ class CI_Session extends CI_Driver_Library {
*/
protected function _flashdata_mark()
{
- foreach ($this->all_userdata() as $name => $value)
+ foreach ($this->userdata() as $name => $value)
{
$parts = explode(self::FLASHDATA_NEW, $name);
if (count($parts) === 2)
{
- $new_name = self::FLASHDATA_KEY.self::FLASHDATA_OLD.$parts[1];
- $this->set_userdata($new_name, $value);
+ $this->set_userdata(self::FLASHDATA_KEY.self::FLASHDATA_OLD.$parts[1], $value);
$this->unset_userdata($name);
}
}
@@ -552,7 +561,7 @@ class CI_Session extends CI_Driver_Library {
*/
protected function _flashdata_sweep()
{
- $userdata = $this->all_userdata();
+ $userdata = $this->userdata();
foreach (array_keys($userdata) as $key)
{
if (strpos($key, self::FLASHDATA_OLD))
@@ -581,7 +590,7 @@ class CI_Session extends CI_Driver_Library {
// Unset expired elements
$now = time();
- $userdata = $this->all_userdata();
+ $userdata = $this->userdata();
foreach (array_keys($userdata) as $key)
{
if (strpos($key, self::FLASHDATA_EXP) && $expirations[$key] < $now)
diff --git a/tests/codeigniter/libraries/Session_test.php b/tests/codeigniter/libraries/Session_test.php
index 6edda99d7..cff0fdbd8 100644
--- a/tests/codeigniter/libraries/Session_test.php
+++ b/tests/codeigniter/libraries/Session_test.php
@@ -156,11 +156,11 @@ class Session_test extends CI_TestCase {
$this->session->native->set_userdata($ndata);
// Make sure all values are present
- $call = $this->session->cookie->all_userdata();
+ $call = $this->session->cookie->userdata();
foreach ($cdata as $key => $value) {
$this->assertEquals($value, $call[$key]);
}
- $nall = $this->session->native->all_userdata();
+ $nall = $this->session->native->userdata();
foreach ($ndata as $key => $value) {
$this->assertEquals($value, $nall[$key]);
}
@@ -283,8 +283,8 @@ class Session_test extends CI_TestCase {
// Simulate page reload and verify independent messages
$this->session->cookie->reload();
$this->session->native->reload();
- $this->assertEquals($cdata, $this->session->cookie->all_flashdata());
- $this->assertEquals($ndata, $this->session->native->all_flashdata());
+ $this->assertEquals($cdata, $this->session->cookie->flashdata());
+ $this->assertEquals($ndata, $this->session->native->flashdata());
// Keep messages
$this->session->cookie->keep_flashdata($kdata);
@@ -293,14 +293,14 @@ class Session_test extends CI_TestCase {
// Simulate next page reload and verify message persistence
$this->session->cookie->reload();
$this->session->native->reload();
- $this->assertEquals($cdata, $this->session->cookie->all_flashdata());
- $this->assertEquals($ndata, $this->session->native->all_flashdata());
+ $this->assertEquals($cdata, $this->session->cookie->flashdata());
+ $this->assertEquals($ndata, $this->session->native->flashdata());
// Simulate next page reload and verify absence of messages
$this->session->cookie->reload();
$this->session->native->reload();
- $this->assertEmpty($this->session->cookie->all_flashdata());
- $this->assertEmpty($this->session->native->all_flashdata());
+ $this->assertEmpty($this->session->cookie->flashdata());
+ $this->assertEmpty($this->session->native->flashdata());
}
/**
@@ -329,8 +329,8 @@ class Session_test extends CI_TestCase {
// Simulate page reload and make sure all values are present
$this->session->cookie->reload();
$this->session->native->reload();
- $this->assertEquals($cdata, $this->session->cookie->all_flashdata());
- $this->assertEquals($ndata, $this->session->native->all_flashdata());
+ $this->assertEquals($cdata, $this->session->cookie->flashdata());
+ $this->assertEquals($ndata, $this->session->native->flashdata());
}
/**
diff --git a/user_guide_src/source/changelog.rst b/user_guide_src/source/changelog.rst
index 825e0f845..ca228565d 100644
--- a/user_guide_src/source/changelog.rst
+++ b/user_guide_src/source/changelog.rst
@@ -222,6 +222,9 @@ Release Date: Not Released
- Added port handling support for UNIX-based systems (MSSQL driver).
- Added *OFFSET* support for SQL Server 2005 and above.
- Added ``db_set_charset()`` support (MSSQL driver).
+ - Added a *scrollable* property to enable configuration of the cursor to use (SQLSRV driver).
+ - Added support and auto-detection for the ``SQLSRV_CURSOR_CLIENT_BUFFERED`` scrollable cursor flag (SQLSRV driver).
+ - Changed default behavior to not use ``SQLSRV_CURSOR_STATIC`` due to performance issues (SQLSRV driver).
- Improved support of the Oracle (OCI8) driver, including:
@@ -240,8 +243,9 @@ Release Date: Not Released
- Added an optional second parameter to ``drop_table()`` that allows adding the **IF EXISTS** condition, which is no longer the default.
- Added support for passing a custom database object to the loader.
- - Deprecated ``add_column()``'s third method. *AFTER* clause should now be added to the field definition array instead.
+ - Added support for passing custom table attributes (such as ``ENGINE`` for MySQL) to ``create_table()``.
- Added support for usage of the *FIRST* clause in ``add_column()`` for MySQL and CUBRID.
+ - Deprecated ``add_column()``'s third method. *AFTER* clause should now be added to the field definition array instead.
- Overall improved support for all of the drivers.
- :doc:`Database Utility <database/utilities>` changes include:
@@ -255,22 +259,18 @@ Release Date: Not Released
- :doc:`Session Library <libraries/sessions>` changes include:
- - Library changed to :doc:`Driver <general/drivers>` with classic Cookie driver as default.
- - Added Native PHP Session driver to work with ``$_SESSION``.
- - Custom drivers can be added anywhere in package paths and be loaded with the library.
- - Drivers interchangeable on the fly.
- - New **tempdata** feature allows setting user data items with an expiration time.
- - Added default ``$config['sess_driver']`` and ``$config['sess_valid_drivers']`` items to *config.php* file.
- - Cookie driver now respects php.ini's *session.gc_probability* and *session.gc_divisor* settings.
- - Cookie driver now uses HMAC authentication instead of the simple md5 checksum.
- - The Cookie driver now also checks authentication on encrypted session data.
- - Changed the Cookie driver to select only one row when using database sessions.
- - Cookie driver now only writes to database at end of request when using database.
- - Cookie driver now uses PHP functions for faster array manipulation when using database.
- - Added ``all_flashdata()`` method to session class. Returns an associative array of only flashdata.
- - Added ``has_userdata()`` method to verify existence of userdata item.
- - Added ``tempdata()``, ``set_tempdata()``, and ``unset_tempdata()`` methods for manipulating tempdata.
- - ``keep_flashdata()`` now accepts an array of keys.
+ - Library changed to :doc:`Driver <general/drivers>` with classic 'cookie' driver as the default.
+ - Added a 'native' PHP Session driver to work with ``$_SESSION``.
+ - Added a new **tempdata** feature that allows setting userdata items with expiration time (``tempdata()``, ``set_tempdata()``, ``unset_tempdata()``).
+ - Added default ``$config['sess_driver']`` and ``$config['sess_valid_drivers']`` items to *application/config.php* file.
+ - Changed 'cookie' driver to respect php.ini's *session.gc_probability* and *session.gc_divisor* settings.
+ - Changed 'cookie' driver to use HMAC authentication instead of a simple md5 checksum.
+ - Changed 'cookie' driver to select only one row when using database sessions.
+ - Changed 'cookie' driver to write to only write to the database at end of page execution.
+ - Changed method ``keep_flashdata()`` to also accept an array of keys.
+ - Changed methods ``userdata()``, ``flashdata()`` to return an array of all userdata/flashdata when no parameter is passed.
+ - Deprecated method ``all_userdata()`` - it is now just an alias for ``userdata()`` with no parameters.
+ - Added method ``has_userdata()`` that verifies the existence of a userdata item.
- Added *debug* level log messages for key events in the session validation process.
- :doc:`File Uploading Library <libraries/file_uploading>` changes include:
@@ -681,7 +681,9 @@ Bug fixes for 3.0
- Fixed a bug where :doc:`User Agent Library <libraries/user_agent>` methods ``accept_charset()`` and ``accept_lang()`` didn't properly parse HTTP headers that contain spaces.
- Fixed a bug where *default_controller* was called instad of triggering a 404 error if the current route is in a controller directory.
- Fixed a bug (#2737) - :doc:`XML-RPC Library <libraries/xmlrpc>` used objects as array keys, which triggered E_NOTICE messages.
-- Fixed a bug (#2729) - ``CI_Securty::_validate_entities()`` used overly-intrusive ``preg_replace()`` patterns that produced false-positives.
+- Fixed a bug (#2729) - ``CI_Security::_validate_entities()`` used overly-intrusive ``preg_replace()`` patterns that produced false-positives.
+- Fixed a bug (#2771) - ``CI_Security::xss_clean()`` didn't take into account HTML5 entities.
+- Fixed a bug in the :doc:`Session Library <libraries/sessions>` 'cookie' driver where authentication was not performed for encrypted cookies.
Version 2.1.4
=============
diff --git a/user_guide_src/source/database/forge.rst b/user_guide_src/source/database/forge.rst
index ca904ed00..48642ad7e 100644
--- a/user_guide_src/source/database/forge.rst
+++ b/user_guide_src/source/database/forge.rst
@@ -201,6 +201,15 @@ into the definition
$this->dbforge->create_table('table_name', TRUE);
// gives CREATE TABLE IF NOT EXISTS table_name
+You could also pass optional table attributes, such as MySQL's ``ENGINE``::
+
+ $attributes = array('ENGINE' => 'InnoDB');
+ $this->dbforge->create_table('table_name', FALSE, $attributes);
+ // produces: CREATE TABLE `table_name` (...) ENGINE = InnoDB DEFAULT CHARACTER SET utf8 COLLATE utf8_general_ci
+
+.. note:: Unless you specify the ``CHARACTER SET`` and/or ``COLLATE`` attributes,
+ ``create_table()`` will always add them with your configured *char_set*
+ and *dbcollat* values, as long as they are not empty (MySQL only).
Dropping a table
================
diff --git a/user_guide_src/source/installation/upgrade_300.rst b/user_guide_src/source/installation/upgrade_300.rst
index c11db34f8..fccaa2933 100644
--- a/user_guide_src/source/installation/upgrade_300.rst
+++ b/user_guide_src/source/installation/upgrade_300.rst
@@ -469,6 +469,21 @@ in CodeIgniter 3.1+.
.. note:: These options are still available, but you're strongly encouraged to remove their usage
sooner rather than later.
+Session Library method all_userdata()
+=====================================
+
+As seen in the :doc:`Change Log <../changelog>`, :doc:`Session Library <libraries/sessions>`
+method ``userdata()`` now allows you to fetch all userdata by simply omitting its parameter::
+
+ $this->session->userdata();
+
+This makes the ``all_userdata()`` method redudant and therefore it is now just an alias for
+``userdata()`` with the above shown usage and is being deprecated and scheduled for removal
+in CodeIgniter 3.1+.
+
+.. note:: This method is still available, but you're strongly encouraged to remove its usage
+ sooner rather than later.
+
Database Forge method add_column() with an AFTER clause
=======================================================
diff --git a/user_guide_src/source/libraries/sessions.rst b/user_guide_src/source/libraries/sessions.rst
index c4f861620..f63f584a6 100644
--- a/user_guide_src/source/libraries/sessions.rst
+++ b/user_guide_src/source/libraries/sessions.rst
@@ -149,7 +149,7 @@ Retrieving All Session Data
An array of all userdata can be retrieved as follows::
- $this->session->all_userdata()
+ $this->session->userdata()
And returns an associative array like the following::
@@ -206,7 +206,7 @@ To read a flashdata variable::
An array of all flashdata can be retrieved as follows::
- $this->session->all_flashdata();
+ $this->session->flashdata();
If you find that you need to preserve a flashdata variable through an