Merge changes from develop
diff --git a/system/database/drivers/odbc/odbc_driver.php b/system/database/drivers/odbc/odbc_driver.php
index 45e91cb..6f635bd 100644
--- a/system/database/drivers/odbc/odbc_driver.php
+++ b/system/database/drivers/odbc/odbc_driver.php
@@ -222,7 +222,7 @@
 	 */
 	public function affected_rows()
 	{
-		return @odbc_num_rows($this->conn_id);
+		return @odbc_num_rows($this->result_id);
 	}
 
 	// --------------------------------------------------------------------
diff --git a/system/libraries/Session/drivers/Session_cookie.php b/system/libraries/Session/drivers/Session_cookie.php
index 5d338fc..79712ad 100644
--- a/system/libraries/Session/drivers/Session_cookie.php
+++ b/system/libraries/Session/drivers/Session_cookie.php
@@ -404,7 +404,15 @@
 			$hmac = substr($session, $len);
 			$session = substr($session, 0, $len);
 
-			if ($hmac !== hash_hmac('sha1', $session, $this->encryption_key))
+			// Time-attack-safe comparison
+			$hmac_check = hash_hmac('sha1', $session, $this->encryption_key);
+			$diff = 0;
+			for ($i = 0; $i < 40; $i++)
+			{
+				$diff |= ord($hmac[$i]) ^ ord($hmac_check[$i]);
+			}
+
+			if ($diff !== 0)
 			{
 				log_message('error', 'Session: HMAC mismatch. The session cookie data did not match what was expected.');
 				$this->sess_destroy();
diff --git a/user_guide_src/source/changelog.rst b/user_guide_src/source/changelog.rst
index 962c174..d9f77c6 100644
--- a/user_guide_src/source/changelog.rst
+++ b/user_guide_src/source/changelog.rst
@@ -522,7 +522,7 @@
 -  Fixed a bug (#177) - ``CI_Form_validation::set_value()`` didn't set the default value if POST data is NULL.
 -  Fixed a bug (#68, #414) - Oracle's escape_str() didn't properly escape LIKE wild characters.
 -  Fixed a bug (#81) - ODBC's list_fields() and field_data() methods skipped the first column due to odbc_field_*() functions' index starting at 1 instead of 0.
--  Fixed a bug (#129) - ODBC's num_rows() returned -1 in some cases, due to not all subdrivers supporting the odbc_num_rows() function.
+-  Fixed a bug (#129) - ODBC's ``num_rows()`` method returned -1 in some cases, due to not all subdrivers supporting the ``odbc_num_rows()`` function.
 -  Fixed a bug (#153) - E_NOTICE being generated by getimagesize() in the :doc:`File Uploading Library <libraries/file_uploading>`.
 -  Fixed a bug (#611) - SQLSRV's error handling methods used to issue warnings when there's no actual error.
 -  Fixed a bug (#1036) - ``is_write_type()`` method in the :doc:`Database Library <database/index>` didn't return TRUE for RENAME queries.
@@ -687,6 +687,7 @@
 -  Fixed a bug (#2729) - ``CI_Security::_validate_entities()`` used overly-intrusive ``preg_replace()`` patterns that produced false-positives.
 -  Fixed a bug (#2771) - ``CI_Security::xss_clean()`` didn't take into account HTML5 entities.
 -  Fixed a bug in the :doc:`Session Library <libraries/sessions>` 'cookie' driver where authentication was not performed for encrypted cookies.
+-  Fixed a bug (#2856) - ODBC method ``affected_rows()`` passed an incorrect value to ``odbc_num_rows()``.
 
 Version 2.1.4
 =============