Fix issue #33
diff --git a/system/core/Input.php b/system/core/Input.php
index 24e21ea..8c32e45 100644
--- a/system/core/Input.php
+++ b/system/core/Input.php
@@ -693,7 +693,14 @@
 
 			foreach ($_COOKIE as $key => $val)
 			{
-				$_COOKIE[$this->_clean_input_keys($key)] = $this->_clean_input_data($val);
+				if (($cookie_key = $this->_clean_input_keys($key)) !== FALSE)
+				{
+					$_COOKIE[$cookie_key] = $this->_clean_input_data($val);
+				}
+				else
+				{
+					unset($_COOKIE[$key]);
+				}
 			}
 		}
 
@@ -706,7 +713,7 @@
 			$this->security->csrf_verify();
 		}
 
-		log_message('debug', 'Global POST and COOKIE data sanitized');
+		log_message('debug', 'Global POST, GET and COOKIE data sanitized');
 	}
 
 	// --------------------------------------------------------------------
@@ -776,15 +783,25 @@
 	 * only named with alpha-numeric text and a few other items.
 	 *
 	 * @param	string	$str	Input string
-	 * @return	string
+	 * @param	string	$fatal	Whether to terminate script exection
+	 *				or to return FALSE if an invalid
+	 *				key is encountered
+	 * @return	string|bool
 	 */
-	protected function _clean_input_keys($str)
+	protected function _clean_input_keys($str, $fatal = TRUE)
 	{
 		if ( ! preg_match('/^[a-z0-9:_\/|-]+$/i', $str))
 		{
-			set_status_header(503);
-			echo 'Disallowed Key Characters.';
-			exit(EXIT_USER_INPUT);
+			if ($fatal === TRUE)
+			{
+				return FALSE;
+			}
+			else
+			{
+				set_status_header(503);
+				echo 'Disallowed Key Characters.';
+				exit(EXIT_USER_INPUT);
+			}
 		}
 
 		// Clean UTF-8 if supported
diff --git a/user_guide_src/source/changelog.rst b/user_guide_src/source/changelog.rst
index d804cc5..a66fb26 100644
--- a/user_guide_src/source/changelog.rst
+++ b/user_guide_src/source/changelog.rst
@@ -392,6 +392,7 @@
       -  Changed methods ``get()``, ``post()``, ``get_post()``, ``cookie()``, ``server()``, ``user_agent()`` to return NULL instead of FALSE when no value is found.
       -  Added method ``post_get()`` and changed ``get_post()`` to search in GET data first. Both methods' names now properly match their GET/POST data search priorities.
       -  Changed method ``_fetch_from_array()`` to parse array notation in field name.
+      -  Added an option for ``_clean_input_keys()`` to return FALSE instead of terminating the whole script.
 
    -  :doc:`Common functions <general/common_functions>` changes include:
 
@@ -614,6 +615,7 @@
 -  Fixed a bug (#2590) - :php:func:`log_message()` didn't actually cache the ``CI_Log`` class instance.
 -  Fixed a bug (#2609) - :php:func:`get_config()` optional argument was only effective on first function call. Also, it can now add items, in addition to updating existing items.
 -  Fixed a bug in the 'postgre' :doc:`database <database/index>` driver where the connection ID wasn't passed to ``pg_escape_string()``.
+-  Fixed a bug (#33) - Script execution was terminated when an invalid cookie key was encountered.
 
 Version 2.1.4
 =============