Merge remote-tracking branch 'origin/composer' into devel

Conflicts:
	inc/SP/Core/Init.php
This commit is contained in:
nuxsmin
2017-09-20 00:39:18 +02:00
505 changed files with 13982 additions and 8748 deletions

1
.gitignore vendored
View File

@@ -50,5 +50,6 @@ config/*
res/
tools/
tmp/
inc/Plugins/*
!.blank

View File

@@ -29,7 +29,7 @@ use SP\Http\Request;
use SP\Http\Response;
use SP\Util\Checks;
define('APP_ROOT', '..');
define('APP_ROOT', dirname(__DIR__));
require_once APP_ROOT . DIRECTORY_SEPARATOR . 'inc' . DIRECTORY_SEPARATOR . 'Base.php';

View File

@@ -28,7 +28,7 @@ use SP\Http\Request;
use SP\Core\SessionUtil;
use SP\Http\Response;
define('APP_ROOT', '..');
define('APP_ROOT', dirname(__DIR__));
require_once APP_ROOT . DIRECTORY_SEPARATOR . 'inc' . DIRECTORY_SEPARATOR . 'Base.php';

View File

@@ -25,7 +25,7 @@
use SP\Controller\ChecksController;
use SP\Http\Request;
define('APP_ROOT', '..');
define('APP_ROOT', dirname(__DIR__));
require_once APP_ROOT . DIRECTORY_SEPARATOR . 'inc' . DIRECTORY_SEPARATOR . 'Base.php';

View File

@@ -25,7 +25,7 @@
use SP\Controller\MainController;
use SP\Http\Request;
define('APP_ROOT', '..');
define('APP_ROOT', dirname(__DIR__));
require_once APP_ROOT . DIRECTORY_SEPARATOR . 'inc' . DIRECTORY_SEPARATOR . 'Base.php';

View File

@@ -25,7 +25,7 @@
use SP\Controller\ConfigActionController;
use SP\Http\Request;
define('APP_ROOT', '..');
define('APP_ROOT', dirname(__DIR__));
require_once APP_ROOT . DIRECTORY_SEPARATOR . 'inc' . DIRECTORY_SEPARATOR . 'Base.php';

View File

@@ -25,7 +25,7 @@
use SP\Controller\LoginController;
use SP\Http\Request;
define('APP_ROOT', '..');
define('APP_ROOT', dirname(__DIR__));
require_once APP_ROOT . DIRECTORY_SEPARATOR . 'inc' . DIRECTORY_SEPARATOR . 'Base.php';

View File

@@ -26,7 +26,7 @@ use SP\Controller\EventlogController;
use SP\Core\Init;
use SP\Http\Request;
define('APP_ROOT', '..');
define('APP_ROOT', dirname(__DIR__));
require_once APP_ROOT . DIRECTORY_SEPARATOR . 'inc' . DIRECTORY_SEPARATOR . 'Base.php';

View File

@@ -38,7 +38,7 @@ use SP\Mgmt\Files\FileUtil;
use SP\Util\Checks;
use SP\Util\Util;
define('APP_ROOT', '..');
define('APP_ROOT', dirname(__DIR__));
require_once APP_ROOT . DIRECTORY_SEPARATOR . 'inc' . DIRECTORY_SEPARATOR . 'Base.php';

View File

@@ -39,7 +39,7 @@ use SP\Http\Request;
use SP\Http\Response;
use SP\Util\Util;
define('APP_ROOT', '..');
define('APP_ROOT', dirname(__DIR__));
require_once APP_ROOT . DIRECTORY_SEPARATOR . 'inc' . DIRECTORY_SEPARATOR . 'Base.php';

View File

@@ -33,7 +33,7 @@ use SP\Http\Request;
use SP\Http\Response;
use SP\Util\Checks;
define('APP_ROOT', '..');
define('APP_ROOT', dirname(__DIR__));
require APP_ROOT . DIRECTORY_SEPARATOR . 'inc' . DIRECTORY_SEPARATOR . 'Base.php';
require APP_ROOT . DIRECTORY_SEPARATOR . 'js' . DIRECTORY_SEPARATOR . 'strings.js.php';

View File

@@ -25,7 +25,7 @@
use SP\Controller\ItemsController;
use SP\Http\Request;
define('APP_ROOT', '..');
define('APP_ROOT', dirname(__DIR__));
require_once APP_ROOT . DIRECTORY_SEPARATOR . 'inc' . DIRECTORY_SEPARATOR . 'Base.php';

View File

@@ -29,7 +29,7 @@ use SP\Http\JsonResponse;
use SP\Http\Request;
use SP\Util\Json;
define('APP_ROOT', '..');
define('APP_ROOT', dirname(__DIR__));
define('IS_INSTALLER', 1);
require_once APP_ROOT . DIRECTORY_SEPARATOR . 'inc' . DIRECTORY_SEPARATOR . 'Base.php';

View File

@@ -25,7 +25,7 @@
use SP\Controller\ItemActionController;
use SP\Http\Request;
define('APP_ROOT', '..');
define('APP_ROOT', dirname(__DIR__));
require_once APP_ROOT . DIRECTORY_SEPARATOR . 'inc' . DIRECTORY_SEPARATOR . 'Base.php';

View File

@@ -22,11 +22,11 @@
* along with sysPass. If not, see <http://www.gnu.org/licenses/>.
*/
define('APP_ROOT', '..');
use SP\Controller\ItemSearchController;
use SP\Http\Request;
define('APP_ROOT', dirname(__DIR__));
require_once APP_ROOT . DIRECTORY_SEPARATOR . 'inc' . DIRECTORY_SEPARATOR . 'Base.php';
Request::checkReferer('GET');

View File

@@ -25,7 +25,7 @@
use SP\Controller\ItemShowController;
use SP\Http\Request;
define('APP_ROOT', '..');
define('APP_ROOT', dirname(__DIR__));
require_once APP_ROOT . DIRECTORY_SEPARATOR . 'inc' . DIRECTORY_SEPARATOR . 'Base.php';

View File

@@ -22,11 +22,11 @@
* along with sysPass. If not, see <http://www.gnu.org/licenses/>.
*/
define('APP_ROOT', '..');
use SP\Controller\NoticesSearchController;
use SP\Http\Request;
define('APP_ROOT', dirname(__DIR__));
require_once APP_ROOT . DIRECTORY_SEPARATOR . 'inc' . DIRECTORY_SEPARATOR . 'Base.php';
Request::checkReferer('GET');

View File

@@ -22,11 +22,11 @@
* along with sysPass. If not, see <http://www.gnu.org/licenses/>.
*/
define('APP_ROOT', '..');
use SP\Controller\NoticeShowController;
use SP\Http\Request;
define('APP_ROOT', dirname(__DIR__));
require_once APP_ROOT . DIRECTORY_SEPARATOR . 'inc' . DIRECTORY_SEPARATOR . 'Base.php';
Request::checkReferer('GET');

View File

@@ -34,7 +34,7 @@ use SP\Mgmt\Users\UserPass;
use SP\Mgmt\Users\UserPassRecover;
use SP\Util\Json;
define('APP_ROOT', '..');
define('APP_ROOT', dirname(__DIR__));
require_once APP_ROOT . DIRECTORY_SEPARATOR . 'inc' . DIRECTORY_SEPARATOR . 'Base.php';

View File

@@ -25,7 +25,7 @@
use SP\Controller\TaskController;
use SP\Http\Request;
define('APP_ROOT', '..');
define('APP_ROOT', dirname(__DIR__));
require_once APP_ROOT . DIRECTORY_SEPARATOR . 'inc' . DIRECTORY_SEPARATOR . 'Base.php';

View File

@@ -25,7 +25,7 @@
use SP\Controller\MainActionController;
use SP\Http\Request;
define('APP_ROOT', '..');
define('APP_ROOT', dirname(__DIR__));
define('IS_UPGRADE', 1);
require_once APP_ROOT . DIRECTORY_SEPARATOR . 'inc' . DIRECTORY_SEPARATOR . 'Base.php';

View File

@@ -38,7 +38,7 @@ use SP\Util\Checks;
use SP\Util\Json;
use SP\Util\Util;
define('APP_ROOT', '..');
define('APP_ROOT', dirname(__DIR__));
require_once APP_ROOT . DIRECTORY_SEPARATOR . 'inc' . DIRECTORY_SEPARATOR . 'Base.php';

View File

@@ -25,7 +25,7 @@
use SP\Controller\WikiController;
use SP\Http\Request;
define('APP_ROOT', '..');
define('APP_ROOT', dirname(__DIR__));
require_once APP_ROOT . DIRECTORY_SEPARATOR . 'inc' . DIRECTORY_SEPARATOR . 'Base.php';

35
composer.json Normal file
View File

@@ -0,0 +1,35 @@
{
"name": "nuxsmin/syspass",
"description": "PHP web based Password Manager for business and personal use.",
"homepage": "https://syspass.org",
"minimum-stability": "stable",
"license": "GPL-3.0",
"authors": [
{
"name": "Rubén Domínguez",
"email": "nuxsmin@syspass.org",
"role": "Author/Developer",
"homepage": "https://syspass.org/"
}
],
"support": {
"issues": "https://github.com/nuxsmin/sysPass/issues",
"source": "https://github.com/nuxsmin/sysPass",
"docs": "https://doc.syspass.org"
},
"require": {
"php": "5.6.* || 7.0.*",
"defuse/php-encryption": "~2.1",
"phpmailer/phpmailer": "~6.0",
"ademarre/binary-to-text-php": "dev-master",
"phpseclib/phpseclib": "~2.0"
},
"autoload": {
"psr-4": {
"SP\\": "inc/"
}
},
"config": {
"classmap-authoritative": true
}
}

335
composer.lock generated Normal file
View File

@@ -0,0 +1,335 @@
{
"_readme": [
"This file locks the dependencies of your project to a known state",
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file",
"This file is @generated automatically"
],
"content-hash": "a5cfc4b45a24e6a518c075b48dd49b74",
"packages": [
{
"name": "ademarre/binary-to-text-php",
"version": "dev-master",
"source": {
"type": "git",
"url": "https://github.com/ademarre/binary-to-text-php.git",
"reference": "5d98d17be16d65e03851654a717293a4317bb947"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/ademarre/binary-to-text-php/zipball/5d98d17be16d65e03851654a717293a4317bb947",
"reference": "5d98d17be16d65e03851654a717293a4317bb947",
"shasum": ""
},
"require": {
"php": ">=5.2.14"
},
"type": "library",
"autoload": {
"psr-0": {
"Base2n": ""
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Andre DeMarre",
"role": "Developer"
}
],
"description": "Collection of binary-to-text encoding utilities for PHP. Includes Base32 support and much more.",
"homepage": "https://github.com/ademarre/binary-to-text-php",
"keywords": [
"base-4",
"base-8",
"base32",
"binary",
"octal",
"rfc4648"
],
"time": "2015-02-27T05:11:22+00:00"
},
{
"name": "defuse/php-encryption",
"version": "v2.1.0",
"source": {
"type": "git",
"url": "https://github.com/defuse/php-encryption.git",
"reference": "5176f5abb38d3ea8a6e3ac6cd3bbb54d8185a689"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/defuse/php-encryption/zipball/5176f5abb38d3ea8a6e3ac6cd3bbb54d8185a689",
"reference": "5176f5abb38d3ea8a6e3ac6cd3bbb54d8185a689",
"shasum": ""
},
"require": {
"ext-openssl": "*",
"paragonie/random_compat": "~2.0",
"php": ">=5.4.0"
},
"require-dev": {
"nikic/php-parser": "^2.0|^3.0",
"phpunit/phpunit": "^4|^5"
},
"bin": [
"bin/generate-defuse-key"
],
"type": "library",
"autoload": {
"psr-4": {
"Defuse\\Crypto\\": "src"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Taylor Hornby",
"email": "taylor@defuse.ca",
"homepage": "https://defuse.ca/"
},
{
"name": "Scott Arciszewski",
"email": "info@paragonie.com",
"homepage": "https://paragonie.com"
}
],
"description": "Secure PHP Encryption Library",
"keywords": [
"aes",
"authenticated encryption",
"cipher",
"crypto",
"cryptography",
"encrypt",
"encryption",
"openssl",
"security",
"symmetric key cryptography"
],
"time": "2017-05-18T21:28:48+00:00"
},
{
"name": "paragonie/random_compat",
"version": "v2.0.10",
"source": {
"type": "git",
"url": "https://github.com/paragonie/random_compat.git",
"reference": "634bae8e911eefa89c1abfbf1b66da679ac8f54d"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/paragonie/random_compat/zipball/634bae8e911eefa89c1abfbf1b66da679ac8f54d",
"reference": "634bae8e911eefa89c1abfbf1b66da679ac8f54d",
"shasum": ""
},
"require": {
"php": ">=5.2.0"
},
"require-dev": {
"phpunit/phpunit": "4.*|5.*"
},
"suggest": {
"ext-libsodium": "Provides a modern crypto API that can be used to generate random bytes."
},
"type": "library",
"autoload": {
"files": [
"lib/random.php"
]
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Paragon Initiative Enterprises",
"email": "security@paragonie.com",
"homepage": "https://paragonie.com"
}
],
"description": "PHP 5.x polyfill for random_bytes() and random_int() from PHP 7",
"keywords": [
"csprng",
"pseudorandom",
"random"
],
"time": "2017-03-13T16:27:32+00:00"
},
{
"name": "phpmailer/phpmailer",
"version": "v6.0.1",
"source": {
"type": "git",
"url": "https://github.com/PHPMailer/PHPMailer.git",
"reference": "992392437c2e2784e0dc41446024fe411d293c96"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/PHPMailer/PHPMailer/zipball/992392437c2e2784e0dc41446024fe411d293c96",
"reference": "992392437c2e2784e0dc41446024fe411d293c96",
"shasum": ""
},
"require": {
"ext-ctype": "*",
"php": ">=5.5.0"
},
"require-dev": {
"doctrine/annotations": "1.2.*",
"friendsofphp/php-cs-fixer": "^2.2",
"phpdocumentor/phpdocumentor": "2.*",
"phpunit/phpunit": "^4.8 || ^5.7",
"zendframework/zend-eventmanager": "3.0.*",
"zendframework/zend-i18n": "2.7.3",
"zendframework/zend-serializer": "2.7.*"
},
"suggest": {
"ext-mbstring": "Needed to send email in multibyte encoding charset",
"hayageek/oauth2-yahoo": "Needed for Yahoo XOAUTH2 authentication",
"league/oauth2-google": "Needed for Google XOAUTH2 authentication",
"psr/log": "For optional PSR-3 debug logging",
"stevenmaguire/oauth2-microsoft": "Needed for Microsoft XOAUTH2 authentication",
"symfony/polyfill-mbstring": "To support UTF-8 if the Mbstring PHP extension is not enabled (^1.2)"
},
"type": "library",
"autoload": {
"psr-4": {
"PHPMailer\\PHPMailer\\": "src/"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"LGPL-2.1"
],
"authors": [
{
"name": "Jim Jagielski",
"email": "jimjag@gmail.com"
},
{
"name": "Marcus Bointon",
"email": "phpmailer@synchromedia.co.uk"
},
{
"name": "Andy Prevost",
"email": "codeworxtech@users.sourceforge.net"
},
{
"name": "Brent R. Matzelle"
}
],
"description": "PHPMailer is a full-featured email creation and transfer class for PHP",
"time": "2017-09-14T16:47:12+00:00"
},
{
"name": "phpseclib/phpseclib",
"version": "2.0.6",
"source": {
"type": "git",
"url": "https://github.com/phpseclib/phpseclib.git",
"reference": "34a7699e6f31b1ef4035ee36444407cecf9f56aa"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/phpseclib/phpseclib/zipball/34a7699e6f31b1ef4035ee36444407cecf9f56aa",
"reference": "34a7699e6f31b1ef4035ee36444407cecf9f56aa",
"shasum": ""
},
"require": {
"php": ">=5.3.3"
},
"require-dev": {
"phing/phing": "~2.7",
"phpunit/phpunit": "~4.0",
"sami/sami": "~2.0",
"squizlabs/php_codesniffer": "~2.0"
},
"suggest": {
"ext-gmp": "Install the GMP (GNU Multiple Precision) extension in order to speed up arbitrary precision integer arithmetic operations.",
"ext-libsodium": "SSH2/SFTP can make use of some algorithms provided by the libsodium-php extension.",
"ext-mcrypt": "Install the Mcrypt extension in order to speed up a few other cryptographic operations.",
"ext-openssl": "Install the OpenSSL extension in order to speed up a wide variety of cryptographic operations."
},
"type": "library",
"autoload": {
"files": [
"phpseclib/bootstrap.php"
],
"psr-4": {
"phpseclib\\": "phpseclib/"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Jim Wigginton",
"email": "terrafrost@php.net",
"role": "Lead Developer"
},
{
"name": "Patrick Monnerat",
"email": "pm@datasphere.ch",
"role": "Developer"
},
{
"name": "Andreas Fischer",
"email": "bantu@phpbb.com",
"role": "Developer"
},
{
"name": "Hans-Jürgen Petrich",
"email": "petrich@tronic-media.com",
"role": "Developer"
},
{
"name": "Graham Campbell",
"email": "graham@alt-three.com",
"role": "Developer"
}
],
"description": "PHP Secure Communications Library - Pure-PHP implementations of RSA, AES, SSH2, SFTP, X.509 etc.",
"homepage": "http://phpseclib.sourceforge.net",
"keywords": [
"BigInteger",
"aes",
"asn.1",
"asn1",
"blowfish",
"crypto",
"cryptography",
"encryption",
"rsa",
"security",
"sftp",
"signature",
"signing",
"ssh",
"twofish",
"x.509",
"x509"
],
"time": "2017-06-05T06:31:10+00:00"
}
],
"packages-dev": [],
"aliases": [],
"minimum-stability": "stable",
"stability-flags": {
"ademarre/binary-to-text-php": 20
},
"prefer-stable": false,
"prefer-lowest": false,
"platform": {
"php": "5.6.* || 7.0.*"
},
"platform-dev": []
}

View File

@@ -25,7 +25,7 @@
use SP\Html\Minify;
use SP\Http\Request;
define('APP_ROOT', '..');
define('APP_ROOT', dirname(__DIR__));
require_once APP_ROOT . DIRECTORY_SEPARATOR . 'inc' . DIRECTORY_SEPARATOR . 'Base.php';

View File

@@ -30,34 +30,37 @@ defined('APP_ROOT') || die();
define('XML_CONFIG_FILE', __DIR__ . DIRECTORY_SEPARATOR . '..' . DIRECTORY_SEPARATOR . 'config' . DIRECTORY_SEPARATOR . 'config.xml');
define('BASE_DIR', __DIR__);
define('CONFIG_FILE', __DIR__ . DIRECTORY_SEPARATOR . '..' . DIRECTORY_SEPARATOR . 'config' . DIRECTORY_SEPARATOR . 'config.php');
define('MODEL_PATH', __DIR__ . DIRECTORY_SEPARATOR . 'SP');
define('CONTROLLER_PATH', __DIR__ . DIRECTORY_SEPARATOR . '..' . DIRECTORY_SEPARATOR . 'web');
define('VIEW_PATH', __DIR__ . DIRECTORY_SEPARATOR . 'themes');
define('EXTENSIONS_PATH', __DIR__ . DIRECTORY_SEPARATOR . 'Exts');
define('PLUGINS_PATH', __DIR__ . DIRECTORY_SEPARATOR . 'Plugins');
define('LOCALES_PATH', __DIR__ . DIRECTORY_SEPARATOR . 'locales');
define('SQL_PATH', __DIR__ . DIRECTORY_SEPARATOR . 'sql');
define('LOG_FILE', __DIR__ . DIRECTORY_SEPARATOR . '..' . DIRECTORY_SEPARATOR . 'config' . DIRECTORY_SEPARATOR . 'syspass.log');
define('CONFIG_FILE', APP_ROOT . DIRECTORY_SEPARATOR . 'config' . DIRECTORY_SEPARATOR . 'config.php');
define('VENDOR_PATH', APP_ROOT . DIRECTORY_SEPARATOR . 'vendor');
define('LOG_FILE', APP_ROOT . DIRECTORY_SEPARATOR . 'config' . DIRECTORY_SEPARATOR . 'syspass.log');
define('MODEL_PATH', BASE_DIR . DIRECTORY_SEPARATOR . 'SP');
define('VIEW_PATH', BASE_DIR . DIRECTORY_SEPARATOR . 'themes');
define('EXTENSIONS_PATH', BASE_DIR . DIRECTORY_SEPARATOR . 'Exts');
define('PLUGINS_PATH', BASE_DIR . DIRECTORY_SEPARATOR . 'Plugins');
define('LOCALES_PATH', BASE_DIR . DIRECTORY_SEPARATOR . 'locales');
define('SQL_PATH', BASE_DIR . DIRECTORY_SEPARATOR . 'sql');
define('DEBUG', true);
require VENDOR_PATH . DIRECTORY_SEPARATOR . 'autoload.php';
// Required random_compat polyfill for random_bytes() and random_int()
// @see https://github.com/paragonie/random_compat/tree/v2.0.4#random_compat
require_once EXTENSIONS_PATH . DIRECTORY_SEPARATOR . 'random_compat' . DIRECTORY_SEPARATOR . 'lib' . DIRECTORY_SEPARATOR . 'random.php';
//require_once EXTENSIONS_PATH . DIRECTORY_SEPARATOR . 'random_compat' . DIRECTORY_SEPARATOR . 'lib' . DIRECTORY_SEPARATOR . 'random.php';
//
require __DIR__ . DIRECTORY_SEPARATOR . 'SplClassLoader.php';
$ClassLoader = new SplClassLoader('SP');
$ClassLoader->setFileExtension('.class.php');
$ClassLoader->addExcluded('SP\\Profile');
$ClassLoader->addExcluded('SP\\Mgmt\\User\\Profile');
$ClassLoader->addExcluded('SP\\UserPreferences');
$ClassLoader->addExcluded('SP\\Mgmt\\User\\UserPreferences');
$ClassLoader->addExcluded('SP\\CustomFieldDef');
$ClassLoader->addExcluded('SP\\Mgmt\\CustomFieldDef');
$ClassLoader->addExcluded('SP\\PublicLink');
$ClassLoader->register();
//
//$ClassLoader = new SplClassLoader('SP');
//$ClassLoader->setFileExtension('.class.php');
//$ClassLoader->addExcluded('SP\\Profile');
//$ClassLoader->addExcluded('SP\\Mgmt\\User\\Profile');
//$ClassLoader->addExcluded('SP\\UserPreferences');
//$ClassLoader->addExcluded('SP\\Mgmt\\User\\UserPreferences');
//$ClassLoader->addExcluded('SP\\CustomFieldDef');
//$ClassLoader->addExcluded('SP\\Mgmt\\CustomFieldDef');
//$ClassLoader->addExcluded('SP\\PublicLink');
//$ClassLoader->register();
require __DIR__ . DIRECTORY_SEPARATOR . 'BaseFunctions.php';

View File

@@ -1,305 +0,0 @@
<?php
namespace Exts;
/**
* Binary-to-text PHP Utilities
*
* @package binary-to-text-php
* @link https://github.com/ademarre/binary-to-text-php
* @author Andre DeMarre
* @copyright 2009-2013 Andre DeMarre
* @license http://opensource.org/licenses/MIT MIT
*/
/**
* Class for binary-to-text encoding with a base of 2^n
*
* The Base2n class is for binary-to-text conversion. It employs a
* generalization of the algorithms used by many encoding schemes that
* use a fixed number of bits to encode each character. In other words,
* the base is a power of 2.
*
* Earlier versions of this class were named
* FixedBitNotation and FixedBitEncoding.
*
* @package binary-to-text-php
*/
class Base2n
{
protected $_chars;
protected $_bitsPerCharacter;
protected $_radix;
protected $_rightPadFinalBits;
protected $_padFinalGroup;
protected $_padCharacter;
protected $_caseSensitive;
protected $_charmap;
/**
* Constructor
*
* @param integer $bitsPerCharacter Bits to use for each encoded character
* @param string $chars Base character alphabet
* @param boolean $caseSensitive To decode in a case-sensitive manner
* @param boolean $rightPadFinalBits How to encode last character
* @param boolean $padFinalGroup Add padding to end of encoded output
* @param string $padCharacter Character to use for padding
*
* @throws \InvalidArgumentException for incompatible parameters
*/
public function __construct(
$bitsPerCharacter,
$chars = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ-_',
$caseSensitive = TRUE, $rightPadFinalBits = FALSE,
$padFinalGroup = FALSE, $padCharacter = '=')
{
// Ensure validity of $chars
if (!is_string($chars) || ($charLength = strlen($chars)) < 2) {
throw new \InvalidArgumentException('$chars must be a string of at least two characters');
}
// Ensure validity of $padCharacter
if ($padFinalGroup) {
if (!is_string($padCharacter) || !isset($padCharacter[0])) {
throw new \InvalidArgumentException('$padCharacter must be a string of one character');
}
if ($caseSensitive) {
$padCharFound = strpos($chars, $padCharacter[0]);
} else {
$padCharFound = stripos($chars, $padCharacter[0]);
}
if ($padCharFound !== FALSE) {
throw new \InvalidArgumentException('$padCharacter can not be a member of $chars');
}
}
// Ensure validity of $bitsPerCharacter
if (!is_int($bitsPerCharacter)) {
throw new \InvalidArgumentException('$bitsPerCharacter must be an integer');
}
if ($bitsPerCharacter < 1) {
// $bitsPerCharacter must be at least 1
throw new \InvalidArgumentException('$bitsPerCharacter can not be less than 1');
} elseif ($charLength < 1 << $bitsPerCharacter) {
// Character length of $chars is too small for $bitsPerCharacter
// Find greatest acceptable value of $bitsPerCharacter
$bitsPerCharacter = 1;
$radix = 2;
while ($charLength >= ($radix <<= 1) && $bitsPerCharacter < 8) {
$bitsPerCharacter++;
}
$radix >>= 1;
throw new \InvalidArgumentException(
'$bitsPerCharacter can not be more than ' . $bitsPerCharacter
. ' given $chars length of ' . $charLength
. ' (max radix ' . $radix . ')');
} elseif ($bitsPerCharacter > 8) {
// $bitsPerCharacter must not be greater than 8
throw new \InvalidArgumentException('$bitsPerCharacter can not be greater than 8');
} else {
$radix = 1 << $bitsPerCharacter;
}
$this->_chars = $chars;
$this->_bitsPerCharacter = $bitsPerCharacter;
$this->_radix = $radix;
$this->_rightPadFinalBits = $rightPadFinalBits;
$this->_padFinalGroup = $padFinalGroup;
$this->_padCharacter = $padCharacter[0];
$this->_caseSensitive = $caseSensitive;
}
/**
* Encode a string
*
* @param string $rawString Binary data to encode
* @return string
*/
public function encode($rawString)
{
// Unpack string into an array of bytes
$bytes = unpack('C*', $rawString);
$byteCount = count($bytes);
$encodedString = '';
$byte = array_shift($bytes);
$bitsRead = 0;
$oldBits = 0;
$chars = $this->_chars;
$bitsPerCharacter = $this->_bitsPerCharacter;
$rightPadFinalBits = $this->_rightPadFinalBits;
$padFinalGroup = $this->_padFinalGroup;
$padCharacter = $this->_padCharacter;
$charsPerByte = 8 / $bitsPerCharacter;
$encodedLength = $byteCount * $charsPerByte;
// Generate encoded output; each loop produces one encoded character
for ($c = 0; $c < $encodedLength; $c++) {
// Get the bits needed for this encoded character
if ($bitsRead + $bitsPerCharacter > 8) {
// Not enough bits remain in this byte for the current character
// Save the remaining bits before getting the next byte
$oldBitCount = 8 - $bitsRead;
$oldBits = $byte ^ ($byte >> $oldBitCount << $oldBitCount);
$newBitCount = $bitsPerCharacter - $oldBitCount;
if (!$bytes) {
// Last bits; match final character and exit loop
if ($rightPadFinalBits) $oldBits <<= $newBitCount;
$encodedString .= $chars[$oldBits];
if ($padFinalGroup) {
// Array of the lowest common multiples of $bitsPerCharacter and 8, divided by 8
$lcmMap = array(1 => 1, 2 => 1, 3 => 3, 4 => 1, 5 => 5, 6 => 3, 7 => 7, 8 => 1);
$bytesPerGroup = $lcmMap[$bitsPerCharacter];
$pads = $bytesPerGroup * $charsPerByte - ceil((strlen($rawString) % $bytesPerGroup) * $charsPerByte);
$encodedString .= str_repeat($padCharacter, $pads);
}
break;
}
// Get next byte
$byte = array_shift($bytes);
$bitsRead = 0;
} else {
$oldBitCount = 0;
$newBitCount = $bitsPerCharacter;
}
// Read only the needed bits from this byte
$bits = $byte >> 8 - ($bitsRead + ($newBitCount));
$bits ^= $bits >> $newBitCount << $newBitCount;
$bitsRead += $newBitCount;
if ($oldBitCount) {
// Bits come from seperate bytes, add $oldBits to $bits
$bits = ($oldBits << $newBitCount) | $bits;
}
$encodedString .= $chars[$bits];
}
return $encodedString;
}
/**
* Decode a string
*
* @param string $encodedString Data to decode
* @param boolean $strict Returns NULL if $encodedString contains an undecodable character
* @return string
*/
public function decode($encodedString, $strict = FALSE)
{
if (!$encodedString || !is_string($encodedString)) {
// Empty string, nothing to decode
return '';
}
$chars = $this->_chars;
$bitsPerCharacter = $this->_bitsPerCharacter;
$radix = $this->_radix;
$rightPadFinalBits = $this->_rightPadFinalBits;
$padFinalGroup = $this->_padFinalGroup;
$padCharacter = $this->_padCharacter;
$caseSensitive = $this->_caseSensitive;
// Get index of encoded characters
if ($this->_charmap) {
$charmap = $this->_charmap;
} else {
$charmap = array();
for ($i = 0; $i < $radix; $i++) {
$charmap[$chars[$i]] = $i;
}
$this->_charmap = $charmap;
}
// The last encoded character is $encodedString[$lastNotatedIndex]
$lastNotatedIndex = strlen($encodedString) - 1;
// Remove trailing padding characters
if ($padFinalGroup) {
while ($encodedString[$lastNotatedIndex] === $padCharacter) {
$encodedString = substr($encodedString, 0, $lastNotatedIndex);
$lastNotatedIndex--;
}
}
$rawString = '';
$byte = 0;
$bitsWritten = 0;
// Convert each encoded character to a series of unencoded bits
for ($c = 0; $c <= $lastNotatedIndex; $c++) {
if (!$caseSensitive && !isset($charmap[$encodedString[$c]])) {
// Encoded character was not found; try other case
if (isset($charmap[$cUpper = strtoupper($encodedString[$c])])) {
$charmap[$encodedString[$c]] = $charmap[$cUpper];
} elseif (isset($charmap[$cLower = strtolower($encodedString[$c])])) {
$charmap[$encodedString[$c]] = $charmap[$cLower];
}
}
if (isset($charmap[$encodedString[$c]])) {
$bitsNeeded = 8 - $bitsWritten;
$unusedBitCount = $bitsPerCharacter - $bitsNeeded;
// Get the new bits ready
if ($bitsNeeded > $bitsPerCharacter) {
// New bits aren't enough to complete a byte; shift them left into position
$newBits = $charmap[$encodedString[$c]] << $bitsNeeded - $bitsPerCharacter;
$bitsWritten += $bitsPerCharacter;
} elseif ($c !== $lastNotatedIndex || $rightPadFinalBits) {
// Zero or more too many bits to complete a byte; shift right
$newBits = $charmap[$encodedString[$c]] >> $unusedBitCount;
$bitsWritten = 8; //$bitsWritten += $bitsNeeded;
} else {
// Final bits don't need to be shifted
$newBits = $charmap[$encodedString[$c]];
$bitsWritten = 8;
}
$byte |= $newBits;
if ($bitsWritten === 8 || $c === $lastNotatedIndex) {
// Byte is ready to be written
$rawString .= pack('C', $byte);
if ($c !== $lastNotatedIndex) {
// Start the next byte
$bitsWritten = $unusedBitCount;
$byte = ($charmap[$encodedString[$c]] ^ ($newBits << $unusedBitCount)) << 8 - $bitsWritten;
}
}
} elseif ($strict) {
// Unable to decode character; abort
return NULL;
}
}
return $rawString;
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -1,206 +0,0 @@
<?php
/**
* Wrapper around hash() and hash_hmac() functions supporting truncated hashes
* such as sha256-96. Any hash algorithm returned by hash_algos() (and
* truncated versions thereof) are supported.
*
* If {@link \phpseclib\Crypt\Hash::setKey() setKey()} is called,
* {@link \phpseclib\Crypt\Hash::hash() hash()} will return the HMAC as opposed
* to the hash.
*
* Here's a short example of how to use this library:
* <code>
* <?php
* include 'vendor/autoload.php';
*
* $hash = new \phpseclib\Crypt\Hash('sha512');
*
* $hash->setKey('abcdefg');
*
* echo base64_encode($hash->hash('abcdefg'));
* ?>
* </code>
*
* @category Crypt
* @package Hash
* @author Jim Wigginton <terrafrost@php.net>
* @copyright 2015 Jim Wigginton
* @author Andreas Fischer <bantu@phpbb.com>
* @copyright 2015 Andreas Fischer
* @license http://www.opensource.org/licenses/mit-license.html MIT License
* @link http://phpseclib.sourceforge.net
*/
namespace phpseclib\Crypt;
use phpseclib\Exception\UnsupportedAlgorithmException;
/**
* @package Hash
* @author Jim Wigginton <terrafrost@php.net>
* @author Andreas Fischer <bantu@phpbb.com>
* @access public
*/
class Hash
{
/**
* Hash Parameter
*
* @see \phpseclib\Crypt\Hash::setHash()
* @var int
* @access private
*/
var $hashParam;
/**
* Byte-length of hash output (Internal HMAC)
*
* @see \phpseclib\Crypt\Hash::setHash()
* @var int
* @access private
*/
var $length;
/**
* Hash Algorithm
*
* @see \phpseclib\Crypt\Hash::setHash()
* @var string
* @access private
*/
var $hash;
/**
* Key
*
* @see \phpseclib\Crypt\Hash::setKey()
* @var string
* @access private
*/
var $key = false;
/**
* Default Constructor.
*
* @param string $hash
* @access public
*/
function __construct($hash = 'sha256')
{
$this->setHash($hash);
}
/**
* Sets the key for HMACs
*
* Keys can be of any length.
*
* @access public
* @param string $key
*/
function setKey($key = false)
{
$this->key = $key;
}
/**
* Gets the hash function.
*
* As set by the constructor or by the setHash() method.
*
* @access public
* @return string
*/
function getHash()
{
return $this->hashParam;
}
/**
* Sets the hash function.
*
* @access public
* @param string $hash
*/
function setHash($hash)
{
$this->hashParam = $hash = strtolower($hash);
switch ($hash) {
case 'md5-96':
case 'sha1-96':
case 'sha256-96':
case 'sha512-96':
$hash = substr($hash, 0, -3);
$this->length = 12; // 96 / 8 = 12
break;
case 'md2':
case 'md5':
$this->length = 16;
break;
case 'sha1':
$this->length = 20;
break;
case 'sha256':
$this->length = 32;
break;
case 'sha384':
$this->length = 48;
break;
case 'sha512':
$this->length = 64;
break;
default:
// see if the hash isn't "officially" supported see if it can
// be "unofficially" supported and calculate the length
// accordingly.
if (in_array($hash, hash_algos())) {
$this->length = strlen(hash($hash, '', true));
break;
}
// if the hash algorithm doens't exist maybe it's a truncated
// hash, e.g. whirlpool-12 or some such.
if (preg_match('#(-\d+)$#', $hash, $matches)) {
$hash = substr($hash, 0, -strlen($matches[1]));
if (in_array($hash, hash_algos())) {
$this->length = abs($matches[1]) >> 3;
break;
}
}
throw new UnsupportedAlgorithmException(
"$hash is not a supported algorithm"
);
}
$this->hash = $hash;
}
/**
* Compute the HMAC.
*
* @access public
* @param string $text
* @return string
*/
function hash($text)
{
$output = !empty($this->key) || is_string($this->key) ?
hash_hmac($this->hash, $text, $this->key, true) :
hash($this->hash, $text, true);
return strlen($output) > $this->length
? substr($output, 0, $this->length)
: $output;
}
/**
* Returns the hash length (in bytes)
*
* @access public
* @return int
*/
function getLength()
{
return $this->length;
}
}

View File

@@ -1,26 +0,0 @@
<?php
/**
* BadConfigurationException
*
* PHP version 5
*
* @category Exception
* @package BadConfigurationException
* @author Jim Wigginton <terrafrost@php.net>
* @copyright 2015 Jim Wigginton
* @license http://www.opensource.org/licenses/mit-license.html MIT License
* @link http://phpseclib.sourceforge.net
*/
namespace phpseclib\Exception;
/**
* BadConfigurationException
*
* @package BadConfigurationException
* @author Jim Wigginton <terrafrost@php.net>
*/
class BadConfigurationException extends \RuntimeException
{
}

View File

@@ -1,26 +0,0 @@
<?php
/**
* FileNotFoundException
*
* PHP version 5
*
* @category Exception
* @package FileNotFoundException
* @author Jim Wigginton <terrafrost@php.net>
* @copyright 2015 Jim Wigginton
* @license http://www.opensource.org/licenses/mit-license.html MIT License
* @link http://phpseclib.sourceforge.net
*/
namespace phpseclib\Exception;
/**
* FileNotFoundException
*
* @package FileNotFoundException
* @author Jim Wigginton <terrafrost@php.net>
*/
class FileNotFoundException extends \RuntimeException
{
}

View File

@@ -1,26 +0,0 @@
<?php
/**
* NoSupportedAlgorithmsException
*
* PHP version 5
*
* @category Exception
* @package NoSupportedAlgorithmsException
* @author Jim Wigginton <terrafrost@php.net>
* @copyright 2015 Jim Wigginton
* @license http://www.opensource.org/licenses/mit-license.html MIT License
* @link http://phpseclib.sourceforge.net
*/
namespace phpseclib\Exception;
/**
* NoSupportedAlgorithmsException
*
* @package NoSupportedAlgorithmsException
* @author Jim Wigginton <terrafrost@php.net>
*/
class NoSupportedAlgorithmsException extends \RuntimeException
{
}

View File

@@ -1,26 +0,0 @@
<?php
/**
* UnsupportedAlgorithmException
*
* PHP version 5
*
* @category Exception
* @package UnsupportedAlgorithmException
* @author Jim Wigginton <terrafrost@php.net>
* @copyright 2015 Jim Wigginton
* @license http://www.opensource.org/licenses/mit-license.html MIT License
* @link http://phpseclib.sourceforge.net
*/
namespace phpseclib\Exception;
/**
* UnsupportedAlgorithmException
*
* @package UnsupportedAlgorithmException
* @author Jim Wigginton <terrafrost@php.net>
*/
class UnsupportedAlgorithmException extends \RuntimeException
{
}

View File

@@ -1,215 +0,0 @@
<?php
/**
* Random_* Compatibility Library
* for using the new PHP 7 random_* API in PHP 5 projects
*
* @version 2.0.4
* @released 2016-11-07
*
* The MIT License (MIT)
*
* Copyright (c) 2015 - 2016 Paragon Initiative Enterprises
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
if (!defined('PHP_VERSION_ID')) {
// This constant was introduced in PHP 5.2.7
$RandomCompatversion = array_map('intval', explode('.', PHP_VERSION));
define(
'PHP_VERSION_ID',
$RandomCompatversion[0] * 10000
+ $RandomCompatversion[1] * 100
+ $RandomCompatversion[2]
);
$RandomCompatversion = null;
}
/**
* 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);
}
$RandomCompatDIR = dirname(__FILE__);
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()
* 5. openssl_random_pseudo_bytes() (absolute last resort)
*
* 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;
}
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;
}
/**
* 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 (
DIRECTORY_SEPARATOR !== '/' ||
(PHP_VERSION_ID <= 50609 || PHP_VERSION_ID >= 50613)
) {
// See random_bytes_mcrypt.php
require_once $RandomCompatDIR.'/random_bytes_mcrypt.php';
}
}
$RandomCompatUrandom = null;
/**
* 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;
}
/**
* throw new Exception
*/
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'
);
}
}
}
if (!is_callable('random_int')) {
require_once $RandomCompatDIR.'/random_int.php';
}
$RandomCompatDIR = null;
}

View File

@@ -1,191 +0,0 @@
<?php
/**
* Random_* Compatibility Library
* for using the new PHP 7 random_* API in PHP 5 projects
*
* The MIT License (MIT)
*
* Copyright (c) 2015 - 2016 Paragon Initiative Enterprises
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
/**
* Fetch a random integer between $min and $max inclusive
*
* @param int $min
* @param int $max
*
* @throws Exception
*
* @return int
*/
function random_int($min, $max)
{
/**
* Type and input logic checks
*
* If you pass it a float in the range (~PHP_INT_MAX, PHP_INT_MAX)
* (non-inclusive), it will sanely cast it to an int. If you it's equal to
* ~PHP_INT_MAX or PHP_INT_MAX, we let it fail as not an integer. Floats
* lose precision, so the <= and => operators might accidentally let a float
* through.
*/
try {
$min = RandomCompat_intval($min);
} catch (TypeError $ex) {
throw new TypeError(
'random_int(): $min must be an integer'
);
}
try {
$max = RandomCompat_intval($max);
} catch (TypeError $ex) {
throw new TypeError(
'random_int(): $max must be an integer'
);
}
/**
* Now that we've verified our weak typing system has given us an integer,
* let's validate the logic then we can move forward with generating random
* integers along a given range.
*/
if ($min > $max) {
throw new Error(
'Minimum value must be less than or equal to the maximum value'
);
}
if ($max === $min) {
return $min;
}
/**
* Initialize variables to 0
*
* We want to store:
* $bytes => the number of random bytes we need
* $mask => an integer bitmask (for use with the &) operator
* so we can minimize the number of discards
*/
$attempts = $bits = $bytes = $mask = $valueShift = 0;
/**
* At this point, $range is a positive number greater than 0. It might
* overflow, however, if $max - $min > PHP_INT_MAX. PHP will cast it to
* a float and we will lose some precision.
*/
$range = $max - $min;
/**
* Test for integer overflow:
*/
if (!is_int($range)) {
/**
* Still safely calculate wider ranges.
* Provided by @CodesInChaos, @oittaa
*
* @ref https://gist.github.com/CodesInChaos/03f9ea0b58e8b2b8d435
*
* We use ~0 as a mask in this case because it generates all 1s
*
* @ref https://eval.in/400356 (32-bit)
* @ref http://3v4l.org/XX9r5 (64-bit)
*/
$bytes = PHP_INT_SIZE;
$mask = ~0;
} else {
/**
* $bits is effectively ceil(log($range, 2)) without dealing with
* type juggling
*/
while ($range > 0) {
if ($bits % 8 === 0) {
++$bytes;
}
++$bits;
$range >>= 1;
$mask = $mask << 1 | 1;
}
$valueShift = $min;
}
/**
* Now that we have our parameters set up, let's begin generating
* random integers until one falls between $min and $max
*/
do {
/**
* The rejection probability is at most 0.5, so this corresponds
* to a failure probability of 2^-128 for a working RNG
*/
if ($attempts > 128) {
throw new Exception(
'random_int: RNG is broken - too many rejections'
);
}
/**
* Let's grab the necessary number of random bytes
*/
$randomByteString = random_bytes($bytes);
if ($randomByteString === false) {
throw new Exception(
'Random number generator failure'
);
}
/**
* Let's turn $randomByteString into an integer
*
* This uses bitwise operators (<< and |) to build an integer
* out of the values extracted from ord()
*
* Example: [9F] | [6D] | [32] | [0C] =>
* 159 + 27904 + 3276800 + 201326592 =>
* 204631455
*/
$val = 0;
for ($i = 0; $i < $bytes; ++$i) {
$val |= ord($randomByteString[$i]) << ($i * 8);
}
/**
* Apply mask
*/
$val &= $mask;
$val += $valueShift;
++$attempts;
/**
* If $val overflows to a floating point number,
* ... or is larger than $max,
* ... or smaller than $min,
* then try again.
*/
} while (!is_int($val) || $val > $max || $val < $min);
return (int) $val;
}

Some files were not shown because too many files have changed in this diff Show More