diff options
-rw-r--r-- | application/config/config.php | 14 | ||||
-rw-r--r-- | system/core/URI.php | 28 | ||||
-rw-r--r-- | system/database/DB_driver.php | 32 | ||||
-rw-r--r-- | system/helpers/date_helper.php | 47 | ||||
-rw-r--r-- | system/libraries/Form_validation.php | 6 | ||||
-rw-r--r-- | system/libraries/Session.php | 18 | ||||
-rw-r--r-- | tests/codeigniter/core/URI_test.php | 5 | ||||
-rw-r--r-- | tests/codeigniter/helpers/date_helper_test.php | 25 | ||||
-rw-r--r-- | user_guide_src/source/changelog.rst | 9 | ||||
-rw-r--r-- | user_guide_src/source/helpers/date_helper.rst | 18 | ||||
-rw-r--r-- | user_guide_src/source/installation/upgrade_300.rst | 4 | ||||
-rw-r--r-- | user_guide_src/source/libraries/form_validation.rst | 6 | ||||
-rw-r--r-- | user_guide_src/source/libraries/input.rst | 40 |
13 files changed, 154 insertions, 98 deletions
diff --git a/application/config/config.php b/application/config/config.php index 2628885f0..7da889f81 100644 --- a/application/config/config.php +++ b/application/config/config.php @@ -204,7 +204,7 @@ $config['directory_trigger'] = 'd'; // experimental not currently in use | 4 = All Messages | | You can also pass in a array with threshold levels to show individual error types -| +| | array(2) = Debug Messages, without Error Messages | | For a live site you'll usually only enable Errors (1) to be logged otherwise @@ -253,7 +253,7 @@ $config['cache_path'] = ''; | | If you use the Encryption class or the Session class you | MUST set an encryption key. See the user guide for info. -| +| | http://codeigniter.com/user_guide/libraries/encryption.html | http://codeigniter.com/user_guide/libraries/sessions.html | @@ -297,7 +297,7 @@ $config['sess_time_to_update'] = 300; | 'cookie_domain' = Set to .your-domain.com for site-wide cookies | 'cookie_path' = Typically will be a forward slash | 'cookie_secure' = Cookies will only be set if a secure HTTPS connection exists. -| 'cookie_httponly' = Cookie will only be accessible via HTTP(S) (no javascript) +| 'cookie_httponly' = Cookie will only be accessible via HTTP(S) (no javascript) | */ $config['cookie_prefix'] = ""; @@ -362,10 +362,10 @@ $config['compress_output'] = FALSE; | Master Time Reference |-------------------------------------------------------------------------- | -| Options are 'local' or 'gmt'. This pref tells the system whether to use -| your server's local time as the master 'now' reference, or convert it to -| GMT. See the 'date helper' page of the user guide for information -| regarding date handling. +| Options are 'local' or any PHP supported timezone. This preference tells +| the system whether to use your server's local time as the master 'now' +| reference, or convert it to the configured one timezone. See the 'date +| helper' page of the user guide for information regarding date handling. | */ $config['time_reference'] = 'local'; diff --git a/system/core/URI.php b/system/core/URI.php index a575bc36e..a997525ee 100644 --- a/system/core/URI.php +++ b/system/core/URI.php @@ -119,7 +119,7 @@ class CI_URI { } // No PATH_INFO?... What about QUERY_STRING? - $path = (isset($_SERVER['QUERY_STRING'])) ? $_SERVER['QUERY_STRING'] : @getenv('QUERY_STRING'); + $path = isset($_SERVER['QUERY_STRING']) ? $_SERVER['QUERY_STRING'] : @getenv('QUERY_STRING'); if (trim($path, '/') !== '') { $this->_set_uri_string($path); @@ -163,7 +163,7 @@ class CI_URI { * @param string * @return void */ - public function _set_uri_string($str) + protected function _set_uri_string($str) { // Filter out control characters $str = remove_invisible_characters($str, FALSE); @@ -177,8 +177,8 @@ class CI_URI { /** * Detects the URI * - * This function will detect the URI automatically and fix the query string - * if necessary. + * This function will detect the URI automatically + * and fix the query string if necessary. * * @return string */ @@ -189,23 +189,27 @@ class CI_URI { return ''; } - $uri = $_SERVER['REQUEST_URI']; - if (strpos($uri, $_SERVER['SCRIPT_NAME']) === 0) + if (strpos($_SERVER['REQUEST_URI'], $_SERVER['SCRIPT_NAME']) === 0) { - $uri = substr($uri, strlen($_SERVER['SCRIPT_NAME'])); + $uri = substr($_SERVER['REQUEST_URI'], strlen($_SERVER['SCRIPT_NAME'])); } - elseif (strpos($uri, dirname($_SERVER['SCRIPT_NAME'])) === 0) + elseif (strpos($_SERVER['REQUEST_URI'], dirname($_SERVER['SCRIPT_NAME'])) === 0) { - $uri = substr($uri, strlen(dirname($_SERVER['SCRIPT_NAME']))); + $uri = substr($_SERVER['REQUEST_URI'], strlen(dirname($_SERVER['SCRIPT_NAME']))); + } + else + { + $uri = $_SERVER['REQUEST_URI']; } // This section ensures that even on servers that require the URI to be in the query string (Nginx) a correct // URI is found, and also fixes the QUERY_STRING server var and $_GET array. - if (strncmp($uri, '?/', 2) === 0) + if (strpos($uri, '?/') === 0) { $uri = substr($uri, 2); } - $parts = preg_split('#\?#i', $uri, 2); + + $parts = explode('?', $uri, 2); $uri = $parts[0]; if (isset($parts[1])) { @@ -223,7 +227,7 @@ class CI_URI { return '/'; } - $uri = parse_url($uri, PHP_URL_PATH); + $uri = parse_url('pseudo://hostname/'.$uri, PHP_URL_PATH); // Do some final cleaning of the URI and return it return str_replace(array('//', '../'), '/', trim($uri, '/')); diff --git a/system/database/DB_driver.php b/system/database/DB_driver.php index 88a3b388f..d056bdb90 100644 --- a/system/database/DB_driver.php +++ b/system/database/DB_driver.php @@ -596,25 +596,51 @@ abstract class CI_DB_driver { */ public function compile_binds($sql, $binds) { - if (preg_match_all('/(>|<|=|!)\s*('.preg_quote($this->bind_marker).')/i', $sql, $matches, PREG_SET_ORDER | PREG_OFFSET_CAPTURE) !== count($binds)) + if (empty($binds) OR empty($this->bind_marker) OR strpos($sql, $this->bind_marker) === FALSE) { return $sql; } elseif ( ! is_array($binds)) { $binds = array($binds); + $bind_count = 1; } else { // Make sure we're using numeric keys $binds = array_values($binds); + $bind_count = count($binds); } + // We'll need the marker length later + $ml = strlen($this->bind_marker); - for ($i = count($matches) - 1; $i >= 0; $i--) + // Make sure not to replace a chunk inside a string that happens to match the bind marker + if ($c = preg_match_all("/'[^']*'/i", $sql, $matches)) { - $sql = substr_replace($sql, $this->escape($binds[$i]), $matches[$i][2][1], 1); + $c = preg_match_all('/'.preg_quote($this->bind_marker).'/i', + str_replace($matches[0], + str_replace($this->bind_marker, str_repeat(' ', $ml), $matches[0]), + $sql, $c), + $matches, PREG_OFFSET_CAPTURE); + + // Bind values' count must match the count of markers in the query + if ($bind_count !== $c) + { + return $sql; + } + } + elseif (($c = preg_match_all('/'.preg_quote($this->bind_marker).'/i', $sql, $matches, PREG_OFFSET_CAPTURE)) !== $bind_count) + { + return $sql; + } + + do + { + $c--; + $sql = substr_replace($sql, $this->escape($binds[$c]), $matches[0][$c][1], $ml); } + while ($c !== 0); return $sql; } diff --git a/system/helpers/date_helper.php b/system/helpers/date_helper.php index c601dc9e5..d5036f645 100644 --- a/system/helpers/date_helper.php +++ b/system/helpers/date_helper.php @@ -42,29 +42,28 @@ if ( ! function_exists('now')) /** * Get "now" time * - * Returns time() or its GMT equivalent based on the config file preference + * Returns time() based on the timezone parameter or on the + * "time_reference" setting * + * @param string * @return int */ - function now() + function now($timezone = NULL) { - $CI =& get_instance(); - - if (strtolower($CI->config->item('time_reference')) === 'gmt') + if (empty($timezone)) { - $now = time(); - $system_time = mktime(gmdate("H", $now), gmdate("i", $now), gmdate("s", $now), gmdate("m", $now), gmdate("d", $now), gmdate("Y", $now)); - - if (strlen($system_time) < 10) - { - $system_time = time(); - log_message('error', 'The Date class could not set a proper GMT timestamp so the local time() value was used.'); - } + $timezone = config_item('time_reference'); + } - return $system_time; + if ($timezone === 'local' OR $timezone === date_default_timezone_get()) + { + return time(); } - return time(); + $datetime = new DateTime('now', new DateTimeZone($timezone)); + sscanf($datetime->format('j-n-Y G:i:s'), '%d-%d-%d %d:%d:%d', $day, $month, $year, $hour, $minute, $second); + + return mktime($hour, $minute, $second, $month, $day, $year); } } @@ -315,13 +314,13 @@ if ( ! function_exists('local_to_gmt')) $time = time(); } - return mktime( - gmdate('H', $time), - gmdate('i', $time), - gmdate('s', $time), - gmdate('m', $time), - gmdate('d', $time), - gmdate('Y', $time) + return gmmktime( + date('H', $time), + date('i', $time), + date('s', $time), + date('m', $time), + date('d', $time), + date('Y', $time) ); } } @@ -376,9 +375,7 @@ if ( ! function_exists('mysql_to_unix')) // since the formatting changed with MySQL 4.1 // YYYY-MM-DD HH:MM:SS - $time = str_replace('-', '', $time); - $time = str_replace(':', '', $time); - $time = str_replace(' ', '', $time); + $time = str_replace(array('-', ':', ' '), '', $time); // YYYYMMDDHHMMSS return mktime( diff --git a/system/libraries/Form_validation.php b/system/libraries/Form_validation.php index 77c968e7c..6cbe032c7 100644 --- a/system/libraries/Form_validation.php +++ b/system/libraries/Form_validation.php @@ -187,6 +187,12 @@ class CI_Form_validation { return $this; } + // Convert an array of rules to a string + if (is_array($rules)) + { + $rules = implode('|', $rules); + } + // No fields? Nothing to do... if ( ! is_string($field) OR ! is_string($rules) OR $field === '') { diff --git a/system/libraries/Session.php b/system/libraries/Session.php index 7beedd96b..72a942b8a 100644 --- a/system/libraries/Session.php +++ b/system/libraries/Session.php @@ -149,11 +149,11 @@ class CI_Session { public $flashdata_key = 'flash'; /** - * Function to use to get the current time + * Timezone to use for the current time * * @var string */ - public $time_reference = 'time'; + public $time_reference = 'local'; /** * Probablity level of garbage collection of old sessions @@ -203,7 +203,7 @@ class CI_Session { // manually via the $params array above or via the config file foreach (array('sess_encrypt_cookie', 'sess_use_database', 'sess_table_name', 'sess_expiration', 'sess_expire_on_close', 'sess_match_ip', 'sess_match_useragent', 'sess_cookie_name', 'cookie_path', 'cookie_domain', 'cookie_secure', 'cookie_httponly', 'sess_time_to_update', 'time_reference', 'cookie_prefix', 'encryption_key') as $key) { - $this->$key = (isset($params[$key])) ? $params[$key] : $this->CI->config->item($key); + $this->$key = isset($params[$key]) ? $params[$key] : $this->CI->config->item($key); } if ($this->encryption_key === '') @@ -786,9 +786,15 @@ class CI_Session { */ protected function _get_time() { - return (strtolower($this->time_reference) === 'gmt') - ? mktime(gmdate('H'), gmdate('i'), gmdate('s'), gmdate('m'), gmdate('d'), gmdate('Y')) - : time(); + if ($this->time_reference === 'local' OR $this->time_reference === date_default_timezone_get()) + { + return time(); + } + + $datetime = new DateTime('now', new DateTimeZone($this->time_reference)); + sscanf($datetime->format('j-n-Y G:i:s'), '%d-%d-%d %d:%d:%d', $day, $month, $year, $hour, $minute, $second); + + return mktime($hour, $minute, $second, $month, $day, $year); } // -------------------------------------------------------------------- diff --git a/tests/codeigniter/core/URI_test.php b/tests/codeigniter/core/URI_test.php index 0ba694b46..60ed1a4e9 100644 --- a/tests/codeigniter/core/URI_test.php +++ b/tests/codeigniter/core/URI_test.php @@ -9,6 +9,10 @@ class URI_test extends CI_TestCase { // -------------------------------------------------------------------- + /* As of the following commit, _set_uri_string() is a protected method: + + https://github.com/EllisLab/CodeIgniter/commit/d461934184d95b0cfb2feec93f27b621ef72a5c2 + public function test_set_uri_string() { // Slashes get killed @@ -18,6 +22,7 @@ class URI_test extends CI_TestCase { $this->uri->_set_uri_string('nice/uri'); $this->assertEquals('nice/uri', $this->uri->uri_string); } + */ // -------------------------------------------------------------------- diff --git a/tests/codeigniter/helpers/date_helper_test.php b/tests/codeigniter/helpers/date_helper_test.php index 4b747b864..1d397ac81 100644 --- a/tests/codeigniter/helpers/date_helper_test.php +++ b/tests/codeigniter/helpers/date_helper_test.php @@ -13,6 +13,8 @@ class Date_helper_test extends CI_TestCase { public function test_now_local() { + /* + // This stub job, is simply to cater $config['time_reference'] $config = $this->getMock('CI_Config'); $config->expects($this->any()) @@ -22,25 +24,34 @@ class Date_helper_test extends CI_TestCase { // Add the stub to our test instance $this->ci_instance_var('config', $config); + */ + + $this->ci_set_config('time_reference', 'local'); + $this->assertEquals(time(), now()); } // ------------------------------------------------------------------------ - public function test_now_gmt() + public function test_now_utc() { + /* + // This stub job, is simply to cater $config['time_reference'] $config = $this->getMock('CI_Config'); $config->expects($this->any()) ->method('item') - ->will($this->returnValue('gmt')); + ->will($this->returnValue('UTC')); // Add the stub to our stdClass $this->ci_instance_var('config', $config); - $t = time(); + */ + + $this->ci_set_config('time_reference', 'UTC'); + $this->assertEquals( - mktime(gmdate('H', $t), gmdate('i', $t), gmdate('s', $t), gmdate('m', $t), gmdate('d', $t), gmdate('Y', $t)), + gmmktime(date('G'), date('i'), date('s'), date('n'), date('j'), date('Y')), now() ); } @@ -185,9 +196,9 @@ class Date_helper_test extends CI_TestCase { public function test_local_to_gmt() { $this->assertEquals( - mktime( - gmdate('H', $this->time), gmdate('i', $this->time), gmdate('s', $this->time), - gmdate('m', $this->time), gmdate('d', $this->time), gmdate('Y', $this->time) + gmmktime( + date('G', $this->time), date('i', $this->time), date('s', $this->time), + date('n', $this->time), date('j', $this->time), date('Y', $this->time) ), local_to_gmt($this->time) ); diff --git a/user_guide_src/source/changelog.rst b/user_guide_src/source/changelog.rst index ab3e01394..7748f9b37 100644 --- a/user_guide_src/source/changelog.rst +++ b/user_guide_src/source/changelog.rst @@ -48,6 +48,7 @@ Release Date: Not Released - Helpers + - :doc:`Date Helper <helpers/date_helper>` function now() now works with all timezone strings supported by PHP. - ``create_captcha()`` accepts additional colors parameter, allowing for color customization. - ``url_title()`` will now trim extra dashes from beginning and end. - Added XHTML Basic 1.1 doctype to :doc:`HTML Helper <helpers/html_helper>`. @@ -147,6 +148,7 @@ Release Date: Not Released - _execute() now considers input data to be invalid if a specified rule is not found. - 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. - 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. @@ -171,6 +173,7 @@ Release Date: Not Released - Added get_content_type() method to the :doc:`Output Library <libraries/output>`. - Added get_mimes() function to system/core/Commons.php to return the config/mimes.php array. - Added a second argument to set_content_type() in the :doc:`Output Library <libraries/output>` that allows setting the document charset as well. + - $config['time_reference'] now supports all timezone strings supported by PHP. Bug fixes for 3.0 ------------------ @@ -264,11 +267,14 @@ Bug fixes for 3.0 - Fixed a bug in the File-based :doc:`Cache Library <libraries/caching>` driver's get_metadata() method where a non-existent array key was accessed for the TTL value. - Fixed a bug (#1202) - :doc:`Encryption Library <libraries/encryption>` encode_from_legacy() didn't set back the encrypt mode on failure. - Fixed a bug (#145) - compile_binds() failed when the bind marker was present in a literal string within the query. +- Fixed a bug in protect_identifiers() where if passed along with the field names, operators got escaped as well. +- Fixed a bug (#10) - :doc:`URI Library <libraries/uri>` internal method _detect_uri() failed with paths containing a colon. +- Fixed a bug (#1387) - :doc:`Query Builder <database/query_builder>`'s from() method didn't escape table aliases. Version 2.1.1 ============= -Release Date: Not Released +Release Date: June 13, 2012 - General Changes - Fixed support for docx, xlsx files in mimes.php. @@ -293,7 +299,6 @@ Bug fixes for 2.1.1 - Fixed a bug (#726) - PDO put a 'dbname' argument in it's connection string regardless of the database platform in use, which made it impossible to use SQLite. - Fixed a bug - CI_DB_pdo_driver::num_rows() was not returning properly value with SELECT queries, cause it was relying on PDOStatement::rowCount(). - Fixed a bug (#1059) - CI_Image_lib::clear() was not correctly clearing all necessary object properties, namely width and height. -- Fixed a bud (#1387) - Active Record's ``from()`` method didn't escape table aliases. Version 2.1.0 ============= diff --git a/user_guide_src/source/helpers/date_helper.rst b/user_guide_src/source/helpers/date_helper.rst index 18216c5a2..1b7177fc2 100644 --- a/user_guide_src/source/helpers/date_helper.rst +++ b/user_guide_src/source/helpers/date_helper.rst @@ -21,13 +21,21 @@ now() ===== Returns the current time as a Unix timestamp, referenced either to your -server's local time or GMT, based on the "time reference" setting in -your config file. If you do not intend to set your master time reference -to GMT (which you'll typically do if you run a site that lets each user -set their own timezone settings) there is no benefit to using this +server's local time or any PHP suported timezone, based on the "time reference" +setting in your config file. If you do not intend to set your master time reference +to any other PHP suported timezone (which you'll typically do if you run a site that +lets each user set their own timezone settings) there is no benefit to using this function over PHP's time() function. -.. php:method:: now() +.. php:method:: now($timezone = NULL) + + :param string $timezone: The timezone you want to be returned + :returns: integer + +:: + echo now("Australia/Victoria"); + +If a timezone is not provided, it will return time() based on "time_reference" setting. mdate() ======= diff --git a/user_guide_src/source/installation/upgrade_300.rst b/user_guide_src/source/installation/upgrade_300.rst index 63c4227dc..c70737cff 100644 --- a/user_guide_src/source/installation/upgrade_300.rst +++ b/user_guide_src/source/installation/upgrade_300.rst @@ -41,8 +41,8 @@ need to rename the `$active_record` variable to `$query_builder`. $active_group = 'default'; // $active_record = TRUE; $query_builder = TRUE; - + Step 5: Move your errors folder =============================== -In version 3.0.0, the errors folder has been moved from "application/errors" to "application/views/errors".
\ No newline at end of file +In version 3.0.0, the errors folder has been moved from _application/errors_ to _application/views/errors_.
\ No newline at end of file diff --git a/user_guide_src/source/libraries/form_validation.rst b/user_guide_src/source/libraries/form_validation.rst index 3c0e6eda4..3bcad7ba6 100644 --- a/user_guide_src/source/libraries/form_validation.rst +++ b/user_guide_src/source/libraries/form_validation.rst @@ -304,6 +304,10 @@ Give it a try! Submit your form without the proper data and you'll see new error messages that correspond to your new rules. There are numerous rules available which you can read about in the validation reference. +.. note:: You can also pass an array of rules to set_rules(), instead of a string. Example:: + + $this->form_validation->set_rules('username', 'Username', array('required', 'min_length[5]')); + Prepping Data ============= @@ -935,7 +939,7 @@ $this->form_validation->set_rules(); :param string $field: The field name :param string $label: The field label - :param string $rules: The rules, seperated by a pipe "|" + :param mixed $rules: The rules, as a string with rules separated by a pipe "|", or an array or rules. :rtype: Object Permits you to set validation rules, as described in the tutorial diff --git a/user_guide_src/source/libraries/input.rst b/user_guide_src/source/libraries/input.rst index 7f995f050..c0b9c6589 100644 --- a/user_guide_src/source/libraries/input.rst +++ b/user_guide_src/source/libraries/input.rst @@ -42,14 +42,14 @@ this:: Please refer to the :doc:`Security class <security>` documentation for information on using XSS Filtering in your application. -Using POST, COOKIE, or SERVER Data -================================== +Using POST, GET, COOKIE, or SERVER Data +======================================= -CodeIgniter comes with three helper functions that let you fetch POST, +CodeIgniter comes with four helper methods that let you fetch POST, GET, COOKIE or SERVER items. The main advantage of using the provided functions rather than fetching an item directly ($_POST['something']) -is that the functions will check to see if the item is set and return -false (boolean) if not. This lets you conveniently use data without +is that the methods will check to see if the item is set and return +NULL if not. This lets you conveniently use data without having to test whether an item exists first. In other words, normally you might do something like this:: @@ -59,9 +59,10 @@ With CodeIgniter's built in functions you can simply do this:: $something = $this->input->post('something'); -The three functions are: +The four methods are: - $this->input->post() +- $this->input->get() - $this->input->cookie() - $this->input->server() @@ -73,8 +74,8 @@ looking for:: $this->input->post('some_data'); -The function returns FALSE (boolean) if the item you are attempting to -retrieve does not exist. +The function returns NULL if the item you are attempting to retrieve +does not exist. The second optional parameter lets you run the data through the XSS filter. It's enabled by setting the second parameter to boolean TRUE; @@ -130,7 +131,9 @@ $this->input->cookie() This function is identical to the post function, only it fetches cookie data:: - $this->input->cookie('some_data', TRUE); + $this->input->cookie('some_cookie'); + $this->input->cookie('some_cookie, TRUE); // with XSS filter + $this->input->server() ====================== @@ -195,25 +198,6 @@ parameters:: $this->input->set_cookie($name, $value, $expire, $domain, $path, $prefix, $secure); -$this->input->cookie() -====================== - -Lets you fetch a cookie. The first parameter will contain the name of -the cookie you are looking for (including any prefixes):: - - cookie('some_cookie'); - -The function returns NULL if the item you are attempting to -retrieve does not exist. - -The second optional parameter lets you run the data through the XSS -filter. It's enabled by setting the second parameter to boolean TRUE; - -:: - - cookie('some_cookie', TRUE); - - $this->input->ip_address() =========================== |