diff options
Diffstat (limited to 'system')
-rwxr-xr-x | system/core/CodeIgniter.php | 20 | ||||
-rwxr-xr-x | system/core/Input.php | 2 | ||||
-rwxr-xr-x | system/core/Security.php | 72 | ||||
-rw-r--r-- | system/database/DB_active_rec.php | 2 | ||||
-rw-r--r-- | system/database/DB_driver.php | 7 | ||||
-rw-r--r-- | system/database/drivers/mysql/mysql_driver.php | 19 | ||||
-rw-r--r-- | system/database/drivers/mysqli/mysqli_driver.php | 21 | ||||
-rw-r--r-- | system/database/drivers/pdo/index.html | 10 | ||||
-rw-r--r-- | system/database/drivers/pdo/pdo_driver.php | 691 | ||||
-rw-r--r-- | system/database/drivers/pdo/pdo_forge.php | 266 | ||||
-rw-r--r-- | system/database/drivers/pdo/pdo_result.php | 171 | ||||
-rw-r--r-- | system/database/drivers/pdo/pdo_utility.php | 103 | ||||
-rw-r--r-- | system/helpers/html_helper.php | 2 | ||||
-rw-r--r-- | system/helpers/typography_helper.php | 7 | ||||
-rw-r--r-- | system/libraries/Email.php | 30 | ||||
-rw-r--r-- | system/libraries/Sha1.php | 4 | ||||
-rw-r--r-- | system/libraries/Table.php | 4 | ||||
-rw-r--r-- | system/libraries/Typography.php | 4 | ||||
-rw-r--r-- | system/libraries/Unit_test.php | 4 | ||||
-rw-r--r-- | system/libraries/Upload.php | 66 | ||||
-rw-r--r-- | system/libraries/User_agent.php | 4 |
21 files changed, 1382 insertions, 127 deletions
diff --git a/system/core/CodeIgniter.php b/system/core/CodeIgniter.php index aca4fb23c..9f88384b1 100755 --- a/system/core/CodeIgniter.php +++ b/system/core/CodeIgniter.php @@ -33,28 +33,8 @@ * @var string * */ - /** - * CodeIgniter Version - * - * @var string - * - */ define('CI_VERSION', '2.1.0-dev'); -/** - * CodeIgniter Branch (Core = TRUE, Reactor = FALSE) - * - * @var boolean - * - */ - /** - * CodeIgniter Branch (Core = TRUE, Reactor = FALSE) - * - * @var string - * - */ - define('CI_CORE', FALSE); - /* * ------------------------------------------------------ * Load the global functions diff --git a/system/core/Input.php b/system/core/Input.php index f39371fb0..6f8442107 100755 --- a/system/core/Input.php +++ b/system/core/Input.php @@ -555,7 +555,7 @@ class CI_Input { } // We strip slashes if magic quotes is on to keep things consistent - if (function_exists('get_magic_quotes_gpc') AND get_magic_quotes_gpc()) + if (function_exists('get_magic_quotes_gpc') AND @get_magic_quotes_gpc()) { $str = stripslashes($str); } diff --git a/system/core/Security.php b/system/core/Security.php index 6c4c59057..65338ced3 100755 --- a/system/core/Security.php +++ b/system/core/Security.php @@ -33,7 +33,7 @@ class CI_Security { * @access protected */ protected $_xss_hash = ''; - + /** * Random Hash for Cross Site Request Forgery Protection Cookie * @@ -41,7 +41,7 @@ class CI_Security { * @access protected */ protected $_csrf_hash = ''; - + /** * Expiration time for Cross Site Request Forgery Protection Cookie * Defaults to two hours (in seconds) @@ -50,7 +50,7 @@ class CI_Security { * @access protected */ protected $_csrf_expire = 7200; - + /** * Token name for Cross Site Request Forgery Protection Cookie * @@ -58,7 +58,7 @@ class CI_Security { * @access protected */ protected $_csrf_token_name = 'ci_csrf_token'; - + /** * Cookie name for Cross Site Request Forgery Protection Cookie * @@ -66,14 +66,14 @@ class CI_Security { * @access protected */ protected $_csrf_cookie_name = 'ci_csrf_token'; - + /** * List of never allowed strings * * @var array * @access protected */ - + protected $_never_allowed_str = array( 'document.cookie' => '[removed]', 'document.write' => '[removed]', @@ -139,7 +139,7 @@ class CI_Security { { return $this->csrf_set_cookie(); } - + // Check if URI has been whitelisted from CSRF checks if ($exclude_uris = config_item('csrf_exclude_uris')) { @@ -172,9 +172,9 @@ class CI_Security { $this->_csrf_hash = ''; $this->_csrf_set_hash(); $this->csrf_set_cookie(); - + log_message('debug', "CSRF token verified"); - + return $this; } @@ -188,7 +188,7 @@ class CI_Security { public function csrf_set_cookie() { $expire = time() + $this->_csrf_expire; - $secure_cookie = (config_item('cookie_secure') === TRUE) ? 1 : 0; + $secure_cookie = (bool) config_item('cookie_secure'); if ($secure_cookie) { @@ -385,16 +385,11 @@ class CI_Security { foreach ($words as $word) { - $temp = ''; - - for ($i = 0, $wordlen = strlen($word); $i < $wordlen; $i++) - { - $temp .= substr($word, $i, 1)."\s*"; - } + $word = implode("\s*", str_split($word)) . "\s*"; // We only want to do this when it is followed by a non-word character // That way valid stuff like "dealer to" does not become "dealerto" - $str = preg_replace_callback('#('.substr($temp, 0, -3).')(\W)#is', array($this, '_compact_exploded_words'), $str); + $str = preg_replace_callback('#('.substr($word, 0, -3).')(\W)#is', array($this, '_compact_exploded_words'), $str); } /* @@ -473,7 +468,7 @@ class CI_Security { if ($is_image === TRUE) { - return ($str == $converted_string) ? TRUE: FALSE; + return ($str === $converted_string) ? TRUE : FALSE; } log_message('debug', "XSS Filtering completed"); @@ -513,26 +508,17 @@ class CI_Security { * * This function is a replacement for html_entity_decode() * - * In some versions of PHP the native function does not work - * when UTF-8 is the specified character set, so this gives us - * a work-around. More info here: - * http://bugs.php.net/bug.php?id=25670 - * - * NOTE: html_entity_decode() has a bug in some PHP versions when UTF-8 is the - * character set, and the PHP developers said they were not back porting the - * fix to versions other than PHP 5.x. - * * @param string * @param string * @return string */ public function entity_decode($str, $charset = NULL) { - if (stristr($str, '&') === FALSE) + if (strpos($str, '&') === FALSE) { return $str; } - + if (empty($charset)) { $charset = config_item('charset'); @@ -543,26 +529,9 @@ class CI_Security { // at the end of an entity most browsers will still interpret the entity // correctly. html_entity_decode() does not convert entities without // semicolons, so we are left with our own little solution here. Bummer. - - if (function_exists('html_entity_decode') && - (strtolower($charset) != 'utf-8')) - { - $str = html_entity_decode($str, ENT_COMPAT, $charset); - $str = preg_replace('~&#x(0*[0-9a-f]{2,5})~ei', 'chr(hexdec("\\1"))', $str); - return preg_replace('~&#([0-9]{2,4})~e', 'chr(\\1)', $str); - } - - // Numeric Entities - $str = preg_replace('~&#x(0*[0-9a-f]{2,5});{0,1}~ei', 'chr(hexdec("\\1"))', $str); - $str = preg_replace('~&#([0-9]{2,4});{0,1}~e', 'chr(\\1)', $str); - - // Literal Entities - Slightly slow so we do another check - if (stristr($str, '&') === FALSE) - { - $str = strtr($str, array_flip(get_html_translation_table(HTML_ENTITIES))); - } - - return $str; + $str = html_entity_decode($str, ENT_COMPAT, $charset); + $str = preg_replace('~&#x(0*[0-9a-f]{2,5})~ei', 'chr(hexdec("\\1"))', $str); + return preg_replace('~&#([0-9]{2,4})~e', 'chr(\\1)', $str); } // -------------------------------------------------------------------- @@ -886,7 +855,8 @@ class CI_Security { return $this->_csrf_hash = $_COOKIE[$this->_csrf_cookie_name]; } - return $this->_csrf_hash = md5(uniqid(rand(), TRUE)); + $this->_csrf_hash = md5(uniqid(rand(), TRUE)); + $this->csrf_set_cookie(); } return $this->_csrf_hash; @@ -895,4 +865,4 @@ class CI_Security { } /* End of file Security.php */ -/* Location: ./system/libraries/Security.php */
\ No newline at end of file +/* Location: ./system/core/Security.php */ diff --git a/system/database/DB_active_rec.php b/system/database/DB_active_rec.php index 7162e2ac5..83518232e 100644 --- a/system/database/DB_active_rec.php +++ b/system/database/DB_active_rec.php @@ -196,7 +196,7 @@ class CI_DB_active_record extends CI_DB_driver { $alias = $this->_create_alias_from_table(trim($select)); } - $sql = $type.'('.$this->_protect_identifiers(trim($select)).') AS '.$this->_protect_identifiers(trim($alias)); + $sql = $this->_protect_identifiers($type.'('.trim($select).')').' AS '.$this->_protect_identifiers(trim($alias)); $this->ar_select[] = $sql; diff --git a/system/database/DB_driver.php b/system/database/DB_driver.php index 300ca2977..237a4fcea 100644 --- a/system/database/DB_driver.php +++ b/system/database/DB_driver.php @@ -218,7 +218,7 @@ class CI_DB_driver { // Some DBs have functions that return the version, and don't run special // SQL queries per se. In these instances, just return the result. - $driver_version_exceptions = array('oci8', 'sqlite', 'cubrid'); + $driver_version_exceptions = array('oci8', 'sqlite', 'cubrid', 'pdo'); if (in_array($this->dbdriver, $driver_version_exceptions)) { @@ -950,6 +950,7 @@ class CI_DB_driver { foreach ($where as $key => $val) { $prefix = (count($dest) == 0) ? '' : ' AND '; + $key = $this->_protect_identifiers($key); if ($val !== '') { @@ -1165,7 +1166,7 @@ class CI_DB_driver { if ($native == TRUE) { - $message = $error; + $message = (array) $error; } else { @@ -1390,4 +1391,4 @@ class CI_DB_driver { /* End of file DB_driver.php */ -/* Location: ./system/database/DB_driver.php */
\ No newline at end of file +/* Location: ./system/database/DB_driver.php */ diff --git a/system/database/drivers/mysql/mysql_driver.php b/system/database/drivers/mysql/mysql_driver.php index f87cfea4b..dc020c624 100644 --- a/system/database/drivers/mysql/mysql_driver.php +++ b/system/database/drivers/mysql/mysql_driver.php @@ -56,7 +56,7 @@ class CI_DB_mysql_driver extends CI_DB { // whether SET NAMES must be used to set the character set var $use_set_names; - + /** * Non-persistent database connection * @@ -135,20 +135,9 @@ class CI_DB_mysql_driver extends CI_DB { */ function db_set_charset($charset, $collation) { - if ( ! isset($this->use_set_names)) - { - // mysql_set_charset() requires PHP >= 5.2.3 and MySQL >= 5.0.7, use SET NAMES as fallback - $this->use_set_names = (version_compare(PHP_VERSION, '5.2.3', '>=') && version_compare(mysql_get_server_info(), '5.0.7', '>=')) ? FALSE : TRUE; - } - - if ($this->use_set_names === TRUE) - { - return @mysql_query("SET NAMES '".$this->escape_str($charset)."' COLLATE '".$this->escape_str($collation)."'", $this->conn_id); - } - else - { - return @mysql_set_charset($charset, $this->conn_id); - } + return function_exists('mysql_set_charset') + ? @mysql_set_charset($charset, $this->conn_id) + : @mysql_query("SET NAMES '".$this->escape_str($charset)."' COLLATE '".$this->escape_str($collation)."'", $this->conn_id); } // -------------------------------------------------------------------- diff --git a/system/database/drivers/mysqli/mysqli_driver.php b/system/database/drivers/mysqli/mysqli_driver.php index ccd110f79..abef80fbd 100644 --- a/system/database/drivers/mysqli/mysqli_driver.php +++ b/system/database/drivers/mysqli/mysqli_driver.php @@ -56,7 +56,7 @@ class CI_DB_mysqli_driver extends CI_DB { // whether SET NAMES must be used to set the character set var $use_set_names; - + // -------------------------------------------------------------------- /** @@ -135,20 +135,9 @@ class CI_DB_mysqli_driver extends CI_DB { */ function _db_set_charset($charset, $collation) { - if ( ! isset($this->use_set_names)) - { - // mysqli_set_charset() requires MySQL >= 5.0.7, use SET NAMES as fallback - $this->use_set_names = (version_compare(mysqli_get_server_info($this->conn_id), '5.0.7', '>=')) ? FALSE : TRUE; - } - - if ($this->use_set_names === TRUE) - { - return @mysqli_query($this->conn_id, "SET NAMES '".$this->escape_str($charset)."' COLLATE '".$this->escape_str($collation)."'"); - } - else - { - return @mysqli_set_charset($this->conn_id, $charset); - } + return function_exists('mysqli_set_charset') + ? @mysqli_set_charset($this->conn_id, $charset) + : @mysqli_query($this->conn_id, "SET NAMES '".$this->escape_str($charset)."' COLLATE '".$this->escape_str($collation)."'"); } // -------------------------------------------------------------------- @@ -570,7 +559,7 @@ class CI_DB_mysqli_driver extends CI_DB { { return "INSERT INTO ".$table." (".implode(', ', $keys).") VALUES ".implode(', ', $values); } - + // -------------------------------------------------------------------- /** diff --git a/system/database/drivers/pdo/index.html b/system/database/drivers/pdo/index.html new file mode 100644 index 000000000..c942a79ce --- /dev/null +++ b/system/database/drivers/pdo/index.html @@ -0,0 +1,10 @@ +<html> +<head> + <title>403 Forbidden</title> +</head> +<body> + +<p>Directory access is forbidden.</p> + +</body> +</html>
\ No newline at end of file diff --git a/system/database/drivers/pdo/pdo_driver.php b/system/database/drivers/pdo/pdo_driver.php new file mode 100644 index 000000000..c5a215b82 --- /dev/null +++ b/system/database/drivers/pdo/pdo_driver.php @@ -0,0 +1,691 @@ +<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed'); +/** + * CodeIgniter + * + * An open source application development framework for PHP 5.1.6 or newer + * + * @package CodeIgniter + * @author ExpressionEngine Dev Team + * @copyright Copyright (c) 2008 - 2011, EllisLab, Inc. + * @license http://codeigniter.com/user_guide/license.html + * @link http://codeigniter.com + * @since Version 2.1.0 + * @filesource + */ + +// ------------------------------------------------------------------------ + +/** + * PDO Database Adapter Class + * + * Note: _DB is an extender class that the app controller + * creates dynamically based on whether the active record + * class is being used or not. + * + * @package CodeIgniter + * @subpackage Drivers + * @category Database + * @author ExpressionEngine Dev Team + * @link http://codeigniter.com/user_guide/database/ + */ +class CI_DB_pdo_driver extends CI_DB { + + var $dbdriver = 'pdo'; + + // the character used to excape - not necessary for PDO + var $_escape_char = ''; + var $_like_escape_str; + var $_like_escape_chr; + + + /** + * The syntax to count rows is slightly different across different + * database engines, so this string appears in each driver and is + * used for the count_all() and count_all_results() functions. + */ + var $_count_string = "SELECT COUNT(*) AS "; + var $_random_keyword; + + + function __construct($params) + { + parent::CI_DB($params); + + // clause and character used for LIKE escape sequences + if(strpos($this->hostname, 'mysql') !== FALSE) + { + $this->_like_escape_str = ''; + $this->_like_escape_chr = ''; + } + else if(strpos($this->hostname, 'odbc') !== FALSE) + { + $this->_like_escape_str = " {escape '%s'} "; + $this->_like_escape_chr = '!'; + } + else + { + $this->_like_escape_str = " ESCAPE '%s' "; + $this->_like_escape_chr = '!'; + } + + $this->hostname = $this->hostname . ";dbname=".$this->database; + $this->trans_enabled = FALSE; + + $this->_random_keyword = ' RND('.time().')'; // database specific random keyword + } + + /** + * Non-persistent database connection + * + * @access private called by the base class + * @return resource + */ + function db_connect() + { + return new PDO($this->hostname,$this->username,$this->password, array( + PDO::ATTR_ERRMODE => PDO::ERRMODE_SILENT + )); + } + + // -------------------------------------------------------------------- + + /** + * Persistent database connection + * + * @access private called by the base class + * @return resource + */ + function db_pconnect() + { + return new PDO($this->hostname,$this->username,$this->password, array( + PDO::ATTR_ERRMODE => PDO::ERRMODE_SILENT, + PDO::ATTR_PERSISTENT => true + )); + } + + // -------------------------------------------------------------------- + + /** + * Reconnect + * + * Keep / reestablish the db connection if no queries have been + * sent for a length of time exceeding the server's idle timeout + * + * @access public + * @return void + */ + function reconnect() + { + if ($this->db->db_debug) + { + return $this->db->display_error('db_unsuported_feature'); + } + return FALSE; + } + + // -------------------------------------------------------------------- + + /** + * Select the database + * + * @access private called by the base class + * @return resource + */ + function db_select() + { + // Not needed for PDO + return TRUE; + } + + // -------------------------------------------------------------------- + + /** + * Set client character set + * + * @access public + * @param string + * @param string + * @return resource + */ + function db_set_charset($charset, $collation) + { + // @todo - add support if needed + return TRUE; + } + + // -------------------------------------------------------------------- + + /** + * Version number query string + * + * @access public + * @return string + */ + function _version() + { + return $this->conn_id->getAttribute(PDO::ATTR_CLIENT_VERSION); + } + + // -------------------------------------------------------------------- + + /** + * Execute the query + * + * @access private called by the base class + * @param string an SQL query + * @return object + */ + function _execute($sql) + { + $sql = $this->_prep_query($sql); + $result_id = $this->conn_id->query($sql); + + $this->affect_rows = $result_id->rowCount(); + + return $result_id; + } + + // -------------------------------------------------------------------- + + /** + * Prep the query + * + * If needed, each database adapter can prep the query string + * + * @access private called by execute() + * @param string an SQL query + * @return string + */ + function _prep_query($sql) + { + return $sql; + } + + // -------------------------------------------------------------------- + + /** + * Begin Transaction + * + * @access public + * @return bool + */ + function trans_begin($test_mode = FALSE) + { + if ( ! $this->trans_enabled) + { + return TRUE; + } + + // When transactions are nested we only begin/commit/rollback the outermost ones + if ($this->_trans_depth > 0) + { + return TRUE; + } + + // Reset the transaction failure flag. + // If the $test_mode flag is set to TRUE transactions will be rolled back + // even if the queries produce a successful result. + $this->_trans_failure = ($test_mode === TRUE) ? TRUE : FALSE; + + return $this->conn_id->beginTransaction(); + } + + // -------------------------------------------------------------------- + + /** + * Commit Transaction + * + * @access public + * @return bool + */ + function trans_commit() + { + if ( ! $this->trans_enabled) + { + return TRUE; + } + + // When transactions are nested we only begin/commit/rollback the outermost ones + if ($this->_trans_depth > 0) + { + return TRUE; + } + + $ret = $this->conn->commit(); + return $ret; + } + + // -------------------------------------------------------------------- + + /** + * Rollback Transaction + * + * @access public + * @return bool + */ + function trans_rollback() + { + if ( ! $this->trans_enabled) + { + return TRUE; + } + + // When transactions are nested we only begin/commit/rollback the outermost ones + if ($this->_trans_depth > 0) + { + return TRUE; + } + + $ret = $this->conn_id->rollBack(); + return $ret; + } + + // -------------------------------------------------------------------- + + /** + * Escape String + * + * @access public + * @param string + * @param bool whether or not the string will be used in a LIKE condition + * @return string + */ + function escape_str($str, $like = FALSE) + { + if (is_array($str)) + { + foreach ($str as $key => $val) + { + $str[$key] = $this->escape_str($val, $like); + } + + return $str; + } + + // PDO doesn't require escaping + $str = remove_invisible_characters($str); + + // escape LIKE condition wildcards + if ($like === TRUE) + { + $str = str_replace( array('%', '_', $this->_like_escape_chr), + array($this->_like_escape_chr.'%', $this->_like_escape_chr.'_', $this->_like_escape_chr.$this->_like_escape_chr), + $str); + } + + return $str; + } + + // -------------------------------------------------------------------- + + /** + * Affected Rows + * + * @access public + * @return integer + */ + function affected_rows() + { + return $this->affect_rows; + } + + // -------------------------------------------------------------------- + + /** + * Insert ID + * + * @access public + * @return integer + */ + function insert_id($name=NULL) + { + return $this->conn_id->lastInsertId($name); + } + + // -------------------------------------------------------------------- + + /** + * "Count All" query + * + * Generates a platform-specific query string that counts all records in + * the specified database + * + * @access public + * @param string + * @return string + */ + function count_all($table = '') + { + if ($table == '') + { + return 0; + } + + $query = $this->query($this->_count_string . $this->_protect_identifiers('numrows') . " FROM " . $this->_protect_identifiers($table, TRUE, NULL, FALSE)); + + if ($query->num_rows() == 0) + { + return 0; + } + + $row = $query->row(); + $this->_reset_select(); + return (int) $row->numrows; + } + + // -------------------------------------------------------------------- + + /** + * Show table query + * + * Generates a platform-specific query string so that the table names can be fetched + * + * @access private + * @param boolean + * @return string + */ + function _list_tables($prefix_limit = FALSE) + { + $sql = "SHOW TABLES FROM `".$this->database."`"; + + if ($prefix_limit !== FALSE AND $this->dbprefix != '') + { + //$sql .= " LIKE '".$this->escape_like_str($this->dbprefix)."%' ".sprintf($this->_like_escape_str, $this->_like_escape_chr); + return FALSE; // not currently supported + } + + return $sql; + } + + // -------------------------------------------------------------------- + + /** + * Show column query + * + * Generates a platform-specific query string so that the column names can be fetched + * + * @access public + * @param string the table name + * @return string + */ + function _list_columns($table = '') + { + return "SHOW COLUMNS FROM ".$table; + } + + // -------------------------------------------------------------------- + + /** + * Field data query + * + * Generates a platform-specific query so that the column data can be retrieved + * + * @access public + * @param string the table name + * @return object + */ + function _field_data($table) + { + return "SELECT TOP 1 FROM ".$table; + } + + // -------------------------------------------------------------------- + + /** + * The error message string + * + * @access private + * @return string + */ + function _error_message() + { + $error_array = $this->conn_id->errorInfo(); + return $error_array[2]; + } + + // -------------------------------------------------------------------- + + /** + * The error message number + * + * @access private + * @return integer + */ + function _error_number() + { + return $this->conn_id->errorCode(); + } + + // -------------------------------------------------------------------- + + /** + * Escape the SQL Identifiers + * + * This function escapes column and table names + * + * @access private + * @param string + * @return string + */ + function _escape_identifiers($item) + { + if ($this->_escape_char == '') + { + return $item; + } + + foreach ($this->_reserved_identifiers as $id) + { + if (strpos($item, '.'.$id) !== FALSE) + { + $str = $this->_escape_char. str_replace('.', $this->_escape_char.'.', $item); + + // remove duplicates if the user already included the escape + return preg_replace('/['.$this->_escape_char.']+/', $this->_escape_char, $str); + } + } + + if (strpos($item, '.') !== FALSE) + { + $str = $this->_escape_char.str_replace('.', $this->_escape_char.'.'.$this->_escape_char, $item).$this->_escape_char; + + } + else + { + $str = $this->_escape_char.$item.$this->_escape_char; + } + + // remove duplicates if the user already included the escape + return preg_replace('/['.$this->_escape_char.']+/', $this->_escape_char, $str); + } + + // -------------------------------------------------------------------- + + /** + * From Tables + * + * This function implicitly groups FROM tables so there is no confusion + * about operator precedence in harmony with SQL standards + * + * @access public + * @param type + * @return type + */ + function _from_tables($tables) + { + if ( ! is_array($tables)) + { + $tables = array($tables); + } + + return (count($tables) == 1) ? $tables[0] : '('.implode(', ', $tables).')'; + } + + // -------------------------------------------------------------------- + + /** + * Insert statement + * + * Generates a platform-specific insert string from the supplied data + * + * @access public + * @param string the table name + * @param array the insert keys + * @param array the insert values + * @return string + */ + function _insert($table, $keys, $values) + { + return "INSERT INTO ".$table." (".implode(', ', $keys).") VALUES (".implode(', ', $values).")"; + } + + // -------------------------------------------------------------------- + + /** + * Update statement + * + * Generates a platform-specific update string from the supplied data + * + * @access public + * @param string the table name + * @param array the update data + * @param array the where clause + * @param array the orderby clause + * @param array the limit clause + * @return string + */ + function _update($table, $values, $where, $orderby = array(), $limit = FALSE) + { + foreach ($values as $key => $val) + { + $valstr[] = $key." = ".$val; + } + + $limit = ( ! $limit) ? '' : ' LIMIT '.$limit; + + $orderby = (count($orderby) >= 1)?' ORDER BY '.implode(", ", $orderby):''; + + $sql = "UPDATE ".$table." SET ".implode(', ', $valstr); + + $sql .= ($where != '' AND count($where) >=1) ? " WHERE ".implode(" ", $where) : ''; + + $sql .= $orderby.$limit; + + return $sql; + } + + + // -------------------------------------------------------------------- + + /** + * Truncate statement + * + * Generates a platform-specific truncate string from the supplied data + * If the database does not support the truncate() command + * This function maps to "DELETE FROM table" + * + * @access public + * @param string the table name + * @return string + */ + function _truncate($table) + { + return $this->_delete($table); + } + + // -------------------------------------------------------------------- + + /** + * Delete statement + * + * Generates a platform-specific delete string from the supplied data + * + * @access public + * @param string the table name + * @param array the where clause + * @param string the limit clause + * @return string + */ + function _delete($table, $where = array(), $like = array(), $limit = FALSE) + { + $conditions = ''; + + if (count($where) > 0 OR count($like) > 0) + { + $conditions = "\nWHERE "; + $conditions .= implode("\n", $this->ar_where); + + if (count($where) > 0 && count($like) > 0) + { + $conditions .= " AND "; + } + $conditions .= implode("\n", $like); + } + + $limit = ( ! $limit) ? '' : ' LIMIT '.$limit; + + return "DELETE FROM ".$table.$conditions.$limit; + } + + // -------------------------------------------------------------------- + + /** + * Limit string + * + * Generates a platform-specific LIMIT clause + * + * @access public + * @param string the sql query string + * @param integer the number of rows to limit the query to + * @param integer the offset value + * @return string + */ + function _limit($sql, $limit, $offset) + { + if(strpos($this->hostname, 'cubrid') !== FALSE || strpos($this->hostname, 'sqlite') !== FALSE) + { + if ($offset == 0) + { + $offset = ''; + } + else + { + $offset .= ", "; + } + + return $sql."LIMIT ".$offset.$limit; + } + else + { + $sql .= "LIMIT ".$limit; + + if ($offset > 0) + { + $sql .= " OFFSET ".$offset; + } + + return $sql; + } + } + + // -------------------------------------------------------------------- + + /** + * Close DB Connection + * + * @access public + * @param resource + * @return void + */ + function _close($conn_id) + { + $this->conn_id = null; + } + + +} + + + +/* End of file pdo_driver.php */ +/* Location: ./system/database/drivers/pdo/pdo_driver.php */
\ No newline at end of file diff --git a/system/database/drivers/pdo/pdo_forge.php b/system/database/drivers/pdo/pdo_forge.php new file mode 100644 index 000000000..5516873c0 --- /dev/null +++ b/system/database/drivers/pdo/pdo_forge.php @@ -0,0 +1,266 @@ +<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed'); +/** + * CodeIgniter + * + * An open source application development framework for PHP 5.1.6 or newer + * + * @package CodeIgniter + * @author ExpressionEngine Dev Team + * @copyright Copyright (c) 2008 - 2011, EllisLab, Inc. + * @license http://codeigniter.com/user_guide/license.html + * @link http://codeigniter.com + * @since Version 2.1.0 + * @filesource + */ + +// ------------------------------------------------------------------------ + +/** + * PDO Forge Class + * + * @category Database + * @author ExpressionEngine Dev Team + * @link http://codeigniter.com/database/ + */ +class CI_DB_pdo_forge extends CI_DB_forge { + + /** + * Create database + * + * @access private + * @param string the database name + * @return bool + */ + function _create_database() + { + // PDO has no "create database" command since it's + // designed to connect to an existing database + if ($this->db->db_debug) + { + return $this->db->display_error('db_unsuported_feature'); + } + return FALSE; + } + + // -------------------------------------------------------------------- + + /** + * Drop database + * + * @access private + * @param string the database name + * @return bool + */ + function _drop_database($name) + { + // PDO has no "drop database" command since it's + // designed to connect to an existing database + if ($this->db->db_debug) + { + return $this->db->display_error('db_unsuported_feature'); + } + return FALSE; + } + + // -------------------------------------------------------------------- + + /** + * Create Table + * + * @access private + * @param string the table name + * @param array the fields + * @param mixed primary key(s) + * @param mixed key(s) + * @param boolean should 'IF NOT EXISTS' be added to the SQL + * @return bool + */ + function _create_table($table, $fields, $primary_keys, $keys, $if_not_exists) + { + $sql = 'CREATE TABLE '; + + if ($if_not_exists === TRUE) + { + $sql .= 'IF NOT EXISTS '; + } + + $sql .= $this->db->_escape_identifiers($table)." ("; + $current_field_count = 0; + + foreach ($fields as $field=>$attributes) + { + // Numeric field names aren't allowed in databases, so if the key is + // numeric, we know it was assigned by PHP and the developer manually + // entered the field information, so we'll simply add it to the list + if (is_numeric($field)) + { + $sql .= "\n\t$attributes"; + } + else + { + $attributes = array_change_key_case($attributes, CASE_UPPER); + + $sql .= "\n\t".$this->db->_protect_identifiers($field); + + $sql .= ' '.$attributes['TYPE']; + + if (array_key_exists('CONSTRAINT', $attributes)) + { + $sql .= '('.$attributes['CONSTRAINT'].')'; + } + + if (array_key_exists('UNSIGNED', $attributes) && $attributes['UNSIGNED'] === TRUE) + { + $sql .= ' UNSIGNED'; + } + + if (array_key_exists('DEFAULT', $attributes)) + { + $sql .= ' DEFAULT \''.$attributes['DEFAULT'].'\''; + } + + if (array_key_exists('NULL', $attributes) && $attributes['NULL'] === TRUE) + { + $sql .= ' NULL'; + } + else + { + $sql .= ' NOT NULL'; + } + + if (array_key_exists('AUTO_INCREMENT', $attributes) && $attributes['AUTO_INCREMENT'] === TRUE) + { + $sql .= ' AUTO_INCREMENT'; + } + } + + // don't add a comma on the end of the last field + if (++$current_field_count < count($fields)) + { + $sql .= ','; + } + } + + if (count($primary_keys) > 0) + { + $primary_keys = $this->db->_protect_identifiers($primary_keys); + $sql .= ",\n\tPRIMARY KEY (" . implode(', ', $primary_keys) . ")"; + } + + if (is_array($keys) && count($keys) > 0) + { + foreach ($keys as $key) + { + if (is_array($key)) + { + $key = $this->db->_protect_identifiers($key); + } + else + { + $key = array($this->db->_protect_identifiers($key)); + } + + $sql .= ",\n\tFOREIGN KEY (" . implode(', ', $key) . ")"; + } + } + + $sql .= "\n)"; + + return $sql; + } + + // -------------------------------------------------------------------- + + /** + * Drop Table + * + * @access private + * @return bool + */ + function _drop_table($table) + { + // Not a supported PDO feature + if ($this->db->db_debug) + { + return $this->db->display_error('db_unsuported_feature'); + } + return FALSE; + } + + // -------------------------------------------------------------------- + + /** + * Alter table query + * + * Generates a platform-specific query so that a table can be altered + * Called by add_column(), drop_column(), and column_alter(), + * + * @access private + * @param string the ALTER type (ADD, DROP, CHANGE) + * @param string the column name + * @param string the table name + * @param string the column definition + * @param string the default value + * @param boolean should 'NOT NULL' be added + * @param string the field after which we should add the new field + * @return object + */ + function _alter_table($alter_type, $table, $column_name, $column_definition = '', $default_value = '', $null = '', $after_field = '') + { + $sql = 'ALTER TABLE '.$this->db->_protect_identifiers($table)." $alter_type ".$this->db->_protect_identifiers($column_name); + + // DROP has everything it needs now. + if ($alter_type == 'DROP') + { + return $sql; + } + + $sql .= " $column_definition"; + + if ($default_value != '') + { + $sql .= " DEFAULT \"$default_value\""; + } + + if ($null === NULL) + { + $sql .= ' NULL'; + } + else + { + $sql .= ' NOT NULL'; + } + + if ($after_field != '') + { + $sql .= ' AFTER ' . $this->db->_protect_identifiers($after_field); + } + + return $sql; + + } + + + // -------------------------------------------------------------------- + + /** + * Rename a table + * + * Generates a platform-specific query so that a table can be renamed + * + * @access private + * @param string the old table name + * @param string the new table name + * @return string + */ + function _rename_table($table_name, $new_table_name) + { + $sql = 'ALTER TABLE '.$this->db->_protect_identifiers($table_name)." RENAME TO ".$this->db->_protect_identifiers($new_table_name); + return $sql; + } + + +} + +/* End of file pdo_forge.php */ +/* Location: ./system/database/drivers/pdo/pdo_forge.php */
\ No newline at end of file diff --git a/system/database/drivers/pdo/pdo_result.php b/system/database/drivers/pdo/pdo_result.php new file mode 100644 index 000000000..e3ae0da4b --- /dev/null +++ b/system/database/drivers/pdo/pdo_result.php @@ -0,0 +1,171 @@ +<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed'); +/** + * CodeIgniter + * + * An open source application development framework for PHP 5.1.6 or newer + * + * @package CodeIgniter + * @author ExpressionEngine Dev Team + * @copyright Copyright (c) 2008 - 2011, EllisLab, Inc. + * @license http://codeigniter.com/user_guide/license.html + * @link http://codeigniter.com + * @since Version 2.1.0 + * @filesource + */ + +// ------------------------------------------------------------------------ + +/** + * PDO Result Class + * + * This class extends the parent result class: CI_DB_result + * + * @category Database + * @author ExpressionEngine Dev Team + * @link http://codeigniter.com/user_guide/database/ + */ +class CI_DB_pdo_result extends CI_DB_result { + + /** + * Number of rows in the result set + * + * @access public + * @return integer + */ + function num_rows() + { + return $this->result_id->rowCount(); + } + + // -------------------------------------------------------------------- + + /** + * Number of fields in the result set + * + * @access public + * @return integer + */ + function num_fields() + { + return $this->result_id->columnCount(); + } + + // -------------------------------------------------------------------- + + /** + * Fetch Field Names + * + * Generates an array of column names + * + * @access public + * @return array + */ + function list_fields() + { + if ($this->db->db_debug) + { + return $this->db->display_error('db_unsuported_feature'); + } + return FALSE; + } + + // -------------------------------------------------------------------- + + /** + * Field data + * + * Generates an array of objects containing field meta-data + * + * @access public + * @return array + */ + function field_data() + { + $data = array(); + + try + { + for($i = 0; $i < $this->num_fields(); $i++) + { + $data[] = $this->result_id->getColumnMeta($i); + } + + return $data; + } + catch (Exception $e) + { + if ($this->db->db_debug) + { + return $this->db->display_error('db_unsuported_feature'); + } + return FALSE; + } + } + + // -------------------------------------------------------------------- + + /** + * Free the result + * + * @return null + */ + function free_result() + { + if (is_object($this->result_id)) + { + $this->result_id = FALSE; + } + } + + // -------------------------------------------------------------------- + + /** + * Data Seek + * + * Moves the internal pointer to the desired offset. We call + * this internally before fetching results to make sure the + * result set starts at zero + * + * @access private + * @return array + */ + function _data_seek($n = 0) + { + return FALSE; + } + + // -------------------------------------------------------------------- + + /** + * Result - associative array + * + * Returns the result set as an array + * + * @access private + * @return array + */ + function _fetch_assoc() + { + return $this->result_id->fetch(PDO::FETCH_ASSOC); + } + + // -------------------------------------------------------------------- + + /** + * Result - object + * + * Returns the result set as an object + * + * @access private + * @return object + */ + function _fetch_object() + { + return $this->result_id->fetchObject(); + } + +} + + +/* End of file pdo_result.php */ +/* Location: ./system/database/drivers/pdo/pdo_result.php */
\ No newline at end of file diff --git a/system/database/drivers/pdo/pdo_utility.php b/system/database/drivers/pdo/pdo_utility.php new file mode 100644 index 000000000..50b9746de --- /dev/null +++ b/system/database/drivers/pdo/pdo_utility.php @@ -0,0 +1,103 @@ +<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed'); +/** + * CodeIgniter + * + * An open source application development framework for PHP 5.1.6 or newer + * + * @package CodeIgniter + * @author ExpressionEngine Dev Team + * @copyright Copyright (c) 2008 - 2011, EllisLab, Inc. + * @license http://codeigniter.com/user_guide/license.html + * @link http://codeigniter.com + * @since Version 2.1.0 + * @filesource + */ + +// ------------------------------------------------------------------------ + +/** + * PDO Utility Class + * + * @category Database + * @author ExpressionEngine Dev Team + * @link http://codeigniter.com/database/ + */ +class CI_DB_pdo_utility extends CI_DB_utility { + + /** + * List databases + * + * @access private + * @return bool + */ + function _list_databases() + { + // Not sure if PDO lets you list all databases... + if ($this->db->db_debug) + { + return $this->db->display_error('db_unsuported_feature'); + } + return FALSE; + } + + // -------------------------------------------------------------------- + + /** + * Optimize table query + * + * Generates a platform-specific query so that a table can be optimized + * + * @access private + * @param string the table name + * @return object + */ + function _optimize_table($table) + { + // Not a supported PDO feature + if ($this->db->db_debug) + { + return $this->db->display_error('db_unsuported_feature'); + } + return FALSE; + } + + // -------------------------------------------------------------------- + + /** + * Repair table query + * + * Generates a platform-specific query so that a table can be repaired + * + * @access private + * @param string the table name + * @return object + */ + function _repair_table($table) + { + // Not a supported PDO feature + if ($this->db->db_debug) + { + return $this->db->display_error('db_unsuported_feature'); + } + return FALSE; + } + + // -------------------------------------------------------------------- + + /** + * PDO Export + * + * @access private + * @param array Preferences + * @return mixed + */ + function _backup($params = array()) + { + // Currently unsupported + return $this->db->display_error('db_unsuported_feature'); + } + +} + +/* End of file pdo_utility.php */ +/* Location: ./system/database/drivers/pdo/pdo_utility.php */
\ No newline at end of file diff --git a/system/helpers/html_helper.php b/system/helpers/html_helper.php index b64b60650..10a288e6a 100644 --- a/system/helpers/html_helper.php +++ b/system/helpers/html_helper.php @@ -365,7 +365,7 @@ if ( ! function_exists('link_tag')) $link .= '/>'; } - + $link .= "\n"; return $link; } diff --git a/system/helpers/typography_helper.php b/system/helpers/typography_helper.php index 82e686e53..e8cb037a8 100644 --- a/system/helpers/typography_helper.php +++ b/system/helpers/typography_helper.php @@ -76,6 +76,7 @@ if ( ! function_exists('auto_typography')) * * @access public * @param string + * @param string * @return string */ if ( ! function_exists('entity_decode')) @@ -83,12 +84,6 @@ if ( ! function_exists('entity_decode')) function entity_decode($str, $charset = NULL) { global $SEC; - - if (empty($charset)) - { - $charset = config_item('charset'); - } - return $SEC->entity_decode($str, $charset); } } diff --git a/system/libraries/Email.php b/system/libraries/Email.php index c8cb8549e..ef20e1978 100644 --- a/system/libraries/Email.php +++ b/system/libraries/Email.php @@ -36,6 +36,7 @@ class CI_Email { var $smtp_pass = ""; // SMTP Password var $smtp_port = "25"; // SMTP Port var $smtp_timeout = 5; // SMTP Timeout in seconds + var $smtp_crypto = ""; // SMTP Encryption. Can be null, tls or ssl. var $wordwrap = TRUE; // TRUE/FALSE Turns word-wrap on/off var $wrapchars = "76"; // Number of characters to wrap at. var $mailtype = "text"; // text/html Defines email formatting @@ -1667,7 +1668,14 @@ class CI_Email { */ protected function _smtp_connect() { - $this->_smtp_connect = fsockopen($this->smtp_host, + $ssl = NULL; + + if ($this->smtp_crypto == 'ssl') + { + $ssl = 'ssl://'; + } + + $this->_smtp_connect = fsockopen($ssl.$this->smtp_host, $this->smtp_port, $errno, $errstr, @@ -1680,6 +1688,20 @@ class CI_Email { } $this->_set_error_message($this->_get_smtp_data()); + + if ($this->smtp_crypto == 'tls') + { + $this->_send_command('hello'); + $this->_send_command('starttls'); + $crypto = stream_socket_enable_crypto($this->_smtp_connect, TRUE, STREAM_CRYPTO_METHOD_TLS_CLIENT); + } + + if ($crypto !== TRUE) + { + $this->_set_error_message('lang:email_smtp_error', $this->_get_smtp_data()); + return FALSE; + } + return $this->_send_command('hello'); } @@ -1706,6 +1728,12 @@ class CI_Email { $resp = 250; break; + case 'starttls' : + + $this->_send_data('STARTTLS'); + + $resp = 220; + break; case 'from' : $this->_send_data('MAIL FROM:<'.$data.'>'); diff --git a/system/libraries/Sha1.php b/system/libraries/Sha1.php index 1a657572b..8e991f54a 100644 --- a/system/libraries/Sha1.php +++ b/system/libraries/Sha1.php @@ -40,7 +40,7 @@ * @subpackage Libraries * @category Encryption * @author ExpressionEngine Dev Team - * @link http://codeigniter.com/user_guide/general/encryption.html + * @link http://codeigniter.com/user_guide/libraries/encryption.html */ class CI_SHA1 { @@ -248,4 +248,4 @@ class CI_SHA1 { // END CI_SHA /* End of file Sha1.php */ -/* Location: ./system/libraries/Sha1.php */
\ No newline at end of file +/* Location: ./system/libraries/Sha1.php */ diff --git a/system/libraries/Table.php b/system/libraries/Table.php index def696776..c14da727e 100644 --- a/system/libraries/Table.php +++ b/system/libraries/Table.php @@ -24,7 +24,7 @@ * @subpackage Libraries * @category HTML Tables * @author ExpressionEngine Dev Team - * @link http://codeigniter.com/user_guide/libraries/uri.html + * @link http://codeigniter.com/user_guide/libraries/table.html */ class CI_Table { @@ -528,4 +528,4 @@ class CI_Table { /* End of file Table.php */ -/* Location: ./system/libraries/Table.php */
\ No newline at end of file +/* Location: ./system/libraries/Table.php */ diff --git a/system/libraries/Typography.php b/system/libraries/Typography.php index 734cec104..f061311b0 100644 --- a/system/libraries/Typography.php +++ b/system/libraries/Typography.php @@ -22,7 +22,7 @@ * @access private * @category Helpers * @author ExpressionEngine Dev Team - * @link http://codeigniter.com/user_guide/helpers/ + * @link http://codeigniter.com/user_guide/libraries/typography.html */ class CI_Typography { @@ -407,4 +407,4 @@ class CI_Typography { // END Typography Class /* End of file Typography.php */ -/* Location: ./system/libraries/Typography.php */
\ No newline at end of file +/* Location: ./system/libraries/Typography.php */ diff --git a/system/libraries/Unit_test.php b/system/libraries/Unit_test.php index 5bd7e801a..d9bc8ef6b 100644 --- a/system/libraries/Unit_test.php +++ b/system/libraries/Unit_test.php @@ -24,7 +24,7 @@ * @subpackage Libraries * @category UnitTesting * @author ExpressionEngine Dev Team - * @link http://codeigniter.com/user_guide/libraries/uri.html + * @link http://codeigniter.com/user_guide/libraries/unit_testing.html */ class CI_Unit_test { @@ -380,4 +380,4 @@ function is_false($test) /* End of file Unit_test.php */ -/* Location: ./system/libraries/Unit_test.php */
\ No newline at end of file +/* Location: ./system/libraries/Unit_test.php */ diff --git a/system/libraries/Upload.php b/system/libraries/Upload.php index 8f324de79..045283f96 100644 --- a/system/libraries/Upload.php +++ b/system/libraries/Upload.php @@ -198,7 +198,8 @@ class CI_Upload { // Set the uploaded data as class variables $this->file_temp = $_FILES[$field]['tmp_name']; $this->file_size = $_FILES[$field]['size']; - $this->file_type = preg_replace("/^(.+?);.*$/", "\\1", $_FILES[$field]['type']); + $this->_file_mime_type($_FILES[$field]); + $this->file_type = preg_replace("/^(.+?);.*$/", "\\1", $this->file_type); $this->file_type = strtolower(trim(stripslashes($this->file_type), '"')); $this->file_name = $this->_prep_filename($_FILES[$field]['name']); $this->file_ext = $this->get_extension($this->file_name); @@ -1008,8 +1009,69 @@ class CI_Upload { // -------------------------------------------------------------------- + /** + * File MIME type + * + * Detects the (actual) MIME type of the uploaded file, if possible. + * The input array is expected to be $_FILES[$field] + * + * @param array + * @return void + */ + protected function _file_mime_type($file) + { + // Use if the Fileinfo extension, if available (only versions above 5.3 support the FILEINFO_MIME_TYPE flag) + if (is_php('5.3') && function_exists('finfo_file')) + { + $finfo = new finfo(FILEINFO_MIME_TYPE); + if ($finfo !== FALSE) // This is possible, if there is no magic MIME database file found on the system + { + $file_type = $finfo->file($file['tmp_name']); + + /* According to the comments section of the PHP manual page, + * it is possible that this function returns an empty string + * for some files (e.g. if they don't exist in the magic MIME database) + */ + if (strlen($file_type) > 1) + { + $this->file_type = $file_type; + return; + } + } + } + + // Fall back to the deprecated mime_content_type(), if available + if (function_exists('mime_content_type')) + { + $this->file_type = @mime_content_type($file['tmp_name']); + return; + } + + /* This is an ugly hack, but UNIX-type systems provide a native way to detect the file type, + * which is still more secure than depending on the value of $_FILES[$field]['type']. + * + * Notes: + * - a 'W' in the substr() expression bellow, would mean that we're using Windows + * - many system admins would disable the exec() function due to security concerns, hence the function_exists() check + */ + if (DIRECTORY_SEPARATOR !== '\\' && function_exists('exec')) + { + $output = array(); + @exec('file --brief --mime-type ' . escapeshellarg($file['tmp_path']), $output, $return_code); + if ($return_code === 0 && strlen($output[0]) > 0) // A return status code != 0 would mean failed execution + { + $this->file_type = rtrim($output[0]); + return; + } + } + + $this->file_type = $file['type']; + } + + // -------------------------------------------------------------------- + } // END Upload Class /* End of file Upload.php */ -/* Location: ./system/libraries/Upload.php */
\ No newline at end of file +/* Location: ./system/libraries/Upload.php */ diff --git a/system/libraries/User_agent.php b/system/libraries/User_agent.php index 0b77a7d42..2cdaf509d 100644 --- a/system/libraries/User_agent.php +++ b/system/libraries/User_agent.php @@ -18,7 +18,7 @@ /** * User Agent Class * - * Identifies the platform, browser, robot, or mobile devise of the browsing agent + * Identifies the platform, browser, robot, or mobile device of the browsing agent * * @package CodeIgniter * @subpackage Libraries @@ -546,4 +546,4 @@ class CI_User_agent { /* End of file User_agent.php */ -/* Location: ./system/libraries/User_agent.php */
\ No newline at end of file +/* Location: ./system/libraries/User_agent.php */ |