|
|
c143c4 |
|
|
|
c143c4 |
<html>
|
|
|
c143c4 |
<head>
|
|
|
c143c4 |
<meta content="text/html; charset=windows-1252" http-equiv="Content-Type" />
|
|
|
c143c4 |
<meta http-equiv="MSThemeCompatible" content="yes" />
|
|
|
c143c4 |
<title>vBulletin Test Script</title>
|
|
|
c143c4 |
<link rel="stylesheet" href="https://images.vbulletin.com/testscript/vb_test.css" />
|
|
|
c143c4 |
</head>
|
|
|
c143c4 |
<body>
|
|
|
c143c4 |
|
|
|
c143c4 |
|
|
|
c143c4 |
|
|
|
c143c4 |
vBulletin Server Test Script vBulletin Website
|
|
|
c143c4 |
|
|
|
c143c4 |
|
|
|
c143c4 |
|
|
|
c143c4 |
|
|
|
c143c4 |
|
|
|
c143c4 |
|
|
|
c143c4 |
error_reporting(E_ALL);
|
|
|
c143c4 |
|
|
|
c143c4 |
function iif($condition, $truevalue, $falsevalue = '')
|
|
|
c143c4 |
{
|
|
|
c143c4 |
if ($condition)
|
|
|
c143c4 |
{
|
|
|
c143c4 |
return $truevalue;
|
|
|
c143c4 |
}
|
|
|
c143c4 |
else
|
|
|
c143c4 |
{
|
|
|
c143c4 |
return $falsevalue;
|
|
|
c143c4 |
}
|
|
|
c143c4 |
}
|
|
|
c143c4 |
|
|
|
c143c4 |
class DB
|
|
|
c143c4 |
{
|
|
|
c143c4 |
public static function fetch_db($host, $user, $password, $dbname)
|
|
|
c143c4 |
{
|
|
|
c143c4 |
global $db_connection_error;
|
|
|
c143c4 |
$obj = @new mysqli($host, $user, $password, $dbname);
|
|
|
c143c4 |
|
|
|
c143c4 |
//note that according to the documentation we should do this between
|
|
|
c143c4 |
//the init call and real_connect (the constructor effectively does both
|
|
|
c143c4 |
//of these at once). However there is a bug in PHP where this doesn't work
|
|
|
c143c4 |
//and real_connect will reset the option to the ini value.
|
|
|
c143c4 |
//
|
|
|
c143c4 |
//We can't set the ini value because PHP doesn't allow this value to be
|
|
|
c143c4 |
//set in a script. So this is the best we can do. Note that on all supported
|
|
|
c143c4 |
//versions of PHP this ini value is set securely by default.
|
|
|
c143c4 |
$obj->options(MYSQLI_OPT_LOCAL_INFILE, false);
|
|
|
c143c4 |
|
|
|
c143c4 |
if (mysqli_connect_errno())
|
|
|
c143c4 |
{
|
|
|
c143c4 |
$db_connection_error = mysqli_connect_error();
|
|
|
c143c4 |
return false;
|
|
|
c143c4 |
}
|
|
|
c143c4 |
return $obj;
|
|
|
c143c4 |
}
|
|
|
c143c4 |
}
|
|
|
c143c4 |
|
|
|
c143c4 |
function test_ini_set($setting, $value)
|
|
|
c143c4 |
{
|
|
|
c143c4 |
$result = @ini_set($setting, $value);
|
|
|
c143c4 |
if ($result === false OR $result === null)
|
|
|
c143c4 |
{
|
|
|
c143c4 |
return false;
|
|
|
c143c4 |
}
|
|
|
c143c4 |
else
|
|
|
c143c4 |
{
|
|
|
c143c4 |
return $result;
|
|
|
c143c4 |
}
|
|
|
c143c4 |
}
|
|
|
c143c4 |
|
|
|
c143c4 |
//initalise variables dont want any XSS in our test script :)
|
|
|
c143c4 |
$versions = array();
|
|
|
c143c4 |
|
|
|
c143c4 |
$required_versions = array(
|
|
|
c143c4 |
'PHP' => '7.2.0',
|
|
|
c143c4 |
'MySQL' => '5.5.8'
|
|
|
c143c4 |
);
|
|
|
c143c4 |
|
|
|
c143c4 |
if (!empty($_GET['help']))
|
|
|
c143c4 |
{
|
|
|
c143c4 |
$tested = false;
|
|
|
c143c4 |
|
|
|
c143c4 |
$type = strtolower($_GET['help']);
|
|
|
c143c4 |
$help = array();
|
|
|
c143c4 |
$help['php'] = 'Your PHP Version is too low to support vBulletin 5, you must at least upgrade to ' . $required_versions['PHP'];
|
|
|
c143c4 |
$help['mysql'] = 'Your MySQL version is too low to support vBulletin 5, you must at least upgrade to ' . $required_versions['MySQL'];
|
|
|
c143c4 |
$help['pcre'] = 'vBulletin requires PCRE to be enabled in PHP, ask your host to enable this in php.ini';
|
|
|
c143c4 |
$help['open_basedir'] = 'You may experience problems with uploading files to vBulletin';
|
|
|
c143c4 |
$help['curl'] = 'The cUrl extension is needed for many features that gather data from the internet';
|
|
|
c143c4 |
$help['json'] = 'The JSON extension is required to support vBulletin 5';
|
|
|
c143c4 |
$help['gzip'] = 'vBulletin uses GZIP to compress pages, though this is not essential for operation';
|
|
|
c143c4 |
$help['mysql_perms'] = 'vBulletin requires that the mysql username has create, select, update, insert, ' .
|
|
|
c143c4 |
'delete, alter and drop privledges, contact your host and ask them to adjust these privledges.';
|
|
|
c143c4 |
$help['xml'] = 'XML is required as a major component of vBulletin for data storage of languages, settings and templates.';
|
|
|
c143c4 |
$help['gd'] = 'GD functions are used to produce images, this includes features such as thumbnails and image verification on registration';
|
|
|
c143c4 |
$help['iconv'] = 'Iconv is used to handle different character encodings. Either the Multibyte String ' .
|
|
|
c143c4 |
'or iconv modules are required to properly handle character encodings. Multibyte String is preferred.';
|
|
|
c143c4 |
$help['mbstring'] = 'Multibyte String is used to handle different character encodings. Either the Multibyte String ' .
|
|
|
c143c4 |
'or iconv modules are required to properly handle character encodings. Multibyte String is preferred.';
|
|
|
c143c4 |
$help['pcre.backtrack_limit'] = 'PHP 5.2.0 and above imposes a limit on PCRE code that we are unable to work-around on this server. ' .
|
|
|
c143c4 |
'Ask your host to add the following to php.ini:
pcre.backtrack_limit = -1 ';
|
|
|
c143c4 |
$help['pcre.utf8'] = 'PCRE with utf8 support is recommended';
|
|
|
c143c4 |
$help['mysql.utf8mb4'] = 'The utf8mb4 character set allows extended (up to four byte) utf8 characters. Requires MySql 5.5.3 or greater.';
|
|
|
c143c4 |
|
|
|
c143c4 |
echo '' . htmlspecialchars($type) . ' Help';
|
|
|
c143c4 |
echo '' . $help["$type"] . '';
|
|
|
c143c4 |
}
|
|
|
c143c4 |
elseif (empty($_POST['server']) or empty($_POST['user']) or empty($_POST['db']))
|
|
|
c143c4 |
{
|
|
|
c143c4 |
$tested = false;
|
|
|
c143c4 |
|
|
|
c143c4 |
echo 'MySQL Information';
|
|
|
c143c4 |
echo '<form method="post">';
|
|
|
c143c4 |
echo '';
|
|
|
c143c4 |
echo ' MySQL Server';
|
|
|
c143c4 |
echo ' <input type="text" name="server" value="localhost" />';
|
|
|
c143c4 |
echo '';
|
|
|
c143c4 |
echo '';
|
|
|
c143c4 |
echo ' MySQL Database';
|
|
|
c143c4 |
echo ' <input type="text" name="db" />';
|
|
|
c143c4 |
echo '';
|
|
|
c143c4 |
echo '';
|
|
|
c143c4 |
echo ' MySQL Username';
|
|
|
c143c4 |
echo ' <input type="text" name="user" />';
|
|
|
c143c4 |
echo '';
|
|
|
c143c4 |
echo '';
|
|
|
c143c4 |
echo ' MySQL Password';
|
|
|
c143c4 |
echo ' <input type="password" name="pass" autocomplete="off" />';
|
|
|
c143c4 |
echo '';
|
|
|
c143c4 |
echo '';
|
|
|
c143c4 |
echo '<input type="submit" value="Run Test" accesskey="s" />';
|
|
|
c143c4 |
echo '';
|
|
|
c143c4 |
echo '</form>';
|
|
|
c143c4 |
}
|
|
|
c143c4 |
else
|
|
|
c143c4 |
{
|
|
|
c143c4 |
$tested = true;
|
|
|
c143c4 |
|
|
|
c143c4 |
/**
|
|
|
c143c4 |
* Define the tests
|
|
|
c143c4 |
*/
|
|
|
c143c4 |
|
|
|
c143c4 |
// modules
|
|
|
c143c4 |
// modulename => 'represtative function' or array('function1', 'function2'). There should also be a "help"
|
|
|
c143c4 |
// entry for every module
|
|
|
c143c4 |
$required_modules = array(
|
|
|
c143c4 |
'PCRE' => 'preg_replace',
|
|
|
c143c4 |
'XML' => 'xml_set_element_handler',
|
|
|
c143c4 |
'curl' => 'curl_init',
|
|
|
c143c4 |
'json' => 'json_encode'
|
|
|
c143c4 |
);
|
|
|
c143c4 |
|
|
|
c143c4 |
$recommended_modules = array(
|
|
|
c143c4 |
'GZIP' => array('crc32', 'gzcompress'),
|
|
|
c143c4 |
'GD' => 'imagecreatetruecolor',
|
|
|
c143c4 |
'iconv' => 'iconv',
|
|
|
c143c4 |
'mbstring' => 'mb_convert_encoding'
|
|
|
c143c4 |
);
|
|
|
c143c4 |
|
|
|
c143c4 |
//'feature' => test query. Will check if query produces an error, but not
|
|
|
c143c4 |
//what it returns
|
|
|
c143c4 |
$mysql_perms = array(
|
|
|
c143c4 |
'create' => 'CREATE TABLE vb3_test (test int(10) unsigned NOT NULL)',
|
|
|
c143c4 |
'alter' => 'ALTER TABLE vb3_test CHANGE test test VARCHAR(254) NOT NULL',
|
|
|
c143c4 |
'insert' => 'INSERT INTO vb3_test (test) VALUES (\'abcd\')',
|
|
|
c143c4 |
'update' => 'UPDATE vb3_test SET test=123 WHERE test=\'abcd\'',
|
|
|
c143c4 |
'select' => 'SELECT * FROM vb3_test WHERE test=123',
|
|
|
c143c4 |
'delete' => 'DELETE FROM vb3_test WHERE test=123',
|
|
|
c143c4 |
'drop' => 'DROP TABLE vb3_test'
|
|
|
c143c4 |
);
|
|
|
c143c4 |
|
|
|
c143c4 |
//either a query string (check for error) or an anonymous function that
|
|
|
c143c4 |
//takes the mysqli object as a parameter. Always fails when the db connection
|
|
|
c143c4 |
//does not exist (function will not be called).
|
|
|
c143c4 |
$mysql_recommended = array(
|
|
|
c143c4 |
'mysql.utf8mb4' => function($db)
|
|
|
c143c4 |
{
|
|
|
c143c4 |
$result = $db->query("SHOW CHARACTER SET LIKE 'utf8mb4'");
|
|
|
c143c4 |
return ($result->num_rows > 0);
|
|
|
c143c4 |
},
|
|
|
c143c4 |
);
|
|
|
c143c4 |
|
|
|
c143c4 |
$required_tests = array();
|
|
|
c143c4 |
|
|
|
c143c4 |
$recommended_tests = array(
|
|
|
c143c4 |
'open_basedir' => function()
|
|
|
c143c4 |
{
|
|
|
c143c4 |
return (get_cfg_var('open_basedir') == '');
|
|
|
c143c4 |
},
|
|
|
c143c4 |
'pcre.backtrack_limit' => function()
|
|
|
c143c4 |
{
|
|
|
c143c4 |
return (!test_ini_set('pcre.backtrack_limit', -1) === false);
|
|
|
c143c4 |
},
|
|
|
c143c4 |
'pcre.utf8support' => function()
|
|
|
c143c4 |
{
|
|
|
c143c4 |
return (@preg_match('/\p{L}/u', 'a') == 1);
|
|
|
c143c4 |
},
|
|
|
c143c4 |
);
|
|
|
c143c4 |
|
|
|
c143c4 |
|
|
|
c143c4 |
/**
|
|
|
c143c4 |
* Run the tests
|
|
|
c143c4 |
*/
|
|
|
c143c4 |
|
|
|
c143c4 |
class vB_TestObserver
|
|
|
c143c4 |
{
|
|
|
c143c4 |
private $results = array();
|
|
|
c143c4 |
private $failures = 0;
|
|
|
c143c4 |
|
|
|
c143c4 |
public function getFailureCount()
|
|
|
c143c4 |
{
|
|
|
c143c4 |
return $this->failures;
|
|
|
c143c4 |
}
|
|
|
c143c4 |
|
|
|
c143c4 |
public function getResults()
|
|
|
c143c4 |
{
|
|
|
c143c4 |
return $this->results;
|
|
|
c143c4 |
}
|
|
|
c143c4 |
|
|
|
c143c4 |
public function logTest($name, $result)
|
|
|
c143c4 |
{
|
|
|
c143c4 |
$this->results[$name] = (bool) $result;
|
|
|
c143c4 |
if(!$result)
|
|
|
c143c4 |
{
|
|
|
c143c4 |
$this->failures++;
|
|
|
c143c4 |
}
|
|
|
c143c4 |
}
|
|
|
c143c4 |
}
|
|
|
c143c4 |
|
|
|
c143c4 |
$requiredResults = new vB_TestObserver();
|
|
|
c143c4 |
$recommendedResults = new vB_TestObserver();
|
|
|
c143c4 |
$mysqlResults = new vB_TestObserver();
|
|
|
c143c4 |
|
|
|
c143c4 |
//PHP
|
|
|
c143c4 |
$versions['PHP'] = phpversion();
|
|
|
c143c4 |
|
|
|
c143c4 |
$db = DB::fetch_db($_POST['server'], $_POST['user'], $_POST['pass'], $_POST['db']);
|
|
|
c143c4 |
//MySQL
|
|
|
c143c4 |
if(!$db)
|
|
|
c143c4 |
{
|
|
|
c143c4 |
//if we don't this this, then then it will be set by the version test.
|
|
|
c143c4 |
$requiredResults->logTest('MySQL', false);
|
|
|
c143c4 |
}
|
|
|
c143c4 |
else
|
|
|
c143c4 |
{
|
|
|
c143c4 |
$vquery = $db->query('SELECT VERSION() AS version');
|
|
|
c143c4 |
$mysql = $vquery->fetch_array();
|
|
|
c143c4 |
$versions['MySQL'] = $mysql['version'];
|
|
|
c143c4 |
}
|
|
|
c143c4 |
|
|
|
c143c4 |
//check mysql permissions
|
|
|
c143c4 |
foreach($mysql_perms AS $feature => $query)
|
|
|
c143c4 |
{
|
|
|
c143c4 |
$mysqlResults->logTest($feature, ($db AND $db->query($query)));
|
|
|
c143c4 |
}
|
|
|
c143c4 |
|
|
|
c143c4 |
foreach($mysql_recommended AS $feature => $query)
|
|
|
c143c4 |
{
|
|
|
c143c4 |
if(!$db)
|
|
|
c143c4 |
{
|
|
|
c143c4 |
$result = false;
|
|
|
c143c4 |
}
|
|
|
c143c4 |
else if (is_callable($query))
|
|
|
c143c4 |
{
|
|
|
c143c4 |
$result = $query($db);
|
|
|
c143c4 |
}
|
|
|
c143c4 |
else
|
|
|
c143c4 |
{
|
|
|
c143c4 |
$result = (bool) $db->query($query);
|
|
|
c143c4 |
}
|
|
|
c143c4 |
|
|
|
c143c4 |
$recommendedResults->logTest($feature, $result);
|
|
|
c143c4 |
}
|
|
|
c143c4 |
|
|
|
c143c4 |
|
|
|
c143c4 |
if ($db)
|
|
|
c143c4 |
{
|
|
|
c143c4 |
$db->close();
|
|
|
c143c4 |
}
|
|
|
c143c4 |
|
|
|
c143c4 |
//check versions -- if we don't set the version of something, we skip the check
|
|
|
c143c4 |
//(presumably this means we couldn't look it up and there is another error that covers
|
|
|
c143c4 |
//that such as the database.
|
|
|
c143c4 |
foreach($versions as $feature => $version)
|
|
|
c143c4 |
{
|
|
|
c143c4 |
$requiredResults->logTest($feature, !version_compare($version, $required_versions[$feature], '<'));
|
|
|
c143c4 |
}
|
|
|
c143c4 |
|
|
|
c143c4 |
function check_modules($modules, $observer)
|
|
|
c143c4 |
{
|
|
|
c143c4 |
//check modules.
|
|
|
c143c4 |
foreach ($modules AS $module => $function)
|
|
|
c143c4 |
{
|
|
|
c143c4 |
$test_function = $function;
|
|
|
c143c4 |
if (!is_array($function))
|
|
|
c143c4 |
{
|
|
|
c143c4 |
$test_function = array($test_function);
|
|
|
c143c4 |
}
|
|
|
c143c4 |
|
|
|
c143c4 |
$pass = true;
|
|
|
c143c4 |
foreach($test_function AS $check)
|
|
|
c143c4 |
{
|
|
|
c143c4 |
if (!function_exists($check))
|
|
|
c143c4 |
{
|
|
|
c143c4 |
$pass = false;
|
|
|
c143c4 |
}
|
|
|
c143c4 |
}
|
|
|
c143c4 |
|
|
|
c143c4 |
$observer->logTest($module, $pass);
|
|
|
c143c4 |
}
|
|
|
c143c4 |
}
|
|
|
c143c4 |
|
|
|
c143c4 |
check_modules($required_modules, $requiredResults);
|
|
|
c143c4 |
check_modules($recommended_modules, $recommendedResults);
|
|
|
c143c4 |
|
|
|
c143c4 |
foreach($required_tests AS $name => $function)
|
|
|
c143c4 |
{
|
|
|
c143c4 |
$requiredResults->logTest($name, $function());
|
|
|
c143c4 |
}
|
|
|
c143c4 |
|
|
|
c143c4 |
foreach($recommended_tests AS $name => $function)
|
|
|
c143c4 |
{
|
|
|
c143c4 |
$recommendedResults->logTest($name, $function());
|
|
|
c143c4 |
}
|
|
|
c143c4 |
|
|
|
c143c4 |
//translate to the previos vars for display -- should eventually rewrite that
|
|
|
c143c4 |
//part as well.
|
|
|
c143c4 |
$e_test = $requiredResults->getResults();
|
|
|
c143c4 |
$mysql = $mysqlResults->getResults();
|
|
|
c143c4 |
$test = $recommendedResults->getResults();
|
|
|
c143c4 |
|
|
|
c143c4 |
//a bit of a hack to handle previous behavior. This doesn't
|
|
|
c143c4 |
//fit into our nice little formal setup.
|
|
|
c143c4 |
//not sure why we set the version only if GD passes.
|
|
|
c143c4 |
if ($test['GD'])
|
|
|
c143c4 |
{
|
|
|
c143c4 |
$versions['GD'] = '2.x';
|
|
|
c143c4 |
}
|
|
|
c143c4 |
|
|
|
c143c4 |
$e_error = $requiredResults->getFailureCount() + $mysqlResults->getFailureCount();
|
|
|
c143c4 |
$error = $recommendedResults->getFailureCount();
|
|
|
c143c4 |
|
|
|
c143c4 |
echo 'Essential vBulletin Requirements';
|
|
|
c143c4 |
foreach ($e_test AS $type => $result) {
|
|
|
c143c4 |
echo '';
|
|
|
c143c4 |
echo ' ' . $type . '';
|
|
|
c143c4 |
echo ' ' . (!isset($versions["$type"]) ? '' : $versions["$type"]) . '';
|
|
|
c143c4 |
echo ' ' . iif($result, 'Pass', 'Fail') . '';
|
|
|
c143c4 |
echo '';
|
|
|
c143c4 |
}
|
|
|
c143c4 |
if ($db_connection_error)
|
|
|
c143c4 |
{
|
|
|
c143c4 |
echo '';
|
|
|
c143c4 |
echo ' Database Connection Error: ' . htmlspecialchars($db_connection_error) . '';
|
|
|
c143c4 |
echo '';
|
|
|
c143c4 |
}
|
|
|
c143c4 |
echo 'MySQL Permission Requirements';
|
|
|
c143c4 |
foreach ($mysql AS $type => $result) {
|
|
|
c143c4 |
echo '';
|
|
|
c143c4 |
echo ' ' . $type . '';
|
|
|
c143c4 |
echo ' ' . iif($result, 'Pass', 'Fail') . '';
|
|
|
c143c4 |
echo '';
|
|
|
c143c4 |
}
|
|
|
c143c4 |
|
|
|
c143c4 |
echo 'Recommended Settings (Optional)';
|
|
|
c143c4 |
foreach ($test AS $type => $result) {
|
|
|
c143c4 |
echo '';
|
|
|
c143c4 |
echo ' ' . $type . '';
|
|
|
c143c4 |
echo ' ' . (!isset($versions["$type"]) ? '' : $versions["$type"]) . '';
|
|
|
c143c4 |
echo ' ' . iif($result, 'Pass', 'Fail') . '';
|
|
|
c143c4 |
echo '';
|
|
|
c143c4 |
}
|
|
|
c143c4 |
|
|
|
c143c4 |
echo 'Overall Result:' . iif($e_error, 'Fail', 'Pass') . '';
|
|
|
c143c4 |
|
|
|
c143c4 |
}
|
|
|
c143c4 |
|
|
|
c143c4 |
?>
|
|
|
c143c4 |
|
|
|
c143c4 |
|
|
|
c143c4 |
|
|
|
c143c4 |
if ($tested AND is_array($test) AND is_array($e_test))
|
|
|
c143c4 |
{
|
|
|
c143c4 |
if ($e_error == 0 AND $error == 0)
|
|
|
c143c4 |
{
|
|
|
c143c4 |
echo 'vBulletin 5 should run on your system without any errors ';
|
|
|
c143c4 |
}
|
|
|
c143c4 |
elseif ($e_error == 0)
|
|
|
c143c4 |
{
|
|
|
c143c4 |
echo 'vBulletin 5 should run on your system though there may be reduced functionality, click the link(s) above for more information ';
|
|
|
c143c4 |
}
|
|
|
c143c4 |
else
|
|
|
c143c4 |
{
|
|
|
c143c4 |
echo 'vBulletin5 will not run on your system, please click the link(s) above for more information. ';
|
|
|
c143c4 |
}
|
|
|
c143c4 |
}
|
|
|
c143c4 |
/*======================================================================*\
|
|
|
c143c4 |
|| ####################################################################
|
|
|
c143c4 |
|| # CVS: $RCSfile$ - $Revision: 105451 $
|
|
|
c143c4 |
|| ####################################################################
|
|
|
c143c4 |
\*======================================================================*/
|
|
|
c143c4 |
?>
|
|
|
c143c4 |
</body>
|
|
|
c143c4 |
</html>
|