Improve byte-safety
diff --git a/system/core/Log.php b/system/core/Log.php
index 9861215..cf6c75a 100644
--- a/system/core/Log.php
+++ b/system/core/Log.php
@@ -104,6 +104,13 @@
 	 */
 	protected $_levels = array('ERROR' => 1, 'DEBUG' => 2, 'INFO' => 3, 'ALL' => 4);
 
+	/**
+	 * mbstring.func_override flag
+	 *
+	 * @var	bool
+	 */
+	protected static $func_override;
+
 	// --------------------------------------------------------------------
 
 	/**
@@ -115,6 +122,8 @@
 	{
 		$config =& get_config();
 
+		isset(self::$func_override) OR self::$func_override = (extension_loaded('mbstring') && ini_get('mbstring.func_override'));
+
 		$this->_log_path = ($config['log_path'] !== '') ? $config['log_path'] : APPPATH.'logs/';
 		$this->_file_ext = (isset($config['log_file_extension']) && $config['log_file_extension'] !== '')
 			? ltrim($config['log_file_extension'], '.') : 'php';
@@ -208,9 +217,9 @@
 
 		$message .= $this->_format_line($level, $date, $msg);
 
-		for ($written = 0, $length = strlen($message); $written < $length; $written += $result)
+		for ($written = 0, $length = self::strlen($message); $written < $length; $written += $result)
 		{
-			if (($result = fwrite($fp, substr($message, $written))) === FALSE)
+			if (($result = fwrite($fp, self::substr($message, $written))) === FALSE)
 			{
 				break;
 			}
@@ -244,4 +253,44 @@
 	{
 		return $level.' - '.$date.' --> '.$message."\n";
 	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * Byte-safe strlen()
+	 *
+	 * @param	string	$str
+	 * @return	int
+	 */
+	protected static function strlen($str)
+	{
+		return (self::$func_override)
+			? mb_strlen($str, '8bit')
+			: strlen($str);
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * Byte-safe substr()
+	 *
+	 * @param	string	$str
+	 * @param	int	$start
+	 * @param	int	$length
+	 * @return	string
+	 */
+	protected static function substr($str, $start, $length = NULL)
+	{
+		if (self::$func_override)
+		{
+			// mb_substr($str, $start, null, '8bit') returns an empty
+			// string on PHP 5.3
+			isset($length) OR $length = ($start >= 0 ? self::strlen($str) - $start : -$start);
+			return mb_substr($str, $start, $length, '8bit');
+		}
+
+		return isset($length)
+			? substr($str, $start, $length)
+			: substr($str, $start);
+	}
 }