summaryrefslogtreecommitdiffstats
path: root/system
diff options
context:
space:
mode:
authorAndrey Andreev <narf@devilix.net>2015-10-12 16:16:35 +0200
committerAndrey Andreev <narf@devilix.net>2015-10-12 16:16:35 +0200
commit3013f53c59a5d2550a126b1493cf8262bd62dd53 (patch)
tree772e9b569a65e8567c366671373a2700c2028445 /system
parent30f593bbb3408d0c076f2453818c68a7c5c59248 (diff)
parent36a055e49b040e6f18be7bce5e010c2a90d2f44f (diff)
Merge branch '3.0-stable' into develop
Diffstat (limited to 'system')
-rw-r--r--system/core/Config.php20
-rw-r--r--system/core/Exceptions.php2
-rw-r--r--system/core/Input.php20
-rw-r--r--system/core/Loader.php2
-rw-r--r--system/core/Router.php42
-rw-r--r--system/core/Security.php188
-rw-r--r--system/database/DB_driver.php39
-rw-r--r--system/database/DB_query_builder.php2
-rw-r--r--system/database/drivers/mssql/mssql_driver.php16
-rw-r--r--system/database/drivers/sqlsrv/sqlsrv_driver.php15
-rw-r--r--system/helpers/file_helper.php2
-rw-r--r--system/libraries/Cache/drivers/Cache_file.php2
-rw-r--r--system/libraries/Cache/drivers/Cache_memcached.php10
-rw-r--r--system/libraries/Cache/drivers/Cache_redis.php22
-rw-r--r--system/libraries/Email.php23
-rw-r--r--system/libraries/Pagination.php12
16 files changed, 240 insertions, 177 deletions
diff --git a/system/core/Config.php b/system/core/Config.php
index d07000ac9..feea7c85a 100644
--- a/system/core/Config.php
+++ b/system/core/Config.php
@@ -238,7 +238,15 @@ class CI_Config {
if (isset($protocol))
{
- $base_url = $protocol.substr($base_url, strpos($base_url, '://'));
+ // For protocol-relative links
+ if ($protocol === '')
+ {
+ $base_url = substr($base_url, strpos($base_url, '//'));
+ }
+ else
+ {
+ $base_url = $protocol.substr($base_url, strpos($base_url, '://'));
+ }
}
if (empty($uri))
@@ -293,7 +301,15 @@ class CI_Config {
if (isset($protocol))
{
- $base_url = $protocol.substr($base_url, strpos($base_url, '://'));
+ // For protocol-relative links
+ if ($protocol === '')
+ {
+ $base_url = substr($base_url, strpos($base_url, '//'));
+ }
+ else
+ {
+ $base_url = $protocol.substr($base_url, strpos($base_url, '://'));
+ }
}
return $base_url.ltrim($this->_uri_string($uri), '/');
diff --git a/system/core/Exceptions.php b/system/core/Exceptions.php
index fc25f57e6..d8f62c0fe 100644
--- a/system/core/Exceptions.php
+++ b/system/core/Exceptions.php
@@ -187,7 +187,7 @@ class CI_Exceptions {
// --------------------------------------------------------------------
- public function show_exception(Exception $exception)
+ public function show_exception($exception)
{
$templates_path = config_item('error_views_path');
if (empty($templates_path))
diff --git a/system/core/Input.php b/system/core/Input.php
index e1319be8d..4e7a4e95e 100644
--- a/system/core/Input.php
+++ b/system/core/Input.php
@@ -153,6 +153,12 @@ class CI_Input {
// Sanitize global arrays
$this->_sanitize_globals();
+ // CSRF Protection check
+ if ($this->_enable_csrf === TRUE && ! is_cli())
+ {
+ $this->security->csrf_verify();
+ }
+
log_message('info', 'Input Class Initialized');
}
@@ -600,7 +606,7 @@ class CI_Input {
{
$_GET = array();
}
- elseif (is_array($_GET) && count($_GET) > 0)
+ elseif (is_array($_GET))
{
foreach ($_GET as $key => $val)
{
@@ -609,7 +615,7 @@ class CI_Input {
}
// Clean $_POST Data
- if (is_array($_POST) && count($_POST) > 0)
+ if (is_array($_POST))
{
foreach ($_POST as $key => $val)
{
@@ -618,7 +624,7 @@ class CI_Input {
}
// Clean $_COOKIE Data
- if (is_array($_COOKIE) && count($_COOKIE) > 0)
+ if (is_array($_COOKIE))
{
// Also get rid of specially treated cookies that might be set by a server
// or silly application, that are of no use to a CI application anyway
@@ -647,12 +653,6 @@ class CI_Input {
// Sanitize PHP_SELF
$_SERVER['PHP_SELF'] = strip_tags($_SERVER['PHP_SELF']);
- // CSRF Protection check
- if ($this->_enable_csrf === TRUE && ! is_cli())
- {
- $this->security->csrf_verify();
- }
-
log_message('debug', 'Global POST, GET and COOKIE data sanitized');
}
@@ -803,7 +803,7 @@ class CI_Input {
if ( ! isset($headers))
{
- empty($this->headers) OR $this->request_headers();
+ empty($this->headers) && $this->request_headers();
foreach ($this->headers as $key => $value)
{
$headers[strtolower($key)] = $value;
diff --git a/system/core/Loader.php b/system/core/Loader.php
index 5de7a9483..18e4c5287 100644
--- a/system/core/Loader.php
+++ b/system/core/Loader.php
@@ -290,7 +290,7 @@ class CI_Loader {
load_class('Model', 'core');
}
- $model = ucfirst(strtolower($model));
+ $model = ucfirst($model);
if ( ! class_exists($model))
{
foreach ($this->_ci_model_paths as $mod_path)
diff --git a/system/core/Router.php b/system/core/Router.php
index eb868cd5b..a84be1f1d 100644
--- a/system/core/Router.php
+++ b/system/core/Router.php
@@ -153,6 +153,28 @@ class CI_Router {
*/
protected function _set_routing()
{
+ // Load the routes.php file. It would be great if we could
+ // skip this for enable_query_strings = TRUE, but then
+ // default_controller would be empty ...
+ if (file_exists(APPPATH.'config/routes.php'))
+ {
+ include(APPPATH.'config/routes.php');
+ }
+
+ if (file_exists(APPPATH.'config/'.ENVIRONMENT.'/routes.php'))
+ {
+ include(APPPATH.'config/'.ENVIRONMENT.'/routes.php');
+ }
+
+ // Validate & get reserved routes
+ if (isset($route) && is_array($route))
+ {
+ isset($route['default_controller']) && $this->default_controller = $route['default_controller'];
+ isset($route['translate_uri_dashes']) && $this->translate_uri_dashes = $route['translate_uri_dashes'];
+ unset($route['default_controller'], $route['translate_uri_dashes']);
+ $this->routes = $route;
+ }
+
// Are query strings enabled in the config file? Normally CI doesn't utilize query strings
// since URI segments are more search-engine friendly, but they can optionally be used.
// If this feature is enabled, we will gather the directory/class/method a little differently
@@ -199,26 +221,6 @@ class CI_Router {
return;
}
- // Load the routes.php file.
- if (file_exists(APPPATH.'config/routes.php'))
- {
- include(APPPATH.'config/routes.php');
- }
-
- if (file_exists(APPPATH.'config/'.ENVIRONMENT.'/routes.php'))
- {
- include(APPPATH.'config/'.ENVIRONMENT.'/routes.php');
- }
-
- // Validate & get reserved routes
- if (isset($route) && is_array($route))
- {
- isset($route['default_controller']) && $this->default_controller = $route['default_controller'];
- isset($route['translate_uri_dashes']) && $this->translate_uri_dashes = $route['translate_uri_dashes'];
- unset($route['default_controller'], $route['translate_uri_dashes']);
- $this->routes = $route;
- }
-
// Is there anything to parse?
if ($this->uri->uri_string !== '')
{
diff --git a/system/core/Security.php b/system/core/Security.php
index 7c5199255..ab85e2239 100644
--- a/system/core/Security.php
+++ b/system/core/Security.php
@@ -436,7 +436,7 @@ class CI_Security {
$words = array(
'javascript', 'expression', 'vbscript', 'jscript', 'wscript',
'vbs', 'script', 'base64', 'applet', 'alert', 'document',
- 'write', 'cookie', 'window', 'confirm', 'prompt'
+ 'write', 'cookie', 'window', 'confirm', 'prompt', 'eval'
);
foreach ($words as $word)
@@ -480,12 +480,8 @@ class CI_Security {
}
}
while ($original !== $str);
-
unset($original);
- // Remove evil attributes such as style, onclick and xmlns
- $str = $this->_remove_evil_attributes($str, $is_image);
-
/*
* Sanitize naughty HTML elements
*
@@ -495,8 +491,29 @@ class CI_Security {
* So this: <blink>
* Becomes: &lt;blink&gt;
*/
- $naughty = 'alert|prompt|confirm|applet|audio|basefont|base|behavior|bgsound|blink|body|embed|expression|form|frameset|frame|head|html|ilayer|iframe|input|button|select|isindex|layer|link|meta|keygen|object|plaintext|style|script|textarea|title|math|video|svg|xml|xss';
- $str = preg_replace_callback('#<(/*\s*)('.$naughty.')([^><]*)([><]*)#is', array($this, '_sanitize_naughty_html'), $str);
+ $pattern = '#'
+ .'<((?<slash>/*\s*)(?<tagName>[a-z0-9]+)(?=[^a-z0-9]|$)' // tag start and name, followed by a non-tag character
+ .'[^\s\042\047a-z0-9>/=]*' // a valid attribute character immediately after the tag would count as a separator
+ // optional attributes
+ .'(?<attributes>(?:[\s\042\047/=]*' // non-attribute characters, excluding > (tag close) for obvious reasons
+ .'[^\s\042\047>/=]+' // attribute characters
+ // optional attribute-value
+ .'(?:\s*=' // attribute-value separator
+ .'(?:[^\s\042\047=><`]+|\s*\042[^\042]*\042|\s*\047[^\047]*\047|\s*(?U:[^\s\042\047=><`]*))' // single, double or non-quoted value
+ .')?' // end optional attribute-value group
+ .')*)' // end optional attributes group
+ .'[^>]*)(?<closeTag>\>)?#isS';
+
+ // Note: It would be nice to optimize this for speed, BUT
+ // only matching the naughty elements here results in
+ // false positives and in turn - vulnerabilities!
+ do
+ {
+ $old_str = $str;
+ $str = preg_replace_callback($pattern, array($this, '_sanitize_naughty_html'), $str);
+ }
+ while ($old_str !== $str);
+ unset($old_str);
/*
* Sanitize naughty scripting elements
@@ -510,9 +527,11 @@ class CI_Security {
* For example: eval('some code')
* Becomes: eval&#40;'some code'&#41;
*/
- $str = preg_replace('#(alert|prompt|confirm|cmd|passthru|eval|exec|expression|system|fopen|fsockopen|file|file_get_contents|readfile|unlink)(\s*)\((.*?)\)#si',
- '\\1\\2&#40;\\3&#41;',
- $str);
+ $str = preg_replace(
+ '#(alert|prompt|confirm|cmd|passthru|eval|exec|expression|system|fopen|fsockopen|file|file_get_contents|readfile|unlink)(\s*)\((.*?)\)#si',
+ '\\1\\2&#40;\\3&#41;',
+ $str
+ );
// Final clean up
// This adds a bit of extra precaution in case
@@ -750,58 +769,6 @@ class CI_Security {
// --------------------------------------------------------------------
/**
- * Remove Evil HTML Attributes (like event handlers and style)
- *
- * It removes the evil attribute and either:
- *
- * - Everything up until a space. For example, everything between the pipes:
- *
- * <code>
- * <a |style=document.write('hello');alert('world');| class=link>
- * </code>
- *
- * - Everything inside the quotes. For example, everything between the pipes:
- *
- * <code>
- * <a |style="document.write('hello'); alert('world');"| class="link">
- * </code>
- *
- * @param string $str The string to check
- * @param bool $is_image Whether the input is an image
- * @return string The string with the evil attributes removed
- */
- protected function _remove_evil_attributes($str, $is_image)
- {
- $evil_attributes = array('on\w*', 'style', 'xmlns', 'formaction', 'form', 'xlink:href', 'FSCommand', 'seekSegmentTime');
-
- if ($is_image === TRUE)
- {
- /*
- * Adobe Photoshop puts XML metadata into JFIF images,
- * including namespacing, so we have to allow this for images.
- */
- unset($evil_attributes[array_search('xmlns', $evil_attributes)]);
- }
-
- do {
- $count = $temp_count = 0;
-
- // replace occurrences of illegal attribute strings with quotes (042 and 047 are octal quotes)
- $str = preg_replace('/(<[^>]+)(?<!\w)('.implode('|', $evil_attributes).')\s*=\s*(\042|\047)([^\\2]*?)(\\2)/is', '$1[removed]', $str, -1, $temp_count);
- $count += $temp_count;
-
- // find occurrences of illegal attribute strings without quotes
- $str = preg_replace('/(<[^>]+)(?<!\w)('.implode('|', $evil_attributes).')\s*=\s*([^\s>]*)/is', '$1[removed]', $str, -1, $temp_count);
- $count += $temp_count;
- }
- while ($count);
-
- return $str;
- }
-
- // --------------------------------------------------------------------
-
- /**
* Sanitize Naughty HTML
*
* Callback method for xss_clean() to remove naughty HTML elements.
@@ -812,9 +779,70 @@ class CI_Security {
*/
protected function _sanitize_naughty_html($matches)
{
- return '&lt;'.$matches[1].$matches[2].$matches[3] // encode opening brace
- // encode captured opening or closing brace to prevent recursive vectors:
- .str_replace(array('>', '<'), array('&gt;', '&lt;'), $matches[4]);
+ static $naughty_tags = array(
+ 'alert', 'prompt', 'confirm', 'applet', 'audio', 'basefont', 'base', 'behavior', 'bgsound',
+ 'blink', 'body', 'embed', 'expression', 'form', 'frameset', 'frame', 'head', 'html', 'ilayer',
+ 'iframe', 'input', 'button', 'select', 'isindex', 'layer', 'link', 'meta', 'keygen', 'object',
+ 'plaintext', 'style', 'script', 'textarea', 'title', 'math', 'video', 'svg', 'xml', 'xss'
+ );
+
+ static $evil_attributes = array(
+ 'on\w+', 'style', 'xmlns', 'formaction', 'form', 'xlink:href', 'FSCommand', 'seekSegmentTime'
+ );
+
+ // First, escape unclosed tags
+ if (empty($matches['closeTag']))
+ {
+ return '&lt;'.$matches[1];
+ }
+ // Is the element that we caught naughty? If so, escape it
+ elseif (in_array(strtolower($matches['tagName']), $naughty_tags, TRUE))
+ {
+ return '&lt;'.$matches[1].'&gt;';
+ }
+ // For other tags, see if their attributes are "evil" and strip those
+ elseif (isset($matches['attributes']))
+ {
+ // We'll need to catch all attributes separately first
+ $pattern = '#'
+ .'([\s\042\047/=]*)' // non-attribute characters, excluding > (tag close) for obvious reasons
+ .'(?<name>[^\s\042\047>/=]+)' // attribute characters
+ // optional attribute-value
+ .'(?:\s*=(?<value>[^\s\042\047=><`]+|\s*\042[^\042]*\042|\s*\047[^\047]*\047|\s*(?U:[^\s\042\047=><`]*)))' // attribute-value separator
+ .'#i';
+
+ if ($count = preg_match_all($pattern, $matches['attributes'], $attributes, PREG_SET_ORDER | PREG_OFFSET_CAPTURE))
+ {
+ // Since we'll be using substr_replace() below, we
+ // need to handle the attributes in reverse order,
+ // so we don't damage the string.
+ for ($i = $count - 1; $i > -1; $i--)
+ {
+ if (
+ // Is it indeed an "evil" attribute?
+ preg_match('#^('.implode('|', $evil_attributes).')$#i', $attributes[$i]['name'][0])
+ // Or an attribute not starting with a letter? Some parsers get confused by that
+ OR ! ctype_alpha($attributes[$i]['name'][0][0])
+ // Does it have an equals sign, but no value and not quoted? Strip that too!
+ OR (trim($attributes[$i]['value'][0]) === '')
+ )
+ {
+ $matches['attributes'] = substr_replace(
+ $matches['attributes'],
+ ' [removed]',
+ $attributes[$i][0][1],
+ strlen($attributes[$i][0][0])
+ );
+ }
+ }
+
+ // Note: This will strip some non-space characters and/or
+ // reduce multiple spaces between attributes.
+ return '<'.$matches['slash'].$matches['tagName'].' '.trim($matches['attributes']).'>';
+ }
+ }
+
+ return $matches[0];
}
// --------------------------------------------------------------------
@@ -834,12 +862,15 @@ class CI_Security {
*/
protected function _js_link_removal($match)
{
- return str_replace($match[1],
- preg_replace('#href=.*?(?:(?:alert|prompt|confirm)(?:\(|&\#40;)|javascript:|livescript:|mocha:|charset=|window\.|document\.|\.cookie|<script|<xss|data\s*:)#si',
- '',
- $this->_filter_attributes(str_replace(array('<', '>'), '', $match[1]))
- ),
- $match[0]);
+ return str_replace(
+ $match[1],
+ preg_replace(
+ '#href=.*?(?:(?:alert|prompt|confirm)(?:\(|&\#40;)|javascript:|livescript:|mocha:|charset=|window\.|document\.|\.cookie|<script|<xss|data\s*:)#si',
+ '',
+ $this->_filter_attributes($match[1])
+ ),
+ $match[0]
+ );
}
// --------------------------------------------------------------------
@@ -859,12 +890,15 @@ class CI_Security {
*/
protected function _js_img_removal($match)
{
- return str_replace($match[1],
- preg_replace('#src=.*?(?:(?:alert|prompt|confirm)(?:\(|&\#40;)|javascript:|livescript:|mocha:|charset=|window\.|document\.|\.cookie|<script|<xss|base64\s*,)#si',
- '',
- $this->_filter_attributes(str_replace(array('<', '>'), '', $match[1]))
- ),
- $match[0]);
+ return str_replace(
+ $match[1],
+ preg_replace(
+ '#src=.*?(?:(?:alert|prompt|confirm|eval)(?:\(|&\#40;)|javascript:|livescript:|mocha:|charset=|window\.|document\.|\.cookie|<script|<xss|base64\s*,)#si',
+ '',
+ $this->_filter_attributes($match[1])
+ ),
+ $match[0]
+ );
}
// --------------------------------------------------------------------
diff --git a/system/database/DB_driver.php b/system/database/DB_driver.php
index 34d3a5979..cc94edc16 100644
--- a/system/database/DB_driver.php
+++ b/system/database/DB_driver.php
@@ -791,10 +791,13 @@ abstract class CI_DB_driver {
/**
* Enable/disable Transaction Strict Mode
+ *
* When strict mode is enabled, if you are running multiple groups of
- * transactions, if one group fails all groups will be rolled back.
- * If strict mode is disabled, each group is treated autonomously, meaning
- * a failure of one group will not affect any others
+ * transactions, if one group fails all subsequent groups will be
+ * rolled back.
+ *
+ * If strict mode is disabled, each group is treated autonomously,
+ * meaning a failure of one group will not affect any others
*
* @param bool $mode = TRUE
* @return void
@@ -861,8 +864,8 @@ abstract class CI_DB_driver {
$this->trans_rollback();
// If we are NOT running in strict mode, we will reset
- // the _trans_status flag so that subsequent groups of transactions
- // will be permitted.
+ // the _trans_status flag so that subsequent groups of
+ // transactions will be permitted.
if ($this->trans_strict === FALSE)
{
$this->_trans_status = TRUE;
@@ -1480,18 +1483,18 @@ abstract class CI_DB_driver {
? '\s+'.preg_quote(trim(sprintf($this->_like_escape_str, $this->_like_escape_chr)), '/')
: '';
$_operators = array(
- '\s*(?:<|>|!)?=\s*', // =, <=, >=, !=
- '\s*<>?\s*', // <, <>
- '\s*>\s*', // >
- '\s+IS NULL', // IS NULL
- '\s+IS NOT NULL', // IS NOT NULL
- '\s+EXISTS\s*\([^\)]+\)', // EXISTS(sql)
- '\s+NOT EXISTS\s*\([^\)]+\)', // NOT EXISTS(sql)
- '\s+BETWEEN\s+\S+\s+AND\s+\S+', // BETWEEN value AND value
- '\s+IN\s*\([^\)]+\)', // IN(list)
- '\s+NOT IN\s*\([^\)]+\)', // NOT IN (list)
- '\s+LIKE\s+\S+'.$_les, // LIKE 'expr'[ ESCAPE '%s']
- '\s+NOT LIKE\s+\S+'.$_les // NOT LIKE 'expr'[ ESCAPE '%s']
+ '\s*(?:<|>|!)?=\s*', // =, <=, >=, !=
+ '\s*<>?\s*', // <, <>
+ '\s*>\s*', // >
+ '\s+IS NULL', // IS NULL
+ '\s+IS NOT NULL', // IS NOT NULL
+ '\s+EXISTS\s*\([^\)]+\)', // EXISTS(sql)
+ '\s+NOT EXISTS\s*\([^\)]+\)', // NOT EXISTS(sql)
+ '\s+BETWEEN\s+', // BETWEEN value AND value
+ '\s+IN\s*\([^\)]+\)', // IN(list)
+ '\s+NOT IN\s*\([^\)]+\)', // NOT IN (list)
+ '\s+LIKE\s+\S.*('.$_les.')?', // LIKE 'expr'[ ESCAPE '%s']
+ '\s+NOT LIKE\s+\S.*('.$_les.')?' // NOT LIKE 'expr'[ ESCAPE '%s']
);
}
@@ -1760,7 +1763,7 @@ abstract class CI_DB_driver {
}
// Convert tabs or multiple spaces into single spaces
- $item = preg_replace('/\s+/', ' ', $item);
+ $item = preg_replace('/\s+/', ' ', trim($item));
// If the item has an alias declaration we remove it and set it aside.
// Note: strripos() is used in order to support spaces in table names
diff --git a/system/database/DB_query_builder.php b/system/database/DB_query_builder.php
index 7f3334763..cf1100d27 100644
--- a/system/database/DB_query_builder.php
+++ b/system/database/DB_query_builder.php
@@ -2342,7 +2342,7 @@ abstract class CI_DB_query_builder extends CI_DB_driver {
// Split multiple conditions
$conditions = preg_split(
- '/((^|\s+)AND\s+|(^|\s+)OR\s+)/i',
+ '/((?:^|\s+)AND\s+|(?:^|\s+)OR\s+)/i',
$this->{$qb_key}[$i]['condition'],
-1,
PREG_SPLIT_DELIM_CAPTURE | PREG_SPLIT_NO_EMPTY
diff --git a/system/database/drivers/mssql/mssql_driver.php b/system/database/drivers/mssql/mssql_driver.php
index 8f15d8d69..05e5418c3 100644
--- a/system/database/drivers/mssql/mssql_driver.php
+++ b/system/database/drivers/mssql/mssql_driver.php
@@ -381,9 +381,19 @@ class CI_DB_mssql_driver extends CI_DB {
*/
public function error()
{
- $query = $this->query('SELECT @@ERROR AS code');
- $query = $query->row();
- return array('code' => $query->code, 'message' => mssql_get_last_message());
+ // We need this because the error info is discarded by the
+ // server the first time you request it, and query() already
+ // calls error() once for logging purposes when a query fails.
+ static $error = array('code' => 0, 'message' => NULL);
+
+ $message = mssql_get_last_message();
+ if ( ! empty($message))
+ {
+ $error['code'] = $this->query('SELECT @@ERROR AS code')->row()->code;
+ $error['message'] = $message;
+ }
+
+ return $error;
}
// --------------------------------------------------------------------
diff --git a/system/database/drivers/sqlsrv/sqlsrv_driver.php b/system/database/drivers/sqlsrv/sqlsrv_driver.php
index 16f77fab2..8d383b274 100644
--- a/system/database/drivers/sqlsrv/sqlsrv_driver.php
+++ b/system/database/drivers/sqlsrv/sqlsrv_driver.php
@@ -141,13 +141,14 @@ class CI_DB_sqlsrv_driver extends CI_DB {
unset($connection['UID'], $connection['PWD']);
}
- $this->conn_id = sqlsrv_connect($this->hostname, $connection);
-
- // Determine how identifiers are escaped
- $query = $this->query('SELECT CASE WHEN (@@OPTIONS | 256) = @@OPTIONS THEN 1 ELSE 0 END AS qi');
- $query = $query->row_array();
- $this->_quoted_identifier = empty($query) ? FALSE : (bool) $query['qi'];
- $this->_escape_char = ($this->_quoted_identifier) ? '"' : array('[', ']');
+ if (FALSE !== ($this->conn_id = sqlsrv_connect($this->hostname, $connection)))
+ {
+ // Determine how identifiers are escaped
+ $query = $this->query('SELECT CASE WHEN (@@OPTIONS | 256) = @@OPTIONS THEN 1 ELSE 0 END AS qi');
+ $query = $query->row_array();
+ $this->_quoted_identifier = empty($query) ? FALSE : (bool) $query['qi'];
+ $this->_escape_char = ($this->_quoted_identifier) ? '"' : array('[', ']');
+ }
return $this->conn_id;
}
diff --git a/system/helpers/file_helper.php b/system/helpers/file_helper.php
index cd1c641ec..f6cb1629a 100644
--- a/system/helpers/file_helper.php
+++ b/system/helpers/file_helper.php
@@ -343,7 +343,7 @@ if ( ! function_exists('get_mime_by_extension'))
if ( ! is_array($mimes))
{
- $mimes =& get_mimes();
+ $mimes = get_mimes();
if (empty($mimes))
{
diff --git a/system/libraries/Cache/drivers/Cache_file.php b/system/libraries/Cache/drivers/Cache_file.php
index 68bc1ec96..c046f3b7d 100644
--- a/system/libraries/Cache/drivers/Cache_file.php
+++ b/system/libraries/Cache/drivers/Cache_file.php
@@ -267,7 +267,7 @@ class CI_Cache_file extends CI_Driver {
*/
protected function _get($id)
{
- if ( ! file_exists($this->_cache_path.$id))
+ if ( ! is_file($this->_cache_path.$id))
{
return FALSE;
}
diff --git a/system/libraries/Cache/drivers/Cache_memcached.php b/system/libraries/Cache/drivers/Cache_memcached.php
index 111e2109d..59cf4685d 100644
--- a/system/libraries/Cache/drivers/Cache_memcached.php
+++ b/system/libraries/Cache/drivers/Cache_memcached.php
@@ -106,7 +106,7 @@ class CI_Cache_memcached extends CI_Driver {
}
else
{
- throw new RuntimeException('Cache: Failed to create Memcache(d) object; extension not loaded?');
+ log_message('error', 'Cache: Failed to create Memcache(d) object; extension not loaded?');
}
foreach ($this->_memcache_conf as $cache_server)
@@ -284,12 +284,6 @@ class CI_Cache_memcached extends CI_Driver {
*/
public function is_supported()
{
- if ( ! extension_loaded('memcached') && ! extension_loaded('memcache'))
- {
- log_message('debug', 'The Memcached Extension must be loaded to use Memcached Cache.');
- return FALSE;
- }
-
- return TRUE;
+ return (extension_loaded('memcached') OR extension_loaded('memcache'));
}
}
diff --git a/system/libraries/Cache/drivers/Cache_redis.php b/system/libraries/Cache/drivers/Cache_redis.php
index d7dca1973..ea0059ff7 100644
--- a/system/libraries/Cache/drivers/Cache_redis.php
+++ b/system/libraries/Cache/drivers/Cache_redis.php
@@ -115,17 +115,17 @@ class CI_Cache_redis extends CI_Driver
if ( ! $success)
{
- throw new RuntimeException('Cache: Redis connection failed. Check your configuration.');
+ log_message('error', 'Cache: Redis connection failed. Check your configuration.');
+ }
+
+ if (isset($config['password']) && ! $this->_redis->auth($config['password']))
+ {
+ log_message('error', 'Cache: Redis authentication failed.');
}
}
catch (RedisException $e)
{
- throw new RuntimeException('Cache: Redis connection refused ('.$e->getMessage().')');
- }
-
- if (isset($config['password']) && ! $this->_redis->auth($config['password']))
- {
- throw new RuntimeException('Cache: Redis authentication failed.');
+ log_message('error', 'Cache: Redis connection refused ('.$e->getMessage().')');
}
// Initialize the index of serialized values.
@@ -298,13 +298,7 @@ class CI_Cache_redis extends CI_Driver
*/
public function is_supported()
{
- if ( ! extension_loaded('redis'))
- {
- log_message('debug', 'The Redis extension must be loaded to use Redis cache.');
- return FALSE;
- }
-
- return TRUE;
+ return extension_loaded('redis');
}
// ------------------------------------------------------------------------
diff --git a/system/libraries/Email.php b/system/libraries/Email.php
index 459c8f590..acf3629c3 100644
--- a/system/libraries/Email.php
+++ b/system/libraries/Email.php
@@ -1869,20 +1869,26 @@ class CI_Email {
return FALSE;
}
- $this->_send_command('from', $this->clean_email($this->_headers['From']));
+ if ( ! $this->_send_command('from', $this->clean_email($this->_headers['From'])))
+ {
+ return FALSE;
+ }
foreach ($this->_recipients as $val)
{
- $this->_send_command('to', $val);
+ if ( ! $this->_send_command('to', $val))
+ {
+ return FALSE;
+ }
}
if (count($this->_cc_array) > 0)
{
foreach ($this->_cc_array as $val)
{
- if ($val !== '')
+ if ($val !== '' && ! $this->_send_command('to', $val))
{
- $this->_send_command('to', $val);
+ return FALSE;
}
}
}
@@ -1891,14 +1897,17 @@ class CI_Email {
{
foreach ($this->_bcc_array as $val)
{
- if ($val !== '')
+ if ($val !== '' && ! $this->_send_command('to', $val))
{
- $this->_send_command('to', $val);
+ return FALSE;
}
}
}
- $this->_send_command('data');
+ if ( ! $this->_send_command('data'))
+ {
+ return FALSE;
+ }
// perform dot transformation on any lines that begin with a dot
$this->_send_data($this->_header_str.preg_replace('/^\./m', '..$1', $this->_finalbody));
diff --git a/system/libraries/Pagination.php b/system/libraries/Pagination.php
index 5b3aa01f4..4d18998b9 100644
--- a/system/libraries/Pagination.php
+++ b/system/libraries/Pagination.php
@@ -571,7 +571,7 @@ class CI_Pagination {
{
$i = ($this->use_page_numbers) ? $uri_page_number - 1 : $uri_page_number - $this->per_page;
- $attributes = sprintf('%s %s="%d"', $this->_attributes, $this->data_page_attr, (int) $i);
+ $attributes = sprintf('%s %s="%d"', $this->_attributes, $this->data_page_attr, ($this->cur_page - 1));
if ($i === $base_page)
{
@@ -592,11 +592,11 @@ class CI_Pagination {
if ($this->display_pages !== FALSE)
{
// Write the digit links
- for ($loop = $start -1; $loop <= $end; $loop++)
+ for ($loop = $start - 1; $loop <= $end; $loop++)
{
$i = ($this->use_page_numbers) ? $loop : ($loop * $this->per_page) - $this->per_page;
- $attributes = sprintf('%s %s="%d"', $this->_attributes, $this->data_page_attr, (int) $i);
+ $attributes = sprintf('%s %s="%d"', $this->_attributes, $this->data_page_attr, $loop);
if ($i >= $base_page)
{
@@ -614,7 +614,7 @@ class CI_Pagination {
else
{
$append = $this->prefix.$i.$this->suffix;
- $output .= $this->num_tag_open.'<a href="'.$base_url.$append.'"'.$attributes.$this->_attr_rel('start').'>'
+ $output .= $this->num_tag_open.'<a href="'.$base_url.$append.'"'.$attributes.'>'
.$loop.'</a>'.$this->num_tag_close;
}
}
@@ -626,7 +626,7 @@ class CI_Pagination {
{
$i = ($this->use_page_numbers) ? $this->cur_page + 1 : $this->cur_page * $this->per_page;
- $attributes = sprintf('%s %s="%d"', $this->_attributes, $this->data_page_attr, (int) $i);
+ $attributes = sprintf('%s %s="%d"', $this->_attributes, $this->data_page_attr, $this->cur_page + 1);
$output .= $this->next_tag_open.'<a href="'.$base_url.$this->prefix.$i.$this->suffix.'"'.$attributes
.$this->_attr_rel('next').'>'.$this->next_link.'</a>'.$this->next_tag_close;
@@ -637,7 +637,7 @@ class CI_Pagination {
{
$i = ($this->use_page_numbers) ? $num_pages : ($num_pages * $this->per_page) - $this->per_page;
- $attributes = sprintf('%s %s="%d"', $this->_attributes, $this->data_page_attr, (int) $i);
+ $attributes = sprintf('%s %s="%d"', $this->_attributes, $this->data_page_attr, $num_pages);
$output .= $this->last_tag_open.'<a href="'.$base_url.$this->prefix.$i.$this->suffix.'"'.$attributes.'>'
.$this->last_link.'</a>'.$this->last_tag_close;