diff options
-rw-r--r-- | .travis.yml | 4 | ||||
-rwxr-xr-x | system/core/Input.php | 135 | ||||
-rw-r--r-- | system/database/DB_active_rec.php | 12 | ||||
-rw-r--r-- | system/database/DB_driver.php | 22 | ||||
-rw-r--r-- | system/database/drivers/pdo/pdo_driver.php | 29 | ||||
-rw-r--r-- | system/database/drivers/pdo/pdo_result.php | 13 | ||||
-rw-r--r-- | system/libraries/Driver.php | 2 | ||||
-rw-r--r-- | system/libraries/Form_validation.php | 5 | ||||
-rw-r--r-- | system/libraries/Image_lib.php | 2 | ||||
-rw-r--r-- | user_guide/changelog.html | 6 | ||||
-rw-r--r-- | user_guide/installation/upgrade_211.html | 7 | ||||
-rw-r--r-- | user_guide/libraries/form_validation.html | 2 | ||||
-rw-r--r-- | user_guide/libraries/input.html | 2 | ||||
-rw-r--r-- | user_guide/libraries/sessions.html | 2 | ||||
-rw-r--r-- | user_guide/libraries/uri.html | 2 |
15 files changed, 207 insertions, 38 deletions
diff --git a/.travis.yml b/.travis.yml new file mode 100644 index 000000000..b3456f3a8 --- /dev/null +++ b/.travis.yml @@ -0,0 +1,4 @@ +branches: + except: + - 2.1-stable + - master
\ No newline at end of file diff --git a/system/core/Input.php b/system/core/Input.php index 9bfb5f1fb..3559d8607 100755 --- a/system/core/Input.php +++ b/system/core/Input.php @@ -365,18 +365,70 @@ class CI_Input { /** * Validate IP Address * + * @access public + * @param string + * @param string ipv4 or ipv6 + * @return bool + */ + public function valid_ip($ip, $which = '') + { + $which = strtolower($which); + + // First check if filter_var is available + if (is_callable('filter_var')) + { + switch ($which) { + case 'ipv4': + $flag = FILTER_FLAG_IPV4; + break; + case 'ipv6': + $flag = FILTER_FLAG_IPV6; + break; + default: + $flag = ''; + break; + } + + return (bool) filter_var($ip, FILTER_VALIDATE_IP, $flag); + } + + if ($which !== 'ipv6' && $which !== 'ipv4') + { + if (strpos($ip, ':') !== FALSE) + { + $which = 'ipv6'; + } + elseif (strpos($ip, '.') !== FALSE) + { + $which = 'ipv4'; + } + else + { + return FALSE; + } + } + + $func = '_valid_'.$which; + return $this->$func($ip); + } + + // -------------------------------------------------------------------- + + /** + * Validate IPv4 Address + * * Updated version suggested by Geert De Deckere * - * @access public + * @access protected * @param string - * @return string + * @return bool */ - function valid_ip($ip) + protected function _valid_ipv4($ip) { $ip_segments = explode('.', $ip); // Always 4 segments needed - if (count($ip_segments) != 4) + if (count($ip_segments) !== 4) { return FALSE; } @@ -385,6 +437,7 @@ class CI_Input { { return FALSE; } + // Check each segment foreach ($ip_segments as $segment) { @@ -402,6 +455,80 @@ class CI_Input { // -------------------------------------------------------------------- /** + * Validate IPv6 Address + * + * @access protected + * @param string + * @return bool + */ + protected function _valid_ipv6($str) + { + // 8 groups, separated by : + // 0-ffff per group + // one set of consecutive 0 groups can be collapsed to :: + + $groups = 8; + $collapsed = FALSE; + + $chunks = array_filter( + preg_split('/(:{1,2})/', $str, NULL, PREG_SPLIT_DELIM_CAPTURE) + ); + + // Rule out easy nonsense + if (current($chunks) == ':' OR end($chunks) == ':') + { + return FALSE; + } + + // PHP supports IPv4-mapped IPv6 addresses, so we'll expect those as well + if (strpos(end($chunks), '.') !== FALSE) + { + $ipv4 = array_pop($chunks); + + if ( ! $this->_valid_ipv4($ipv4)) + { + return FALSE; + } + + $groups--; + } + + while ($seg = array_pop($chunks)) + { + if ($seg[0] == ':') + { + if (--$groups == 0) + { + return FALSE; // too many groups + } + + if (strlen($seg) > 2) + { + return FALSE; // long separator + } + + if ($seg == '::') + { + if ($collapsed) + { + return FALSE; // multiple collapsed + } + + $collapsed = TRUE; + } + } + elseif (preg_match("/[^0-9a-f]/i", $seg) OR strlen($seg) > 4) + { + return FALSE; // invalid segment + } + } + + return $collapsed OR $groups == 1; + } + + // -------------------------------------------------------------------- + + /** * User Agent * * @access public diff --git a/system/database/DB_active_rec.php b/system/database/DB_active_rec.php index 7bab729f5..10febb1fc 100644 --- a/system/database/DB_active_rec.php +++ b/system/database/DB_active_rec.php @@ -255,7 +255,7 @@ class CI_DB_active_record extends CI_DB_driver { */ public function from($from) { - foreach ((array)$from as $val) + foreach ((array) $from as $val) { if (strpos($val, ',') !== FALSE) { @@ -660,8 +660,12 @@ class CI_DB_active_record extends CI_DB_driver { $prefix = (count($this->ar_like) == 0) ? '' : $type; $v = $this->escape_like_str($v); - - if ($side == 'before') + + if ($side == 'none') + { + $like_statement = $prefix." $k $not LIKE '{$v}'"; + } + elseif ($side == 'before') { $like_statement = $prefix." $k $not LIKE '%{$v}'"; } @@ -1643,7 +1647,7 @@ class CI_DB_active_record extends CI_DB_driver { if (strpos($table, " ") !== FALSE) { // if the alias is written with the AS keyword, remove it - $table = preg_replace('/ AS /i', ' ', $table); + $table = preg_replace('/\s+AS\s+/i', ' ', $table); // Grab the alias $table = trim(strrchr($table, " ")); diff --git a/system/database/DB_driver.php b/system/database/DB_driver.php index 6161f149b..858ec356d 100644 --- a/system/database/DB_driver.php +++ b/system/database/DB_driver.php @@ -1263,15 +1263,20 @@ class CI_DB_driver { } // Convert tabs or multiple spaces into single spaces - $item = preg_replace('/[\t ]+/', ' ', $item); + $item = preg_replace('/\s+/', ' ', $item); // If the item has an alias declaration we remove it and set it aside. // Basically we remove everything to the right of the first space - $alias = ''; - if (strpos($item, ' ') !== FALSE) + if (preg_match('/^([^\s]+) (AS )*(.+)$/i', $item, $matches)) { - $alias = strstr($item, " "); - $item = substr($item, 0, - strlen($alias)); + $item = $matches[1]; + + // Escape the alias + $alias = ' '.$matches[2].$this->_escape_identifiers($matches[3]); + } + else + { + $alias = ''; } // This is basically a bug fix for queries that use MAX, MIN, etc. @@ -1387,7 +1392,7 @@ class CI_DB_driver { return $item.$alias; } - + // -------------------------------------------------------------------- /** @@ -1395,16 +1400,13 @@ class CI_DB_driver { * * This function is used extensively by every db driver. * - * @access private * @return void */ protected function _reset_select() { - } } - /* End of file DB_driver.php */ -/* Location: ./system/database/DB_driver.php */ +/* Location: ./system/database/DB_driver.php */
\ No newline at end of file diff --git a/system/database/drivers/pdo/pdo_driver.php b/system/database/drivers/pdo/pdo_driver.php index 4fc65aeb4..654074cd1 100644 --- a/system/database/drivers/pdo/pdo_driver.php +++ b/system/database/drivers/pdo/pdo_driver.php @@ -51,23 +51,23 @@ class CI_DB_pdo_driver extends CI_DB { function __construct($params) { parent::__construct($params); - + // clause and character used for LIKE escape sequences if (strpos($this->hostname, 'mysql') !== FALSE) { $this->_like_escape_str = ''; $this->_like_escape_chr = ''; - + //Prior to this version, the charset can't be set in the dsn if(is_php('5.3.6')) { $this->hostname .= ";charset={$this->char_set}"; } - + //Set the charset with the connection options $this->options['PDO::MYSQL_ATTR_INIT_COMMAND'] = "SET NAMES {$this->char_set}"; } - else if (strpos($this->hostname, 'odbc') !== FALSE) + elseif (strpos($this->hostname, 'odbc') !== FALSE) { $this->_like_escape_str = " {escape '%s'} "; $this->_like_escape_chr = '!'; @@ -77,9 +77,9 @@ class CI_DB_pdo_driver extends CI_DB { $this->_like_escape_str = " ESCAPE '%s' "; $this->_like_escape_chr = '!'; } - - $this->hostname .= ";dbname=".$this->database; - + + empty($this->database) OR $this->hostname .= ';dbname='.$this->database; + $this->trans_enabled = FALSE; $this->_random_keyword = ' RND('.time().')'; // database specific random keyword @@ -94,7 +94,7 @@ class CI_DB_pdo_driver extends CI_DB { function db_connect() { $this->options['PDO::ATTR_ERRMODE'] = PDO::ERRMODE_SILENT; - + return new PDO($this->hostname, $this->username, $this->password, $this->options); } @@ -189,11 +189,20 @@ class CI_DB_pdo_driver extends CI_DB { function _execute($sql) { $sql = $this->_prep_query($sql); - $result_id = $this->conn_id->query($sql); + $result_id = $this->conn_id->prepare($sql); + $result_id->execute(); if (is_object($result_id)) { - $this->affect_rows = $result_id->rowCount(); + if (is_numeric(stripos($sql, 'SELECT'))) + { + $this->affect_rows = count($result_id->fetchAll()); + $result_id->execute(); + } + else + { + $this->affect_rows = $result_id->rowCount(); + } } else { diff --git a/system/database/drivers/pdo/pdo_result.php b/system/database/drivers/pdo/pdo_result.php index 7c4a2f977..650b5f98d 100644 --- a/system/database/drivers/pdo/pdo_result.php +++ b/system/database/drivers/pdo/pdo_result.php @@ -34,7 +34,18 @@ class CI_DB_pdo_result extends CI_DB_result { */ function num_rows() { - return $this->result_id->rowCount(); + if (is_numeric(stripos($this->result_id->queryString, 'SELECT'))) + { + $dbh = $this->conn_id; + $query = $dbh->query($this->result_id->queryString); + $result = $query->fetchAll(); + unset($dbh, $query); + return count($result); + } + else + { + return $this->result_id->rowCount(); + } } // -------------------------------------------------------------------- diff --git a/system/libraries/Driver.php b/system/libraries/Driver.php index f9959ff81..4912c4aa7 100644 --- a/system/libraries/Driver.php +++ b/system/libraries/Driver.php @@ -30,7 +30,7 @@ class CI_Driver_Library { protected $valid_drivers = array(); - protected static $lib_name; + protected $lib_name; // The first time a child is used it won't exist, so we instantiate it // subsequents calls will go straight to the proper child. diff --git a/system/libraries/Form_validation.php b/system/libraries/Form_validation.php index a34809e05..9aab5da4b 100644 --- a/system/libraries/Form_validation.php +++ b/system/libraries/Form_validation.php @@ -1079,11 +1079,12 @@ class CI_Form_validation { * * @access public * @param string + * @param string "ipv4" or "ipv6" to validate a specific ip format * @return string */ - public function valid_ip($ip) + public function valid_ip($ip, $which = '') { - return $this->CI->input->valid_ip($ip); + return $this->CI->input->valid_ip($ip, $which); } // -------------------------------------------------------------------- diff --git a/system/libraries/Image_lib.php b/system/libraries/Image_lib.php index 7f905128b..21ec2cb4b 100644 --- a/system/libraries/Image_lib.php +++ b/system/libraries/Image_lib.php @@ -104,7 +104,7 @@ class CI_Image_lib { */ function clear() { - $props = array('source_folder', 'dest_folder', 'source_image', 'full_src_path', 'full_dst_path', 'new_image', 'image_type', 'size_str', 'quality', 'orig_width', 'orig_height', 'rotation_angle', 'x_axis', 'y_axis', 'create_fnc', 'copy_fnc', 'wm_overlay_path', 'wm_use_truetype', 'dynamic_output', 'wm_font_size', 'wm_text', 'wm_vrt_alignment', 'wm_hor_alignment', 'wm_padding', 'wm_hor_offset', 'wm_vrt_offset', 'wm_font_color', 'wm_use_drop_shadow', 'wm_shadow_color', 'wm_shadow_distance', 'wm_opacity'); + $props = array('source_folder', 'dest_folder', 'source_image', 'full_src_path', 'full_dst_path', 'new_image', 'image_type', 'size_str', 'quality', 'orig_width', 'orig_height', 'width', 'height', 'rotation_angle', 'x_axis', 'y_axis', 'create_fnc', 'copy_fnc', 'wm_overlay_path', 'wm_use_truetype', 'dynamic_output', 'wm_font_size', 'wm_text', 'wm_vrt_alignment', 'wm_hor_alignment', 'wm_padding', 'wm_hor_offset', 'wm_vrt_offset', 'wm_font_color', 'wm_use_drop_shadow', 'wm_shadow_color', 'wm_shadow_distance', 'wm_opacity'); foreach ($props as $val) { diff --git a/user_guide/changelog.html b/user_guide/changelog.html index d8fa374cb..e033864be 100644 --- a/user_guide/changelog.html +++ b/user_guide/changelog.html @@ -69,6 +69,8 @@ Change Log <li>Libraries <ul> <li>Further improved MIME type detection in the <a href="libraries/file_uploading.html">File Uploading Library</a>.</li> + <li>Added support for IPv6 to the <a href="libraries/input.html">Input Library</a>.</li> + <li>Added support for the IP format parameter to the <a href="libraries/form_validation.html">Form Validation Library</a>.</li> </ul> </li> <li>Helpers @@ -86,6 +88,10 @@ Change Log <li>Fixed a bug (#538) - Windows paths were ignored when using the <a href="libraries/image_lib.html">Image Manipulation Class</a> to create a new file.</li> <li>Fixed a bug - When database caching was enabled, $this->db->query() checked the cache before binding variables which resulted in cached queries never being found.</li> <li>Fixed a bug - CSRF cookie value was allowed to be any (non-empty) string before being written to the output, making code injection a risk.</li> + <li>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.</li> + <li>Fixed a bug - CI_DB_pdo_result::num_rows() was not returning properly value with SELECT queries, cause it was relying on PDOStatement::rowCount().</li> + <li>Fixed a bug (#1059) - CI_Image_lib::clear() was not correctly clearing all necessary object properties, namely width and height.</li> + <li>Fixed a bug (#1387) - Active Record's <samp>from()</samp> method didn't escape table aliases.</li> </ul> diff --git a/user_guide/installation/upgrade_211.html b/user_guide/installation/upgrade_211.html index a2afdee2b..92b5faab1 100644 --- a/user_guide/installation/upgrade_211.html +++ b/user_guide/installation/upgrade_211.html @@ -3,7 +3,7 @@ <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> -<title>Upgrading from 2.0.3 to 2.1.0 : CodeIgniter User Guide</title> +<title>Upgrading from 2.1.0 to 2.1.1 : CodeIgniter User Guide</title> <style type='text/css' media='all'>@import url('../userguide.css');</style> <link rel='stylesheet' type='text/css' media='all' href='../userguide.css' /> @@ -69,6 +69,11 @@ Upgrading from 2.1.0 to 2.1.1 <p>This config file has been updated to contain more user mime-types, please copy it to <kbd>application/config/mimes.php</kbd>.</p> +<h2>Step 3: Update your IP address tables:</h2> + +<p>This upgrade adds support for IPv6 IP addresses. In order to store them, you need to enlarge your <var>ip_address</var> columns to 45 characters. For example, CodeIgniter's session table will need to change:</p> + +<code>ALTER TABLE ci_sessions CHANGE ip_address ip_address varchar(45) default '0' NOT NULL</code> </div> <!-- END CONTENT --> diff --git a/user_guide/libraries/form_validation.html b/user_guide/libraries/form_validation.html index 81f2b9582..8d6f3b6d2 100644 --- a/user_guide/libraries/form_validation.html +++ b/user_guide/libraries/form_validation.html @@ -1058,7 +1058,7 @@ POST array:</p> <tr> <td class="td"><strong>valid_ip</strong></td> <td class="td">No</td> - <td class="td">Returns FALSE if the supplied IP is not valid.</td> + <td class="td">Returns FALSE if the supplied IP is not valid. Accepts an optional parameter of "IPv4" or "IPv6" to specify an IP format.</td> <td class="td"> </td> </tr> diff --git a/user_guide/libraries/input.html b/user_guide/libraries/input.html index 2f2d1830b..e199c58dd 100644 --- a/user_guide/libraries/input.html +++ b/user_guide/libraries/input.html @@ -248,7 +248,7 @@ else<br /> {<br /> echo 'Valid';<br /> }</code> - +<p>Accepts an optional second string parameter of "IPv4" or "IPv6" to specify an IP format. The default checks for both formats.</p> <h2>$this->input->user_agent()</h2> <p>Returns the user agent (web browser) being used by the current user. Returns FALSE if it's not available.</p> diff --git a/user_guide/libraries/sessions.html b/user_guide/libraries/sessions.html index ba9085f59..bfffa0b2f 100644 --- a/user_guide/libraries/sessions.html +++ b/user_guide/libraries/sessions.html @@ -221,7 +221,7 @@ prototype (for MySQL) required by the session class:</p> <textarea class="textarea" style="width:100%" cols="50" rows="10"> CREATE TABLE IF NOT EXISTS `ci_sessions` ( session_id varchar(40) DEFAULT '0' NOT NULL, - ip_address varchar(16) DEFAULT '0' NOT NULL, + ip_address varchar(45) DEFAULT '0' NOT NULL, user_agent varchar(120) NOT NULL, last_activity int(10) unsigned DEFAULT 0 NOT NULL, user_data text NOT NULL, diff --git a/user_guide/libraries/uri.html b/user_guide/libraries/uri.html index 9b9b5d889..f333199ac 100644 --- a/user_guide/libraries/uri.html +++ b/user_guide/libraries/uri.html @@ -191,7 +191,7 @@ $str = $this->uri->assoc_to_uri($array);<br /> <p>The function would return this:</p> -<code>/news/local/345</code> +<code>news/local/345</code> <h2>$this->uri->ruri_string()</h2> |