diff options
-rw-r--r-- | composer.json | 2 | ||||
-rw-r--r-- | system/core/CodeIgniter.php | 2 | ||||
-rw-r--r-- | system/core/Output.php | 95 | ||||
-rw-r--r-- | system/database/drivers/pdo/subdrivers/pdo_oci_forge.php | 2 | ||||
-rw-r--r-- | system/helpers/form_helper.php | 2 | ||||
-rw-r--r-- | system/libraries/Email.php | 26 | ||||
-rw-r--r-- | system/libraries/Form_validation.php | 4 | ||||
-rw-r--r-- | tests/codeigniter/libraries/Form_validation_test.php | 1 | ||||
-rw-r--r-- | user_guide_src/source/changelog.rst | 27 | ||||
-rw-r--r-- | user_guide_src/source/helpers/form_helper.rst | 2 | ||||
-rw-r--r-- | user_guide_src/source/installation/downloads.rst | 3 | ||||
-rw-r--r-- | user_guide_src/source/installation/upgrade_316.rst | 14 | ||||
-rw-r--r-- | user_guide_src/source/installation/upgrading.rst | 1 |
13 files changed, 103 insertions, 78 deletions
diff --git a/composer.json b/composer.json index 0a898d2c1..fea8f1f85 100644 --- a/composer.json +++ b/composer.json @@ -11,7 +11,7 @@ "source": "https://github.com/bcit-ci/CodeIgniter" }, "require": { - "php": ">=5.2.4" + "php": ">=5.4.8" }, "suggest": { "paragonie/random_compat": "Provides better randomness in PHP 5.x" diff --git a/system/core/CodeIgniter.php b/system/core/CodeIgniter.php index 8eed52eb7..c97ff2bbb 100644 --- a/system/core/CodeIgniter.php +++ b/system/core/CodeIgniter.php @@ -383,7 +383,7 @@ defined('BASEPATH') OR exit('No direct script access allowed'); * ReflectionMethod::isConstructor() is the ONLY reliable check, * knowing which method will be executed as a constructor. */ - elseif ( ! is_callable(array($class, $method)) && strcasecmp($class, $method) === 0) + elseif ( ! is_callable(array($class, $method))) { $reflection = new ReflectionMethod($class, $method); if ( ! $reflection->isPublic() OR $reflection->isConstructor()) diff --git a/system/core/Output.php b/system/core/Output.php index c684c94c9..2dabb2445 100644 --- a/system/core/Output.php +++ b/system/core/Output.php @@ -586,62 +586,59 @@ class CI_Output { return; } - if (flock($fp, LOCK_EX)) + if ( ! flock($fp, LOCK_EX)) { - // If output compression is enabled, compress the cache - // itself, so that we don't have to do that each time - // we're serving it - if ($this->_compress_output === TRUE) - { - $output = gzencode($output); + log_message('error', 'Unable to secure a file lock for file at: '.$cache_path); + fclose($fp); + return; + } - if ($this->get_header('content-type') === NULL) - { - $this->set_content_type($this->mime_type); - } + // If output compression is enabled, compress the cache + // itself, so that we don't have to do that each time + // we're serving it + if ($this->_compress_output === TRUE) + { + $output = gzencode($output); + + if ($this->get_header('content-type') === NULL) + { + $this->set_content_type($this->mime_type); } + } - $expire = time() + ($this->cache_expiration * 60); + $expire = time() + ($this->cache_expiration * 60); - // Put together our serialized info. - $cache_info = serialize(array( - 'expire' => $expire, - 'headers' => $this->headers - )); + // Put together our serialized info. + $cache_info = serialize(array( + 'expire' => $expire, + 'headers' => $this->headers + )); - $output = $cache_info.'ENDCI--->'.$output; + $output = $cache_info.'ENDCI--->'.$output; - for ($written = 0, $length = self::strlen($output); $written < $length; $written += $result) + for ($written = 0, $length = self::strlen($output); $written < $length; $written += $result) + { + if (($result = fwrite($fp, self::substr($output, $written))) === FALSE) { - if (($result = fwrite($fp, self::substr($output, $written))) === FALSE) - { - break; - } + break; } - - flock($fp, LOCK_UN); - } - else - { - log_message('error', 'Unable to secure a file lock for file at: '.$cache_path); - return; } + flock($fp, LOCK_UN); fclose($fp); - if (is_int($result)) - { - chmod($cache_path, 0640); - log_message('debug', 'Cache file written: '.$cache_path); - - // Send HTTP cache-control headers to browser to match file cache settings. - $this->set_cache_header($_SERVER['REQUEST_TIME'], $expire); - } - else + if ( ! is_int($result)) { @unlink($cache_path); log_message('error', 'Unable to write the complete cache content at: '.$cache_path); + return; } + + chmod($cache_path, 0640); + log_message('debug', 'Cache file written: '.$cache_path); + + // Send HTTP cache-control headers to browser to match file cache settings. + $this->set_cache_header($_SERVER['REQUEST_TIME'], $expire); } // -------------------------------------------------------------------- @@ -708,11 +705,9 @@ class CI_Output { log_message('debug', 'Cache file has expired. File deleted.'); return FALSE; } - else - { - // Or else send the HTTP cache control headers. - $this->set_cache_header($last_modified, $expire); - } + + // Send the HTTP cache control headers + $this->set_cache_header($last_modified, $expire); // Add headers from cache file. foreach ($cache_info['headers'] as $header) @@ -798,13 +793,11 @@ class CI_Output { $this->set_status_header(304); exit; } - else - { - header('Pragma: public'); - header('Cache-Control: max-age='.$max_age.', public'); - header('Expires: '.gmdate('D, d M Y H:i:s', $expiration).' GMT'); - header('Last-modified: '.gmdate('D, d M Y H:i:s', $last_modified).' GMT'); - } + + header('Pragma: public'); + header('Cache-Control: max-age='.$max_age.', public'); + header('Expires: '.gmdate('D, d M Y H:i:s', $expiration).' GMT'); + header('Last-modified: '.gmdate('D, d M Y H:i:s', $last_modified).' GMT'); } // -------------------------------------------------------------------- diff --git a/system/database/drivers/pdo/subdrivers/pdo_oci_forge.php b/system/database/drivers/pdo/subdrivers/pdo_oci_forge.php index c8983ee56..813207b8e 100644 --- a/system/database/drivers/pdo/subdrivers/pdo_oci_forge.php +++ b/system/database/drivers/pdo/subdrivers/pdo_oci_forge.php @@ -117,7 +117,7 @@ class CI_DB_pdo_oci_forge extends CI_DB_pdo_forge { if ($alter_type === 'MODIFY' && ! empty($field[$i]['new_name'])) { $sqls[] = $sql.' RENAME COLUMN '.$this->db->escape_identifiers($field[$i]['name']) - .' '.$this->db->escape_identifiers($field[$i]['new_name']); + .' TO '.$this->db->escape_identifiers($field[$i]['new_name']); } } } diff --git a/system/helpers/form_helper.php b/system/helpers/form_helper.php index 6f7e63b32..0c7ee4a40 100644 --- a/system/helpers/form_helper.php +++ b/system/helpers/form_helper.php @@ -596,7 +596,7 @@ if ( ! function_exists('form_label')) * * @param string The text to appear onscreen * @param string The id the label applies to - * @param array Additional attributes + * @param mixed Additional attributes * @return string */ function form_label($label_text = '', $id = '', $attributes = array()) diff --git a/system/libraries/Email.php b/system/libraries/Email.php index d7178f321..fa5820dcd 100644 --- a/system/libraries/Email.php +++ b/system/libraries/Email.php @@ -893,18 +893,13 @@ class CI_Email { /** * Get Mail Protocol * - * @param bool * @return mixed */ - protected function _get_protocol($return = TRUE) + protected function _get_protocol() { $this->protocol = strtolower($this->protocol); in_array($this->protocol, $this->_protocols, TRUE) OR $this->protocol = 'mail'; - - if ($return === TRUE) - { - return $this->protocol; - } + return $this->protocol; } // -------------------------------------------------------------------- @@ -912,25 +907,21 @@ class CI_Email { /** * Get Mail Encoding * - * @param bool * @return string */ - protected function _get_encoding($return = TRUE) + protected function _get_encoding() { in_array($this->_encoding, $this->_bit_depths) OR $this->_encoding = '8bit'; foreach ($this->_base_charsets as $charset) { - if (strpos($charset, $this->charset) === 0) + if (strpos($this->charset, $charset) === 0) { $this->_encoding = '7bit'; } } - if ($return === TRUE) - { - return $this->_encoding; - } + return $this->_encoding; } // -------------------------------------------------------------------- @@ -1809,14 +1800,15 @@ class CI_Email { { $this->_unwrap_specials(); - $method = '_send_with_'.$this->_get_protocol(); + $protocol = $this->_get_protocol(); + $method = '_send_with_'.$protocol; if ( ! $this->$method()) { - $this->_set_error_message('lang:email_send_failure_'.($this->_get_protocol() === 'mail' ? 'phpmail' : $this->_get_protocol())); + $this->_set_error_message('lang:email_send_failure_'.($protocol === 'mail' ? 'phpmail' : $protocol)); return FALSE; } - $this->_set_error_message('lang:email_sent', $this->_get_protocol()); + $this->_set_error_message('lang:email_sent', $protocol); return TRUE; } diff --git a/system/libraries/Form_validation.php b/system/libraries/Form_validation.php index 7be0b949d..6eaf67710 100644 --- a/system/libraries/Form_validation.php +++ b/system/libraries/Form_validation.php @@ -1233,9 +1233,9 @@ class CI_Form_validation { */ public function valid_email($str) { - if (function_exists('idn_to_ascii') && sscanf($str, '%[^@]@%s', $name, $domain) === 2) + if (function_exists('idn_to_ascii') && preg_match('#\A([^@]+)@(.+)\z#', $str, $matches)) { - $str = $name.'@'.idn_to_ascii($domain); + $str = $matches[1].'@'.idn_to_ascii($matches[2]); } return (bool) filter_var($str, FILTER_VALIDATE_EMAIL); diff --git a/tests/codeigniter/libraries/Form_validation_test.php b/tests/codeigniter/libraries/Form_validation_test.php index 035410724..ab0e1fc0a 100644 --- a/tests/codeigniter/libraries/Form_validation_test.php +++ b/tests/codeigniter/libraries/Form_validation_test.php @@ -268,6 +268,7 @@ class Form_validation_test extends CI_TestCase { public function test_rule_valid_email() { $this->assertTrue($this->form_validation->valid_email('email@sample.com')); + $this->assertFalse($this->form_validation->valid_email('email@sample.com foo bar')); $this->assertFalse($this->form_validation->valid_email('valid_email', '@sample.com')); } diff --git a/user_guide_src/source/changelog.rst b/user_guide_src/source/changelog.rst index 767b2486d..59b4e0fd9 100644 --- a/user_guide_src/source/changelog.rst +++ b/user_guide_src/source/changelog.rst @@ -107,16 +107,39 @@ Release Date: Not Released - Removed the second (out of three) parameter from the :php:func:`form_upload()` function (it was never used). -Version 3.1.5 +Version 3.1.6 ============= Release Date: Not Released +Version 3.1.5 +============= + +Release Date: Jun 19, 2017 + +- **Security** + + - :doc:`Form Validation Library <libraries/form_validation>` rule ``valid_email`` could be bypassed if ``idn_to_ascii()`` is available. + +- General Changes + + - Updated :doc:`Form Helper <helpers/form_helper>` function :php:func:`form_label()` to accept HTML attributes as a string. + +Bug fixes for 3.1.5 +------------------- + +- Fixed a bug (#5070) - :doc:`Email Library <libraries/email>` didn't properly detect 7-bit encoding. +- Fixed a bug (#5084) - :doc:`XML-RPC Library <libraries/xmlrpc>` errored because of a variable name typo. +- Fixed a bug (#5108) - :doc:`Inflector Helper <helpers/inflector_helper>` function :php:func:`singular()` didn't properly handle 'quizzes'. +- Fixed a regression (#5131) - private controller methods triggered PHP errors instead of a 404 response. +- Fixed a bug (#5150) - :doc:`Database Forge <database/forge>` method ``modify_column()`` triggered an error while renaming columns with the 'oci8', 'pdo/oci' drivers. +- Fixed a bug (#5155) - :doc:`Query Builder <database/query_builder>` method ``count_all_results()`` returned incorrect result for queries using ``LIMIT``, ``OFFSET``. + Version 3.1.4 ============= -Release Date: March 20, 2017 +Release Date: Mar 20, 2017 - **Security** diff --git a/user_guide_src/source/helpers/form_helper.rst b/user_guide_src/source/helpers/form_helper.rst index 97595c90b..43a20e18c 100644 --- a/user_guide_src/source/helpers/form_helper.rst +++ b/user_guide_src/source/helpers/form_helper.rst @@ -485,7 +485,7 @@ The following functions are available: :param string $label_text: Text to put in the <label> tag :param string $id: ID of the form element that we're making a label for - :param string $attributes: HTML attributes + :param mixed $attributes: HTML attributes :returns: An HTML field label tag :rtype: string diff --git a/user_guide_src/source/installation/downloads.rst b/user_guide_src/source/installation/downloads.rst index f36857e57..fb9222df9 100644 --- a/user_guide_src/source/installation/downloads.rst +++ b/user_guide_src/source/installation/downloads.rst @@ -3,7 +3,8 @@ Downloading CodeIgniter ####################### - `CodeIgniter v3.2.0-dev (Current version) <https://codeload.github.com/bcit-ci/CodeIgniter/zip/develop>`_ -- `CodeIgniter v3.1.5-dev <https://codeload.github.com/bcit-ci/CodeIgniter/zip/3.1-stable>`_ +- `CodeIgniter v3.1.6-dev <https://codeload.github.com/bcit-ci/CodeIgniter/zip/3.1-stable>`_ +- `CodeIgniter v3.1.5 <https://codeload.github.com/bcit-ci/CodeIgniter/zip/3.1.5>`_ - `CodeIgniter v3.1.4 <https://codeload.github.com/bcit-ci/CodeIgniter/zip/3.1.4>`_ - `CodeIgniter v3.1.3 <https://codeload.github.com/bcit-ci/CodeIgniter/zip/3.1.3>`_ - `CodeIgniter v3.1.2 <https://codeload.github.com/bcit-ci/CodeIgniter/zip/3.1.2>`_ diff --git a/user_guide_src/source/installation/upgrade_316.rst b/user_guide_src/source/installation/upgrade_316.rst new file mode 100644 index 000000000..e382c20ab --- /dev/null +++ b/user_guide_src/source/installation/upgrade_316.rst @@ -0,0 +1,14 @@ +############################# +Upgrading from 3.1.5 to 3.1.6 +############################# + +Before performing an update you should take your site offline by +replacing the index.php file with a static one. + +Step 1: Update your CodeIgniter files +===================================== + +Replace all files and directories in your *system/* directory. + +.. note:: If you have any custom developed files in these directories, + please make copies of them first. diff --git a/user_guide_src/source/installation/upgrading.rst b/user_guide_src/source/installation/upgrading.rst index b76392d05..3383796d0 100644 --- a/user_guide_src/source/installation/upgrading.rst +++ b/user_guide_src/source/installation/upgrading.rst @@ -9,6 +9,7 @@ upgrading from. :titlesonly: Upgrading from 3.1.3+ to 3.2.x <upgrade_320> + Upgrading from 3.1.5 to 3.1.6 <upgrade_316> Upgrading from 3.1.4 to 3.1.5 <upgrade_315> Upgrading from 3.1.3 to 3.1.4 <upgrade_314> Upgrading from 3.1.2 to 3.1.3 <upgrade_313> |