From 2c6cc41c8f226c4403625c953c9e35e4a8380c76 Mon Sep 17 00:00:00 2001 From: Aleksander Machniak Date: Tue, 27 Jun 2017 17:16:56 +0200 Subject: [PATCH] Fix uninitialized string offset in rcube_utils::bin2ascii() and make sure rcube_utils::random_bytes() result has always requested length (#5788) --- CHANGELOG | 1 + program/lib/Roundcube/rcube_utils.php | 67 ++++++++++----------------- 2 files changed, 25 insertions(+), 43 deletions(-) diff --git a/CHANGELOG b/CHANGELOG index 019d96f4e..81558ad4c 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -3,6 +3,7 @@ CHANGELOG Roundcube Webmail - Password: Fix compatibility with PHP 7+ in cpanel_webmail driver (#5820) - Fix decoding non-ascii attachment names from TNEF attachments (#5646, #5799) +- Fix uninitialized string offset in rcube_utils::bin2ascii() and make sure rcube_utils::random_bytes() result has always requested length (#5788) RELEASE 1.3.0 ------------- diff --git a/program/lib/Roundcube/rcube_utils.php b/program/lib/Roundcube/rcube_utils.php index 4aaaf40f2..3c0fc1eb2 100644 --- a/program/lib/Roundcube/rcube_utils.php +++ b/program/lib/Roundcube/rcube_utils.php @@ -1138,28 +1138,33 @@ class rcube_utils */ public static function random_bytes($length, $raw = false) { + $hextab = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"; + $tabsize = strlen($hextab); + // Use PHP7 true random generator - if (function_exists('random_bytes')) { - // random_bytes() can throw an Error/TypeError/Exception in some cases - try { - $random = random_bytes($length); - } - catch (Throwable $e) {} + if ($raw && function_exists('random_bytes')) { + return random_bytes($length); } - if (!$random) { - $random = openssl_random_pseudo_bytes($length); - } + if (!$raw && function_exists('random_int')) { + $result = ''; + while ($length-- > 0) { + $result .= $hextab[random_int(0, $tabsize - 1)]; + } - if ($raw) { - return $random; + return $result; } - $random = self::bin2ascii($random); + $random = openssl_random_pseudo_bytes($length); + + if ($random === false) { + throw new Exception("Failed to get random bytes"); + } - // truncate to the specified size... - if ($length < strlen($random)) { - $random = substr($random, 0, $length); + if (!$raw) { + for ($x = 0; $x < $length; $x++) { + $random[$x] = $hextab[ord($random[$x]) % $tabsize]; + } } return $random; @@ -1170,40 +1175,16 @@ class rcube_utils * * @param string $input Binary input * - * @return string Readable output + * @return string Readable output (Base62) + * @deprecated since 1.3.1 */ public static function bin2ascii($input) { - // Above method returns "hexits". - // Based on bin_to_readable() function in ext/session/session.c. - // Note: removed ",-" characters from hextab $hextab = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"; - $nbits = 6; // can be 4, 5 or 6 - $length = strlen($input); $result = ''; - $char = 0; - $i = 0; - $have = 0; - $mask = (1 << $nbits) - 1; - - while (true) { - if ($have < $nbits) { - if ($i < $length) { - $char |= ord($input[$i++]) << $have; - $have += 8; - } - else if (!$have) { - break; - } - else { - $have = $nbits; - } - } - // consume nbits - $result .= $hextab[$char & $mask]; - $char >>= $nbits; - $have -= $nbits; + for ($x = 0; $x < strlen($input); $x++) { + $result .= $hextab[ord($input[$x]) % 62]; } return $result;