From eea2ff56657dc5f690523cfcd372b760569ef649 Mon Sep 17 00:00:00 2001
From: Andrey Andreev <narf@bofh.bg>
Date: Thu, 19 Jan 2012 13:21:53 +0200
Subject: Fix issue #154

---
 system/libraries/Session.php | 118 ++++++++++++++++++-------------------------
 1 file changed, 50 insertions(+), 68 deletions(-)

(limited to 'system')

diff --git a/system/libraries/Session.php b/system/libraries/Session.php
index 04103a4d9..c4f97e965 100644
--- a/system/libraries/Session.php
+++ b/system/libraries/Session.php
@@ -9,7 +9,7 @@
  * Licensed under the Open Software License version 3.0
  *
  * This source file is subject to the Open Software License (OSL 3.0) that is
- * bundled with this package in the files license.txt / license.rst.  It is
+ * bundled with this package in the files license.txt / license.rst. It is
  * also available through the world wide web at this URL:
  * http://opensource.org/licenses/OSL-3.0
  * If you did not receive a copy of the license and are unable to obtain it
@@ -67,7 +67,7 @@ class CI_Session {
 	 */
 	public function __construct($params = array())
 	{
-		log_message('debug', "Session Class Initialized");
+		log_message('debug', 'Session Class Initialized');
 
 		// Set the super object to a local variable for use throughout the class
 		$this->CI =& get_instance();
@@ -93,14 +93,14 @@ class CI_Session {
 			$this->CI->load->library('encrypt');
 		}
 
-		// Are we using a database?  If so, load it
+		// Are we using a database? If so, load it
 		if ($this->sess_use_database === TRUE AND $this->sess_table_name != '')
 		{
 			$this->CI->load->database();
 		}
 
-		// Set the "now" time.  Can either be GMT or server time, based on the
-		// config prefs.  We use this to set the "last activity" time
+		// Set the "now" time. Can either be GMT or server time, based on the
+		// config prefs. We use this to set the "last activity" time
 		$this->now = $this->_get_time();
 
 		// Set the session length. If the session expiration is
@@ -114,7 +114,7 @@ class CI_Session {
 		$this->sess_cookie_name = $this->cookie_prefix.$this->sess_cookie_name;
 
 		// Run the Session routine. If a session doesn't exist we'll
-		// create a new one.  If it does, we'll update it.
+		// create a new one. If it does, we'll update it.
 		if ( ! $this->sess_read())
 		{
 			$this->sess_create();
@@ -133,7 +133,7 @@ class CI_Session {
 		// Delete expired sessions if necessary
 		$this->_sess_gc();
 
-		log_message('debug', "Session routines successfully run");
+		log_message('debug', 'Session routines successfully run');
 	}
 
 	// --------------------------------------------------------------------
@@ -166,7 +166,7 @@ class CI_Session {
 			$hash	 = substr($session, strlen($session)-32); // get last 32 chars
 			$session = substr($session, 0, strlen($session)-32);
 
-			// Does the md5 hash match?  This is to prevent manipulation of session data in userspace
+			// Does the md5 hash match? This is to prevent manipulation of session data in userspace
 			if ($hash !==  md5($session.$this->encryption_key))
 			{
 				log_message('error', 'The session cookie data did not match what was expected. This could be a possible hacking attempt.');
@@ -179,28 +179,11 @@ class CI_Session {
 		$session = $this->_unserialize($session);
 
 		// Is the session data we unserialized an array with the correct format?
-		if ( ! is_array($session) OR ! isset($session['session_id']) OR ! isset($session['ip_address']) OR ! isset($session['user_agent']) OR ! isset($session['last_activity']))
-		{
-			$this->sess_destroy();
-			return FALSE;
-		}
-
-		// Is the session current?
-		if (($session['last_activity'] + $this->sess_expiration) < $this->now)
-		{
-			$this->sess_destroy();
-			return FALSE;
-		}
-
-		// Does the IP Match?
-		if ($this->sess_match_ip == TRUE AND $session['ip_address'] !== $this->CI->input->ip_address())
-		{
-			$this->sess_destroy();
-			return FALSE;
-		}
-
-		// Does the User Agent Match?
-		if ($this->sess_match_useragent == TRUE AND trim($session['user_agent']) !== trim(substr($this->CI->input->user_agent(), 0, 120)))
+		if ( ! is_array($session) OR ! isset($session['session_id'], $session['ip_address'], $session['user_agent'], $session['last_activity'])
+			OR ($session['last_activity'] + $this->sess_expiration) < $this->now // Is the session current?
+			OR ($this->sess_match_ip == TRUE && $session['ip_address'] !== $this->CI->input->ip_address()) // Does the IP match?
+			OR ($this->sess_match_useragent == TRUE && trim($session['user_agent']) !== trim(substr($this->CI->input->user_agent(), 0, 120))) // Does the User Agent Match?
+			)
 		{
 			$this->sess_destroy();
 			return FALSE;
@@ -223,7 +206,7 @@ class CI_Session {
 
 			$query = $this->CI->db->get($this->sess_table_name);
 
-			// No result?  Kill it!
+			// No result? Kill it!
 			if ($query->num_rows() === 0)
 			{
 				$this->sess_destroy();
@@ -282,7 +265,7 @@ class CI_Session {
 			$cookie_userdata[$val] = $this->userdata[$val];
 		}
 
-		// Did we find any custom data?  If not, we turn the empty array into a string
+		// Did we find any custom data? If not, we turn the empty array into a string
 		// since there's no reason to serialize and store an empty array in the DB
 		if (count($custom_userdata) === 0)
 		{
@@ -298,7 +281,7 @@ class CI_Session {
 		$this->CI->db->where('session_id', $this->userdata['session_id']);
 		$this->CI->db->update($this->sess_table_name, array('last_activity' => $this->userdata['last_activity'], 'user_data' => $custom_userdata));
 
-		// Write the cookie.  Notice that we manually pass the cookie data array to the
+		// Write the cookie. Notice that we manually pass the cookie data array to the
 		// _set_cookie() function. Normally that function will store $this->userdata, but
 		// in this case that array contains custom data, which we do not want in the cookie.
 		$this->_set_cookie($cookie_userdata);
@@ -324,13 +307,12 @@ class CI_Session {
 		$sessid .= $this->CI->input->ip_address();
 
 		$this->userdata = array(
-							'session_id'	=> md5(uniqid($sessid, TRUE)),
-							'ip_address'	=> $this->CI->input->ip_address(),
-							'user_agent'	=> substr($this->CI->input->user_agent(), 0, 120),
-							'last_activity'	=> $this->now,
-							'user_data'		=> ''
-							);
-
+					'session_id'	=> md5(uniqid($sessid, TRUE)),
+					'ip_address'	=> $this->CI->input->ip_address(),
+					'user_agent'	=> substr($this->CI->input->user_agent(), 0, 120),
+					'last_activity'	=> $this->now,
+					'user_data'	=> ''
+				);
 
 		// Save the data to the DB if needed
 		if ($this->sess_use_database === TRUE)
@@ -352,7 +334,8 @@ class CI_Session {
 	public function sess_update()
 	{
 		// We only update the session every five minutes by default
-		if (($this->userdata['last_activity'] + $this->sess_time_to_update) >= $this->now)
+		if (($this->userdata['last_activity'] + $this->sess_time_to_update) >= $this->now
+			OR $this->CI->input->is_ajax_request()) // Changing the session ID during an AJAX call causes problems
 		{
 			return;
 		}
@@ -405,7 +388,7 @@ class CI_Session {
 	public function sess_destroy()
 	{
 		// Kill the session DB row
-		if ($this->sess_use_database === TRUE AND isset($this->userdata['session_id']))
+		if ($this->sess_use_database === TRUE && isset($this->userdata['session_id']))
 		{
 			$this->CI->db->where('session_id', $this->userdata['session_id']);
 			$this->CI->db->delete($this->sess_table_name);
@@ -413,13 +396,13 @@ class CI_Session {
 
 		// Kill the cookie
 		setcookie(
-					$this->sess_cookie_name,
-					addslashes(serialize(array())),
-					($this->now - 31500000),
-					$this->cookie_path,
-					$this->cookie_domain,
-					0
-				);
+				$this->sess_cookie_name,
+				addslashes(serialize(array())),
+				($this->now - 31500000),
+				$this->cookie_path,
+				$this->cookie_domain,
+				0
+			);
 	}
 
 	// --------------------------------------------------------------------
@@ -535,7 +518,7 @@ class CI_Session {
 	 */
 	public function keep_flashdata($key)
 	{
-		// 'old' flashdata gets removed.  Here we mark all
+		// 'old' flashdata gets removed. Here we mark all
 		// flashdata as 'new' to preserve it from _flashdata_sweep()
 		// Note the function will return FALSE if the $key
 		// provided cannot be found
@@ -586,7 +569,6 @@ class CI_Session {
 	 *
 	 * @return	void
 	 */
-
 	protected function _flashdata_sweep()
 	{
 		$userdata = $this->all_userdata();
@@ -609,13 +591,9 @@ class CI_Session {
 	 */
 	protected function _get_time()
 	{
-		if (strtolower($this->time_reference) === 'gmt')
-		{
-			$now = time();
-			return mktime(gmdate('H', $now), gmdate('i', $now), gmdate('s', $now), gmdate('m', $now), gmdate('d', $now), gmdate('Y', $now));
-		}
-
-		return time();
+		return (strtolower($this->time_reference) === 'gmt')
+			? mktime(gmdate('H'), gmdate('i'), gmdate('s'), gmdate('m'), gmdate('d'), gmdate('Y'))
+			: time();
 	}
 
 	// --------------------------------------------------------------------
@@ -649,13 +627,13 @@ class CI_Session {
 
 		// Set the cookie
 		setcookie(
-					$this->sess_cookie_name,
-					$cookie_data,
-					$expire,
-					$this->cookie_path,
-					$this->cookie_domain,
-					$this->cookie_secure
-				);
+				$this->sess_cookie_name,
+				$cookie_data,
+				$expire,
+				$this->cookie_path,
+				$this->cookie_domain,
+				$this->cookie_secure
+			);
 	}
 
 	// --------------------------------------------------------------------
@@ -687,8 +665,11 @@ class CI_Session {
 	 *
 	 * This function converts any slashes found into a temporary marker
 	 *
+	 * @param	string
+	 * @param	string
+	 * @return	void
 	 */
-	function _escape_slashes(&$val, $key)
+	protected function _escape_slashes(&$val, $key)
 	{
 		if (is_string($val))
 		{
@@ -725,6 +706,9 @@ class CI_Session {
 	 *
 	 * This function converts any slash markers back into actual slashes
 	 *
+	 * @param	string
+	 * @param	string
+	 * @return	void
 	 */
 	protected function _unescape_slashes(&$val, $key)
 	{
@@ -763,9 +747,7 @@ class CI_Session {
 		}
 	}
 
-
 }
-// END Session Class
 
 /* End of file Session.php */
 /* Location: ./system/libraries/Session.php */
-- 
cgit v1.2.3-24-g4f1b


From 9c622f373046a0a626799f4ed5a0f944628b0b43 Mon Sep 17 00:00:00 2001
From: Andrey Andreev <narf@bofh.bg>
Date: Thu, 19 Jan 2012 14:12:54 +0200
Subject: Still update the session on AJAX calls, just don't regenerate the
 session ID

---
 system/libraries/Session.php | 36 ++++++++++++++++++++++++++++++------
 1 file changed, 30 insertions(+), 6 deletions(-)

(limited to 'system')

diff --git a/system/libraries/Session.php b/system/libraries/Session.php
index c4f97e965..784bb62b2 100644
--- a/system/libraries/Session.php
+++ b/system/libraries/Session.php
@@ -334,12 +334,40 @@ class CI_Session {
 	public function sess_update()
 	{
 		// We only update the session every five minutes by default
-		if (($this->userdata['last_activity'] + $this->sess_time_to_update) >= $this->now
-			OR $this->CI->input->is_ajax_request()) // Changing the session ID during an AJAX call causes problems
+		if (($this->userdata['last_activity'] + $this->sess_time_to_update) >= $this->now)
 		{
 			return;
 		}
 
+		// _set_cookie() will handle this for us if we aren't using database sessions
+		// by pushing all userdata to the cookie.
+		$cookie_data = NULL;
+
+		/* Changing the session ID during an AJAX call causes problems,
+		 * so we'll only update our last_activity
+		 */
+		if ($this->CI->input->is_ajax_request())
+		{
+			$this->userdata['last_activity'] = $this->now;
+
+			// Update the session ID and last_activity field in the DB if needed
+			if ($this->sess_use_database === TRUE)
+			{
+				// set cookie explicitly to only have our session data
+				$cookie_data = array();
+				foreach (array('session_id','ip_address','user_agent','last_activity') as $val)
+				{
+					$cookie_data[$val] = $this->userdata[$val];
+				}
+
+				$this->CI->db->query($this->CI->db->update_string($this->sess_table_name,
+											array('last_activity' => $this->userdata['last_activity']),
+											array('session_id' => $this->userdata['session_id'])));
+			}
+
+			return $this->_set_cookie($cookie_data);
+		}
+
 		// Save the old session id so we know which record to
 		// update in the database if we need it
 		$old_sessid = $this->userdata['session_id'];
@@ -357,10 +385,6 @@ class CI_Session {
 		$this->userdata['session_id'] = $new_sessid = md5(uniqid($new_sessid, TRUE));
 		$this->userdata['last_activity'] = $this->now;
 
-		// _set_cookie() will handle this for us if we aren't using database sessions
-		// by pushing all userdata to the cookie.
-		$cookie_data = NULL;
-
 		// Update the session ID and last_activity field in the DB if needed
 		if ($this->sess_use_database === TRUE)
 		{
-- 
cgit v1.2.3-24-g4f1b


From 7e087f5e07c4630092a1d6ecdd103dc15f48e573 Mon Sep 17 00:00:00 2001
From: Andrey Andreev <narf@bofh.bg>
Date: Fri, 20 Jan 2012 11:46:27 +0200
Subject: Revert if() merge, for readability

---
 system/libraries/Session.php | 27 ++++++++++++++++++++++-----
 1 file changed, 22 insertions(+), 5 deletions(-)

(limited to 'system')

diff --git a/system/libraries/Session.php b/system/libraries/Session.php
index 784bb62b2..b8c623584 100644
--- a/system/libraries/Session.php
+++ b/system/libraries/Session.php
@@ -179,11 +179,28 @@ class CI_Session {
 		$session = $this->_unserialize($session);
 
 		// Is the session data we unserialized an array with the correct format?
-		if ( ! is_array($session) OR ! isset($session['session_id'], $session['ip_address'], $session['user_agent'], $session['last_activity'])
-			OR ($session['last_activity'] + $this->sess_expiration) < $this->now // Is the session current?
-			OR ($this->sess_match_ip == TRUE && $session['ip_address'] !== $this->CI->input->ip_address()) // Does the IP match?
-			OR ($this->sess_match_useragent == TRUE && trim($session['user_agent']) !== trim(substr($this->CI->input->user_agent(), 0, 120))) // Does the User Agent Match?
-			)
+		if ( ! is_array($session) OR ! isset($session['session_id'], $session['ip_address'], $session['user_agent'], $session['last_activity']))
+		{
+			$this->sess_destroy();
+			return FALSE;
+		}
+
+		// Is the session current?
+		if (($session['last_activity'] + $this->sess_expiration) < $this->now)
+		{
+			$this->sess_destroy();
+			return FALSE;
+		}
+
+		// Does the IP match?
+		if ($this->sess_match_ip == TRUE && $session['ip_address'] !== $this->CI->input->ip_address())
+		{
+			$this->sess_destroy();
+			return FALSE;
+		}
+
+		// Does the User Agent Match?
+		if ($this->sess_match_useragent == TRUE && trim($session['user_agent']) !== trim(substr($this->CI->input->user_agent(), 0, 120)))
 		{
 			$this->sess_destroy();
 			return FALSE;
-- 
cgit v1.2.3-24-g4f1b


From f88681873b8b556d58f22a3e99c916eadbcb6171 Mon Sep 17 00:00:00 2001
From: Andrey Andreev <narf@bofh.bg>
Date: Fri, 20 Jan 2012 13:14:53 +0200
Subject: Replace AND with &&

---
 system/libraries/Session.php | 6 ++----
 1 file changed, 2 insertions(+), 4 deletions(-)

(limited to 'system')

diff --git a/system/libraries/Session.php b/system/libraries/Session.php
index b8c623584..c331d99f7 100644
--- a/system/libraries/Session.php
+++ b/system/libraries/Session.php
@@ -25,8 +25,6 @@
  * @filesource
  */
 
-// ------------------------------------------------------------------------
-
 /**
  * Session Class
  *
@@ -94,7 +92,7 @@ class CI_Session {
 		}
 
 		// Are we using a database? If so, load it
-		if ($this->sess_use_database === TRUE AND $this->sess_table_name != '')
+		if ($this->sess_use_database === TRUE && $this->sess_table_name != '')
 		{
 			$this->CI->load->database();
 		}
@@ -232,7 +230,7 @@ class CI_Session {
 
 			// Is there custom data?  If so, add it to the main session array
 			$row = $query->row();
-			if (isset($row->user_data) AND $row->user_data != '')
+			if (isset($row->user_data) && $row->user_data != '')
 			{
 				$custom_data = $this->_unserialize($row->user_data);
 
-- 
cgit v1.2.3-24-g4f1b


From f863a02e314813753662106459e93f6675b1566e Mon Sep 17 00:00:00 2001
From: Andrey Andreev <narf@bofh.bg>
Date: Tue, 24 Jan 2012 15:31:54 +0200
Subject: Revert a space in the license agreement :)

---
 system/libraries/Session.php | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

(limited to 'system')

diff --git a/system/libraries/Session.php b/system/libraries/Session.php
index c331d99f7..66b39a6a2 100644
--- a/system/libraries/Session.php
+++ b/system/libraries/Session.php
@@ -9,7 +9,7 @@
  * Licensed under the Open Software License version 3.0
  *
  * This source file is subject to the Open Software License (OSL 3.0) that is
- * bundled with this package in the files license.txt / license.rst. It is
+ * bundled with this package in the files license.txt / license.rst.  It is
  * also available through the world wide web at this URL:
  * http://opensource.org/licenses/OSL-3.0
  * If you did not receive a copy of the license and are unable to obtain it
-- 
cgit v1.2.3-24-g4f1b