summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--system/core/CodeIgniter.php2
-rw-r--r--system/core/Security.php18
-rw-r--r--system/database/DB_query_builder.php51
-rw-r--r--system/database/drivers/oci8/oci8_driver.php15
-rw-r--r--system/database/drivers/postgre/postgre_driver.php7
-rw-r--r--system/libraries/Email.php18
-rw-r--r--system/libraries/Form_validation.php2
-rw-r--r--system/libraries/Image_lib.php5
-rw-r--r--system/libraries/Xmlrpc.php2
9 files changed, 81 insertions, 39 deletions
diff --git a/system/core/CodeIgniter.php b/system/core/CodeIgniter.php
index 962196b6b..4ad513dd6 100644
--- a/system/core/CodeIgniter.php
+++ b/system/core/CodeIgniter.php
@@ -55,7 +55,7 @@ defined('BASEPATH') OR exit('No direct script access allowed');
* @var string
*
*/
- const CI_VERSION = '3.1.7';
+ const CI_VERSION = '3.1.8';
/*
* ------------------------------------------------------
diff --git a/system/core/Security.php b/system/core/Security.php
index 6cdce5d98..31926b466 100644
--- a/system/core/Security.php
+++ b/system/core/Security.php
@@ -134,7 +134,9 @@ class CI_Security {
*/
protected $_never_allowed_str = array(
'document.cookie' => '[removed]',
+ '(document).cookie' => '[removed]',
'document.write' => '[removed]',
+ '(document).write' => '[removed]',
'.parentNode' => '[removed]',
'.innerHTML' => '[removed]',
'-moz-binding' => '[removed]',
@@ -152,7 +154,7 @@ class CI_Security {
*/
protected $_never_allowed_regex = array(
'javascript\s*:',
- '(document|(document\.)?window)\.(location|on\w*)',
+ '(\(?document\)?|\(?window\)?(\.document)?)\.(location|on\w*)',
'expression\s*(\(|&\#40;)', // CSS and IE
'vbscript\s*:', // IE, surprise!
'wscript\s*:', // IE
@@ -542,6 +544,14 @@ class CI_Security {
$str
);
+ // Same thing, but for "tag functions" (e.g. eval`some code`)
+ // See https://github.com/bcit-ci/CodeIgniter/issues/5420
+ $str = preg_replace(
+ '#(alert|prompt|confirm|cmd|passthru|eval|exec|expression|system|fopen|fsockopen|file|file_get_contents|readfile|unlink)(\s*)`(.*?)`#si',
+ '\\1\\2`\\3`',
+ $str
+ );
+
// Final clean up
// This adds a bit of extra precaution in case
// something got through the above filters
@@ -853,7 +863,7 @@ class CI_Security {
// For other tags, see if their attributes are "evil" and strip those
elseif (isset($matches['attributes']))
{
- // We'll store the already fitlered attributes here
+ // We'll store the already filtered attributes here
$attributes = array();
// Attribute-catching pattern
@@ -927,7 +937,7 @@ class CI_Security {
return str_replace(
$match[1],
preg_replace(
- '#href=.*?(?:(?:alert|prompt|confirm)(?:\(|&\#40;)|javascript:|livescript:|mocha:|charset=|window\.|document\.|\.cookie|<script|<xss|d\s*a\s*t\s*a\s*:)#si',
+ '#href=.*?(?:(?:alert|prompt|confirm)(?:\(|&\#40;|`|&\#96;)|javascript:|livescript:|mocha:|charset=|window\.|\(?document\)?\.|\.cookie|<script|<xss|d\s*a\s*t\s*a\s*:)#si',
'',
$this->_filter_attributes($match[1])
),
@@ -955,7 +965,7 @@ class CI_Security {
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',
+ '#src=.*?(?:(?:alert|prompt|confirm|eval)(?:\(|&\#40;|`|&\#96;)|javascript:|livescript:|mocha:|charset=|window\.|\(?document\)?\.|\.cookie|<script|<xss|base64\s*,)#si',
'',
$this->_filter_attributes($match[1])
),
diff --git a/system/database/DB_query_builder.php b/system/database/DB_query_builder.php
index b9bbb5016..8f477e3a1 100644
--- a/system/database/DB_query_builder.php
+++ b/system/database/DB_query_builder.php
@@ -680,7 +680,7 @@ abstract class CI_DB_query_builder extends CI_DB_driver {
{
if ($escape === TRUE)
{
- $v = ' '.$this->escape($v);
+ $v = $this->escape($v);
}
if ( ! $this->_has_operator($k))
@@ -698,10 +698,11 @@ abstract class CI_DB_query_builder extends CI_DB_driver {
$k = substr($k, 0, $match[0][1]).($match[1][0] === '=' ? ' IS NULL' : ' IS NOT NULL');
}
- $this->{$qb_key}[] = array('condition' => $prefix.$k.$v, 'escape' => $escape);
+ ${$qb_key} = array('condition' => $prefix.$k, 'value' => $v, 'escape' => $escape);
+ $this->{$qb_key}[] = ${$qb_key};
if ($this->qb_caching === TRUE)
{
- $this->{$qb_cache_key}[] = array('condition' => $prefix.$k.$v, 'escape' => $escape);
+ $this->{$qb_cache_key}[] = ${$qb_key};
$this->qb_cache_exists[] = substr($qb_key, 3);
}
@@ -834,6 +835,7 @@ abstract class CI_DB_query_builder extends CI_DB_driver {
$where_in = array(
'condition' => $prefix.$key.$not.' IN('.implode(', ', $where_in).')',
+ 'value' => NULL,
'escape' => $escape
);
@@ -962,33 +964,34 @@ abstract class CI_DB_query_builder extends CI_DB_driver {
$v = $this->escape_like_str($v);
}
- if ($side === 'none')
+ switch ($side)
{
- $like_statement = "{$prefix} {$k} {$not} LIKE '{$v}'";
- }
- elseif ($side === 'before')
- {
- $like_statement = "{$prefix} {$k} {$not} LIKE '%{$v}'";
- }
- elseif ($side === 'after')
- {
- $like_statement = "{$prefix} {$k} {$not} LIKE '{$v}%'";
- }
- else
- {
- $like_statement = "{$prefix} {$k} {$not} LIKE '%{$v}%'";
+ case 'none':
+ $v = "'{$v}'";
+ break;
+ case 'before':
+ $v = "%'{$v}'";
+ break;
+ case 'after':
+ $v = "'{$v}%'";
+ break;
+ case 'both':
+ default:
+ $v = "'%{$v}%'";
+ break;
}
// some platforms require an escape sequence definition for LIKE wildcards
if ($escape === TRUE && $this->_like_escape_str !== '')
{
- $like_statement .= sprintf($this->_like_escape_str, $this->_like_escape_chr);
+ $v .= sprintf($this->_like_escape_str, $this->_like_escape_chr);
}
- $this->qb_where[] = array('condition' => $like_statement, 'escape' => $escape);
+ $qb_where = array('condition' => "{$prefix} {$k} {$not} LIKE", 'value' => $v, 'escape' => $escape);
+ $this->qb_where[] = $qb_where;
if ($this->qb_caching === TRUE)
{
- $this->qb_cache_where[] = array('condition' => $like_statement, 'escape' => $escape);
+ $this->qb_cache_where[] = $qb_where;
$this->qb_cache_exists[] = 'where';
}
}
@@ -1013,6 +1016,7 @@ abstract class CI_DB_query_builder extends CI_DB_driver {
$prefix = (count($this->qb_where) === 0 && count($this->qb_cache_where) === 0) ? '' : $type;
$where = array(
'condition' => $prefix.$not.str_repeat(' ', ++$this->qb_where_group_count).' (',
+ 'value' => NULL,
'escape' => FALSE
);
@@ -1073,6 +1077,7 @@ abstract class CI_DB_query_builder extends CI_DB_driver {
$this->qb_where_group_started = FALSE;
$where = array(
'condition' => str_repeat(' ', $this->qb_where_group_count--).')',
+ 'value' => NULL,
'escape' => FALSE
);
@@ -1433,7 +1438,7 @@ abstract class CI_DB_query_builder extends CI_DB_driver {
// --------------------------------------------------------------------
/**
- * Get_Where
+ * get_where()
*
* Allows the where clause, limit and offset to be added directly
*
@@ -2395,7 +2400,7 @@ abstract class CI_DB_query_builder extends CI_DB_driver {
}
elseif ($this->{$qb_key}[$i]['escape'] === FALSE)
{
- $this->{$qb_key}[$i] = $this->{$qb_key}[$i]['condition'];
+ $this->{$qb_key}[$i] = $this->{$qb_key}[$i]['condition'].(isset($this->{$qb_key}[$i]['value']) ? ' '.$this->{$qb_key}[$i]['value'] : '');
continue;
}
@@ -2434,7 +2439,7 @@ abstract class CI_DB_query_builder extends CI_DB_driver {
.' '.trim($matches[3]).$matches[4].$matches[5];
}
- $this->{$qb_key}[$i] = implode('', $conditions);
+ $this->{$qb_key}[$i] = implode('', $conditions).(isset($this->{$qb_key}[$i]['value']) ? ' '.$this->{$qb_key}[$i]['value'] : '');
}
return ($qb_key === 'qb_having' ? "\nHAVING " : "\nWHERE ")
diff --git a/system/database/drivers/oci8/oci8_driver.php b/system/database/drivers/oci8/oci8_driver.php
index 1bd977390..b90db4bd2 100644
--- a/system/database/drivers/oci8/oci8_driver.php
+++ b/system/database/drivers/oci8/oci8_driver.php
@@ -97,7 +97,7 @@ class CI_DB_oci8_driver extends CI_DB {
*
* @var bool
*/
- public $limit_used;
+ public $limit_used = FALSE;
// --------------------------------------------------------------------
@@ -685,4 +685,17 @@ class CI_DB_oci8_driver extends CI_DB {
oci_close($this->conn_id);
}
+ // --------------------------------------------------------------------
+
+ /**
+ * We need to reset our $limit_used hack flag, so it doesn't propagate
+ * to subsequent queries.
+ *
+ * @return void
+ */
+ protected function _reset_select()
+ {
+ $this->limit_used = FALSE;
+ parent::_reset_select();
+ }
}
diff --git a/system/database/drivers/postgre/postgre_driver.php b/system/database/drivers/postgre/postgre_driver.php
index 7fb258abb..5779c8783 100644
--- a/system/database/drivers/postgre/postgre_driver.php
+++ b/system/database/drivers/postgre/postgre_driver.php
@@ -224,8 +224,8 @@ class CI_DB_postgre_driver extends CI_DB {
* and so we'll have to fall back to running a query in
* order to get it.
*/
- return isset($pg_version['server'])
- ? $this->data_cache['version'] = $pg_version['server']
+ return (isset($pg_version['server']) && preg_match('#^(\d+\.\d+)#', $pg_version['server'], $match))
+ ? $this->data_cache['version'] = $match[1]
: parent::version();
}
@@ -354,8 +354,7 @@ class CI_DB_postgre_driver extends CI_DB {
*/
public function insert_id()
{
- $v = pg_version($this->conn_id);
- $v = isset($v['server']) ? $v['server'] : 0; // 'server' key is only available since PosgreSQL 7.4
+ $v = $this->version();
$table = (func_num_args() > 0) ? func_get_arg(0) : NULL;
$column = (func_num_args() > 1) ? func_get_arg(1) : NULL;
diff --git a/system/libraries/Email.php b/system/libraries/Email.php
index 6a8bda70e..a53e7e72a 100644
--- a/system/libraries/Email.php
+++ b/system/libraries/Email.php
@@ -1035,7 +1035,7 @@ class CI_Email {
if (function_exists('idn_to_ascii') && strpos($email, '@'))
{
list($account, $domain) = explode('@', $email, 2);
- $domain = is_php('5.4')
+ $domain = defined('INTL_IDNA_VARIANT_UTS46')
? idn_to_ascii($domain, 0, INTL_IDNA_VARIANT_UTS46)
: idn_to_ascii($domain);
$email = $account.'@'.$domain;
@@ -1856,7 +1856,7 @@ class CI_Email {
if (function_exists('idn_to_ascii') && strpos($email, '@'))
{
list($account, $domain) = explode('@', $email, 2);
- $domain = is_php('5.4')
+ $domain = defined('INTL_IDNA_VARIANT_UTS46')
? idn_to_ascii($domain, 0, INTL_IDNA_VARIANT_UTS46)
: idn_to_ascii($domain);
$email = $account.'@'.$domain;
@@ -2074,7 +2074,19 @@ class CI_Email {
$this->_send_command('hello');
$this->_send_command('starttls');
- $crypto = stream_socket_enable_crypto($this->_smtp_connect, TRUE, STREAM_CRYPTO_METHOD_TLS_CLIENT);
+ /**
+ * STREAM_CRYPTO_METHOD_TLS_CLIENT is quite the mess ...
+ *
+ * - On PHP <5.6 it doesn't even mean TLS, but SSL 2.0, and there's no option to use actual TLS
+ * - On PHP 5.6.0-5.6.6, >=7.2 it means negotiation with any of TLS 1.0, 1.1, 1.2
+ * - On PHP 5.6.7-7.1.* it means only TLS 1.0
+ *
+ * We want the negotiation, so we'll force it below ...
+ */
+ $method = is_php('5.6')
+ ? STREAM_CRYPTO_METHOD_TLSv1_0_CLIENT | STREAM_CRYPTO_METHOD_TLSv1_1_CLIENT | STREAM_CRYPTO_METHOD_TLSv1_2_CLIENT
+ : STREAM_CRYPTO_METHOD_TLS_CLIENT;
+ $crypto = stream_socket_enable_crypto($this->_smtp_connect, TRUE, $method);
if ($crypto !== TRUE)
{
diff --git a/system/libraries/Form_validation.php b/system/libraries/Form_validation.php
index 3444c65a0..6a97ee599 100644
--- a/system/libraries/Form_validation.php
+++ b/system/libraries/Form_validation.php
@@ -1231,7 +1231,7 @@ class CI_Form_validation {
{
if (function_exists('idn_to_ascii') && preg_match('#\A([^@]+)@(.+)\z#', $str, $matches))
{
- $domain = is_php('5.4')
+ $domain = defined('INTL_IDNA_VARIANT_UTS46')
? idn_to_ascii($matches[2], 0, INTL_IDNA_VARIANT_UTS46)
: idn_to_ascii($matches[2]);
$str = $matches[1].'@'.$domain;
diff --git a/system/libraries/Image_lib.php b/system/libraries/Image_lib.php
index b9adcd6e5..a5cb6fb47 100644
--- a/system/libraries/Image_lib.php
+++ b/system/libraries/Image_lib.php
@@ -835,7 +835,10 @@ class CI_Image_lib {
imagedestroy($dst_img);
imagedestroy($src_img);
- chmod($this->full_dst_path, $this->file_permissions);
+ if ($this->dynamic_output !== TRUE)
+ {
+ chmod($this->full_dst_path, $this->file_permissions);
+ }
return TRUE;
}
diff --git a/system/libraries/Xmlrpc.php b/system/libraries/Xmlrpc.php
index 39e4dd37e..c23504de8 100644
--- a/system/libraries/Xmlrpc.php
+++ b/system/libraries/Xmlrpc.php
@@ -1181,7 +1181,7 @@ class XML_RPC_Message extends CI_Xmlrpc
$data = implode("\r\n", $lines);
// Parse XML data
- if ( ! xml_parse($parser, $data, count($data)))
+ if ( ! xml_parse($parser, $data, TRUE))
{
$errstr = sprintf('XML error: %s at line %d',
xml_error_string(xml_get_error_code($parser)),