Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Replace Nested Conditional with Guard Clauses #122

Merged
merged 1 commit into from
Feb 3, 2017
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
282 changes: 142 additions & 140 deletions lib/random.php
Original file line number Diff line number Diff line change
Expand Up @@ -44,171 +44,173 @@
/**
* PHP 7.0.0 and newer have these functions natively.
*/
if (PHP_VERSION_ID < 70000) {
if (!defined('RANDOM_COMPAT_READ_BUFFER')) {
define('RANDOM_COMPAT_READ_BUFFER', 8);
}
if (PHP_VERSION_ID >= 70000) {
return;
}

$RandomCompatDIR = dirname(__FILE__);
if (!defined('RANDOM_COMPAT_READ_BUFFER')) {
define('RANDOM_COMPAT_READ_BUFFER', 8);
}

require_once $RandomCompatDIR.'/byte_safe_strings.php';
require_once $RandomCompatDIR.'/cast_to_int.php';
require_once $RandomCompatDIR.'/error_polyfill.php';
$RandomCompatDIR = dirname(__FILE__);

if (!is_callable('random_bytes')) {
/**
* PHP 5.2.0 - 5.6.x way to implement random_bytes()
*
* We use conditional statements here to define the function in accordance
* to the operating environment. It's a micro-optimization.
*
* In order of preference:
* 1. Use libsodium if available.
* 2. fread() /dev/urandom if available (never on Windows)
* 3. mcrypt_create_iv($bytes, MCRYPT_DEV_URANDOM)
* 4. COM('CAPICOM.Utilities.1')->GetRandom()
*
* See RATIONALE.md for our reasoning behind this particular order
*/
if (extension_loaded('libsodium')) {
// See random_bytes_libsodium.php
if (PHP_VERSION_ID >= 50300 && is_callable('\\Sodium\\randombytes_buf')) {
require_once $RandomCompatDIR.'/random_bytes_libsodium.php';
} elseif (method_exists('Sodium', 'randombytes_buf')) {
require_once $RandomCompatDIR.'/random_bytes_libsodium_legacy.php';
}
require_once $RandomCompatDIR.'/byte_safe_strings.php';
require_once $RandomCompatDIR.'/cast_to_int.php';
require_once $RandomCompatDIR.'/error_polyfill.php';

if (!is_callable('random_bytes')) {
/**
* PHP 5.2.0 - 5.6.x way to implement random_bytes()
*
* We use conditional statements here to define the function in accordance
* to the operating environment. It's a micro-optimization.
*
* In order of preference:
* 1. Use libsodium if available.
* 2. fread() /dev/urandom if available (never on Windows)
* 3. mcrypt_create_iv($bytes, MCRYPT_DEV_URANDOM)
* 4. COM('CAPICOM.Utilities.1')->GetRandom()
*
* See RATIONALE.md for our reasoning behind this particular order
*/
if (extension_loaded('libsodium')) {
// See random_bytes_libsodium.php
if (PHP_VERSION_ID >= 50300 && is_callable('\\Sodium\\randombytes_buf')) {
require_once $RandomCompatDIR.'/random_bytes_libsodium.php';
} elseif (method_exists('Sodium', 'randombytes_buf')) {
require_once $RandomCompatDIR.'/random_bytes_libsodium_legacy.php';
}
}

/**
* Reading directly from /dev/urandom:
*/
if (DIRECTORY_SEPARATOR === '/') {
// DIRECTORY_SEPARATOR === '/' on Unix-like OSes -- this is a fast
// way to exclude Windows.
$RandomCompatUrandom = true;
$RandomCompat_basedir = ini_get('open_basedir');

if (!empty($RandomCompat_basedir)) {
$RandomCompat_open_basedir = explode(
PATH_SEPARATOR,
strtolower($RandomCompat_basedir)
);
$RandomCompatUrandom = (array() !== array_intersect(
array('/dev', '/dev/', '/dev/urandom'),
$RandomCompat_open_basedir
));
$RandomCompat_open_basedir = null;
}
/**
* Reading directly from /dev/urandom:
*/
if (DIRECTORY_SEPARATOR === '/') {
// DIRECTORY_SEPARATOR === '/' on Unix-like OSes -- this is a fast
// way to exclude Windows.
$RandomCompatUrandom = true;
$RandomCompat_basedir = ini_get('open_basedir');

if (
!is_callable('random_bytes')
&&
$RandomCompatUrandom
&&
@is_readable('/dev/urandom')
) {
// Error suppression on is_readable() in case of an open_basedir
// or safe_mode failure. All we care about is whether or not we
// can read it at this point. If the PHP environment is going to
// panic over trying to see if the file can be read in the first
// place, that is not helpful to us here.

// See random_bytes_dev_urandom.php
require_once $RandomCompatDIR.'/random_bytes_dev_urandom.php';
}
// Unset variables after use
$RandomCompat_basedir = null;
} else {
$RandomCompatUrandom = false;
if (!empty($RandomCompat_basedir)) {
$RandomCompat_open_basedir = explode(
PATH_SEPARATOR,
strtolower($RandomCompat_basedir)
);
$RandomCompatUrandom = (array() !== array_intersect(
array('/dev', '/dev/', '/dev/urandom'),
$RandomCompat_open_basedir
));
$RandomCompat_open_basedir = null;
}

/**
* mcrypt_create_iv()
*
* We only want to use mcypt_create_iv() if:
*
* - random_bytes() hasn't already been defined
* - PHP >= 5.3.7
* - the mcrypt extensions is loaded
* - One of these two conditions is true:
* - We're on Windows (DIRECTORY_SEPARATOR !== '/')
* - We're not on Windows and /dev/urandom is readabale
* (i.e. we're not in a chroot jail)
* - Special case:
* - If we're not on Windows, but the PHP version is between
* 5.6.10 and 5.6.12, we don't want to use mcrypt. It will
* hang indefinitely. This is bad.
*/
if (
!is_callable('random_bytes')
&&
PHP_VERSION_ID >= 50307
$RandomCompatUrandom
&&
extension_loaded('mcrypt')
@is_readable('/dev/urandom')
) {
// Prevent this code from hanging indefinitely on non-Windows;
// see https://bugs.php.net/bug.php?id=69833
if (
DIRECTORY_SEPARATOR !== '/' ||
(PHP_VERSION_ID <= 50609 || PHP_VERSION_ID >= 50613)
) {
// See random_bytes_mcrypt.php
require_once $RandomCompatDIR.'/random_bytes_mcrypt.php';
}
// Error suppression on is_readable() in case of an open_basedir
// or safe_mode failure. All we care about is whether or not we
// can read it at this point. If the PHP environment is going to
// panic over trying to see if the file can be read in the first
// place, that is not helpful to us here.

// See random_bytes_dev_urandom.php
require_once $RandomCompatDIR.'/random_bytes_dev_urandom.php';
}
$RandomCompatUrandom = null;
// Unset variables after use
$RandomCompat_basedir = null;
} else {
$RandomCompatUrandom = false;
}

/**
* This is a Windows-specific fallback, for when the mcrypt extension
* isn't loaded.
*/
/**
* mcrypt_create_iv()
*
* We only want to use mcypt_create_iv() if:
*
* - random_bytes() hasn't already been defined
* - PHP >= 5.3.7
* - the mcrypt extensions is loaded
* - One of these two conditions is true:
* - We're on Windows (DIRECTORY_SEPARATOR !== '/')
* - We're not on Windows and /dev/urandom is readabale
* (i.e. we're not in a chroot jail)
* - Special case:
* - If we're not on Windows, but the PHP version is between
* 5.6.10 and 5.6.12, we don't want to use mcrypt. It will
* hang indefinitely. This is bad.
*/
if (
!is_callable('random_bytes')
&&
PHP_VERSION_ID >= 50307
&&
extension_loaded('mcrypt')
) {
// Prevent this code from hanging indefinitely on non-Windows;
// see https://bugs.php.net/bug.php?id=69833
if (
!is_callable('random_bytes')
&&
extension_loaded('com_dotnet')
&&
class_exists('COM')
DIRECTORY_SEPARATOR !== '/' ||
(PHP_VERSION_ID <= 50609 || PHP_VERSION_ID >= 50613)
) {
$RandomCompat_disabled_classes = preg_split(
'#\s*,\s*#',
strtolower(ini_get('disable_classes'))
);
// See random_bytes_mcrypt.php
require_once $RandomCompatDIR.'/random_bytes_mcrypt.php';
}
}
$RandomCompatUrandom = null;

if (!in_array('com', $RandomCompat_disabled_classes)) {
try {
$RandomCompatCOMtest = new COM('CAPICOM.Utilities.1');
if (method_exists($RandomCompatCOMtest, 'GetRandom')) {
// See random_bytes_com_dotnet.php
require_once $RandomCompatDIR.'/random_bytes_com_dotnet.php';
}
} catch (com_exception $e) {
// Don't try to use it.
/**
* This is a Windows-specific fallback, for when the mcrypt extension
* isn't loaded.
*/
if (
!is_callable('random_bytes')
&&
extension_loaded('com_dotnet')
&&
class_exists('COM')
) {
$RandomCompat_disabled_classes = preg_split(
'#\s*,\s*#',
strtolower(ini_get('disable_classes'))
);

if (!in_array('com', $RandomCompat_disabled_classes)) {
try {
$RandomCompatCOMtest = new COM('CAPICOM.Utilities.1');
if (method_exists($RandomCompatCOMtest, 'GetRandom')) {
// See random_bytes_com_dotnet.php
require_once $RandomCompatDIR.'/random_bytes_com_dotnet.php';
}
} catch (com_exception $e) {
// Don't try to use it.
}
$RandomCompat_disabled_classes = null;
$RandomCompatCOMtest = null;
}
$RandomCompat_disabled_classes = null;
$RandomCompatCOMtest = null;
}

/**
* throw new Exception
*/
if (!is_callable('random_bytes')) {
/**
* throw new Exception
* We don't have any more options, so let's throw an exception right now
* and hope the developer won't let it fail silently.
*/
if (!is_callable('random_bytes')) {
/**
* We don't have any more options, so let's throw an exception right now
* and hope the developer won't let it fail silently.
*/
function random_bytes($length)
{
throw new Exception(
'There is no suitable CSPRNG installed on your system'
);
}
function random_bytes($length)
{
throw new Exception(
'There is no suitable CSPRNG installed on your system'
);
}
}
}

if (!is_callable('random_int')) {
require_once $RandomCompatDIR.'/random_int.php';
}

$RandomCompatDIR = null;
if (!is_callable('random_int')) {
require_once $RandomCompatDIR.'/random_int.php';
}

$RandomCompatDIR = null;