Resolve merge conflicts with ChangeLog

Signed-off-by: Isaac Bennetch <bennetch@gmail.com>
This commit is contained in:
Isaac Bennetch 2016-11-24 11:03:58 -05:00
commit 253894e299
30 changed files with 197 additions and 79 deletions

View File

@ -1,7 +1,7 @@
phpMyAdmin - ChangeLog
======================
4.6.5 (not yet released)
4.6.5 (2016-11-24)
- issue Remove potentionally license problematic sRGB profile
- issue #12459 Display read only fields as read only when editing
- issue #12384 Fix expanding of navigation pane when clicking on database
@ -93,6 +93,20 @@ phpMyAdmin - ChangeLog
- issue #12361 Fix self SQL injection in table-specific privileges
- issue #12698 Add link to release notes and download on new version notification
- issue #12712 Error when trying to setup replication (fatal error in call to an old PMA_DBI_connect function)
- issue [security] Unsafe generation of $cfg['blowfish_secret'], see PMASA-2016-58
- issue [security] phpMyAdmin's phpinfo functionality is removed, see PMASA-2016-59
- issue [security] AllowRoot and allow/deny rule bypass with specially-crafted username, see PMASA-2016-60
- issue [security] Username matching weaknesses with allow/deny rules, see PMASA-2016-61
- issue [security] Possible to bypass logout timeout, see PMASA-2016-62
- issue [security] Full path disclosure (FPD) weaknesses, see PMASA-2016-63
- issue [security] Multiple XSS weaknesses, see PMASA-2016-64
- issue [security] Multiple denial-of-service (DOS) vulnerabilities, see PMASA-2016-65
- issue [security] Possible to bypass white-list protection for URL redirection, see PMASA-2016-66
- issue [security] BBCode injection to login page, see PMASA-2016-67
- issue [security] Denial-of-service (DOS) vulnerability in table partitioning, see PMASA-2016-68
- issue [security] Multiple SQL injection vulnerabilities, see PMASA-2016-69
- issue [security] Incorrect serialized string parsing, see PMASA-2016-70
- issue [security] CSRF token not stripped from the URL, see PMASA-2016-71
4.6.4 (2016-08-16)
- issue [security] Weaknesses with cookie encryption, see PMASA-2016-29

2
README
View File

@ -1,7 +1,7 @@
phpMyAdmin - Readme
===================
Version 4.6.5-dev
Version 4.6.5
A web interface for MySQL and MariaDB.

View File

@ -51,7 +51,7 @@ copyright = u'2012 - 2016, The phpMyAdmin devel team'
# built documents.
#
# The short X.Y version.
version = '4.6.5-dev'
version = '4.6.5'
# The full version, including alpha/beta/rc tags.
release = version

View File

@ -616,8 +616,8 @@ if ($GLOBALS['PMA_recoding_engine'] != PMA_CHARSET_NONE && isset($charset_of_fil
// Something to skip? (because timeout has passed)
if (! $error && isset($_POST['skip'])) {
$original_skip = $skip = $_POST['skip'];
while ($skip > 0) {
$original_skip = $skip = intval($_POST['skip']);
while ($skip > 0 && ! $finished) {
PMA_importGetNextChunk($skip < $read_limit ? $skip : $read_limit);
// Disable read progressivity, otherwise we eat all memory!
$read_multiply = 1;

View File

@ -389,7 +389,7 @@ PMA_printListItem(
PMA_printListItem(
__('Official Homepage'),
'li_pma_homepage',
PMA_linkURL('https://www.phpMyAdmin.net/'),
PMA_linkURL('https://www.phpmyadmin.net/'),
null,
'_blank'
);

View File

@ -625,9 +625,9 @@ AJAX.registerOnload('config.js', function () {
var tab_check_fnc = function () {
if (location.hash != prev_hash) {
prev_hash = location.hash;
if (location.hash.match(/^#tab_[a-zA-Z0-9_]+/)) {
if (prev_hash.match(/^#tab_[a-zA-Z0-9_]+$/)) {
// session ID is sometimes appended here
var hash = location.hash.substr(5).split('&')[0];
var hash = prev_hash.substr(5).split('&')[0];
if ($('#' + hash).length) {
setTab(hash);
}

View File

@ -280,15 +280,16 @@ PMA_SetUrlHash = (function (jQuery, window) {
/**
* Start initialisation
*/
if (window.location.hash.substring(0, 8) == '#PMAURL-') {
var urlhash = window.location.hash;
if (urlhash.substring(0, 8) == '#PMAURL-') {
// We have a valid hash, let's redirect the user
// to the page that it's pointing to
var colon_position = window.location.hash.indexOf(':');
var questionmark_position = window.location.hash.indexOf('?');
var colon_position = urlhash.indexOf(':');
var questionmark_position = urlhash.indexOf('?');
if (colon_position != -1 && questionmark_position != -1 && colon_position < questionmark_position) {
var hash_url = window.location.hash.substring(colon_position + 1, questionmark_position);
var hash_url = urlhash.substring(colon_position + 1, questionmark_position);
if (PMA_gotoWhitelist.indexOf(hash_url) != -1) {
window.location = window.location.hash.substring(
window.location = urlhash.substring(
colon_position + 1
);
}
@ -328,4 +329,4 @@ PMA_SetUrlHash = (function (jQuery, window) {
* Publicly exposes a reference to the otherwise private setUrlHash function
*/
return setUrlHash;
})(jQuery, window);
})(jQuery, window);

View File

@ -101,7 +101,7 @@ class Config
*/
public function checkSystem()
{
$this->set('PMA_VERSION', '4.6.5-dev');
$this->set('PMA_VERSION', '4.6.5');
/**
* @deprecated
*/

View File

@ -1940,7 +1940,10 @@ class DbQbe
// sets row count
$rows = PMA_ifSetOr($_REQUEST['rows'], 0, 'numeric');
$criteriaRowAdd = PMA_ifSetOr($_REQUEST['criteriaRowAdd'], 0, 'numeric');
$this->_criteria_row_count = max($rows + $criteriaRowAdd, 0);
$this->_criteria_row_count = min(
100,
max($rows + $criteriaRowAdd, 0)
);
return $criteriaColumnCount;
}

View File

@ -478,7 +478,7 @@ class Error extends Message
/* Probably affected by open_basedir */
if ($dest === FALSE) {
return $path;
return basename($path);
}
$Ahere = explode(

View File

@ -193,16 +193,19 @@ class ErrorHandler
$this->errors[$error->getHash()] = $error;
switch ($error->getNumber()) {
case E_USER_NOTICE:
case E_USER_WARNING:
case E_STRICT:
case E_DEPRECATED:
case E_NOTICE:
case E_WARNING:
case E_CORE_WARNING:
case E_COMPILE_WARNING:
case E_USER_ERROR:
case E_RECOVERABLE_ERROR:
/* Avoid rendering BB code in PHP errors */
$error->setBBCode(false);
break;
case E_USER_NOTICE:
case E_USER_WARNING:
case E_USER_ERROR:
// just collect the error
// display is called from outside
break;

View File

@ -112,6 +112,14 @@ class Message
*/
protected $isDisplayed = false;
/**
* Whether to use BB code when displaying.
*
* @access protected
* @var boolean
*/
protected $useBBCode = true;
/**
* Unique id
*
@ -236,6 +244,7 @@ class Message
{
$r = new Message('', $type);
$r->setMessage($message);
$r->setBBCode(false);
return $r;
}
@ -392,6 +401,18 @@ class Message
return $this->getNumber() === Message::ERROR;
}
/**
* Set whether we should use BB Code when rendering.
*
* @param boolean $useBBCode Use BB Code?
*
* @return void
*/
public function setBBCode($useBBCode)
{
$this->useBBCode = $useBBCode;
}
/**
* set raw message (overrides string)
*
@ -647,7 +668,9 @@ class Message
$message = Message::format($message, $this->getParams());
}
$message = Message::decodeBB($message);
if ($this->useBBCode) {
$message = Message::decodeBB($message);
}
foreach ($this->getAddedMessages() as $add_message) {
$message .= $add_message;

View File

@ -160,6 +160,16 @@ class SavedSearches
}
}
/* Limit amount of rows */
if (!isset($data['rows'])) {
$data['rows'] = 0;
} else {
$data['rows'] = min(
max(0, intval($data['rows'])),
100
);
}
for ($i = 0; $i <= $data['rows']; $i++) {
$data['Or' . $i] = $criterias['Or' . $i];
}

View File

@ -144,8 +144,9 @@ class Tracker
static public function getLogComment()
{
$date = date('Y-m-d H:i:s');
$user = preg_replace('/\s+/', ' ', $GLOBALS['cfg']['Server']['user']);
return "# log " . $date . " " . $GLOBALS['cfg']['Server']['user'] . "\n";
return "# log " . $date . " " . $user . "\n";
}
/**

View File

@ -72,7 +72,7 @@ class VersionInformation
CURLOPT_TIMEOUT,
$connection_timeout
);
$response = curl_exec($curl_handle);
$response = @curl_exec($curl_handle);
} else if (ini_get('allow_url_fopen')) {
$context = array(
'http' => array(
@ -81,12 +81,16 @@ class VersionInformation
)
);
$context = Util::handleContext($context);
$response = file_get_contents(
$response = @file_get_contents(
$file,
false,
stream_context_create($context)
);
}
// Check possible failure of getting data
if ($response === false) {
$response = '{}';
}
}
/* Parse response */

View File

@ -754,10 +754,17 @@ function PMA_linkURL($url)
function PMA_isAllowedDomain($url)
{
$arr = parse_url($url);
// Avoid URLs without hostname or with credentials
if (empty($arr['host']) || ! empty($arr['user']) || ! empty($arr['pass'])) {
// We need host to be set
if (! isset($arr['host']) || strlen($arr['host']) == 0) {
return false;
}
// We do not want these to be present
$blocked = array('user', 'pass', 'port');
foreach ($blocked as $part) {
if (isset($arr[$part]) && strlen($arr[$part]) != 0) {
return false;
}
}
$domain = $arr["host"];
$domainWhiteList = array(
/* Include current domain */
@ -766,6 +773,7 @@ function PMA_isAllowedDomain($url)
'wiki.phpmyadmin.net', 'www.phpmyadmin.net', 'phpmyadmin.net',
'demo.phpmyadmin.net',
'docs.phpmyadmin.net',
'demo.phpmyadmin.net',
/* mysql.com domains */
'dev.mysql.com','bugs.mysql.com',
/* mariadb domains */
@ -781,7 +789,7 @@ function PMA_isAllowedDomain($url)
/* Following are doubtful ones. */
'mysqldatabaseadministration.blogspot.com',
);
if (in_array(mb_strtolower($domain), $domainWhiteList)) {
if (in_array($domain, $domainWhiteList)) {
return true;
}
@ -1014,7 +1022,7 @@ if (! function_exists('hash_hmac')) {
/**
* Sanitizes MySQL hostname
*
* * strips p: prefix
* * strips p: prefix(es)
*
* @param string $name User given hostname
*
@ -1022,13 +1030,31 @@ if (! function_exists('hash_hmac')) {
*/
function PMA_sanitizeMySQLHost($name)
{
if (strtolower(substr($name, 0, 2)) == 'p:') {
return substr($name, 2);
while (strtolower(substr($name, 0, 2)) == 'p:') {
$name = substr($name, 2);
}
return $name;
}
/**
* Sanitizes MySQL username
*
* * strips part behind null byte
*
* @param string $name User given username
*
* @return string
*/
function PMA_sanitizeMySQLUser($name)
{
$position = strpos($name, chr(0));
if ($position !== false) {
return substr($name, 0, $position);
}
return $name;
}
/**
* Safe unserializer wrapper
*
@ -1062,7 +1088,7 @@ function PMA_safeUnserialize($data)
case 's':
/* string */
// parse sting length
$strlen = intval($data[$i + 2]);
$strlen = intval(substr($data, $i + 2));
// string start
$i = strpos($data, ':', $i + 2);
if ($i === false) {

View File

@ -18,12 +18,10 @@ use PMA\libraries\ZipFile;
*/
function PMA_shutdownDuringExport()
{
$a = error_get_last();
if ($a != null && mb_strpos($a['message'], "execution time")) {
//write in partially downloaded file for future reference of user
print_r($a);
$error = error_get_last();
if ($error != null && mb_strpos($error['message'], "execution time")) {
//set session variable to check if there was error while exporting
$_SESSION['pma_export_error'] = $a['message'];
$_SESSION['pma_export_error'] = $error['message'];
}
}

View File

@ -194,7 +194,7 @@ function PMA_ipv6MaskTest($test_range, $ip_to_test)
if ($is_single) {
$range_hex = bin2hex(inet_pton($test_range));
$result = $ip_hex === $range_hex;
$result = hash_equals($ip_hex, $range_hex);
return $result;
}
@ -321,7 +321,7 @@ function PMA_allowDeny($type)
// check for username
if (($rule_data[1] != '%') //wildcarded first
&& ($rule_data[1] != $username)
&& (! hash_equals($rule_data[1], $username))
) {
continue;
}

View File

@ -114,7 +114,7 @@ abstract class AuthenticationPlugin
} else {
$dbi_error = $GLOBALS['dbi']->getError();
if (!empty($dbi_error)) {
return PMA_sanitize($dbi_error);
return htmlspecialchars($dbi_error);
} elseif (isset($GLOBALS['errno'])) {
return '#' . $GLOBALS['errno'] . ' '
. __('Cannot log in to the MySQL server');
@ -134,4 +134,26 @@ abstract class AuthenticationPlugin
public function handlePasswordChange($password)
{
}
/**
* Store session access time in session.
*
* Tries to workaround PHP 5 session garbage collection which
* looks at the session file's last modified time
*
* @return void
*/
public function setSessionAccessTime()
{
if (isset($_REQUEST['access_time'])) {
// Ensure access_time is in range <0, LoginCookieValidity + 1>
// to avoid excessive extension of validity.
//
// Negative values can cause session expiry extension
// Too big values can cause overflow and lead to same
$_SESSION['last_access_time'] = time() - min(max(0, intval($_REQUEST['access_time'])), $GLOBALS['cfg']['LoginCookieValidity'] + 1);
} else {
$_SESSION['last_access_time'] = time();
}
}
}

View File

@ -61,13 +61,7 @@ class AuthenticationConfig extends AuthenticationPlugin
*/
public function authSetUser()
{
// try to workaround PHP 5 session garbage collection which
// looks at the session file's last modified time
if (isset($_REQUEST['access_time'])) {
$_SESSION['last_access_time'] = time() - $_REQUEST['access_time'];
} else {
$_SESSION['last_access_time'] = time();
}
$this->setSessionAccessTime();
return true;
}

View File

@ -301,7 +301,7 @@ class AuthenticationCookie extends AuthenticationPlugin
}
// The user just logged in
$GLOBALS['PHP_AUTH_USER'] = $_REQUEST['pma_username'];
$GLOBALS['PHP_AUTH_USER'] = PMA_sanitizeMySQLUser($_REQUEST['pma_username']);
$GLOBALS['PHP_AUTH_PW'] = empty($_REQUEST['pma_password'])
? ''
: $_REQUEST['pma_password'];
@ -408,14 +408,14 @@ class AuthenticationCookie extends AuthenticationPlugin
// Ensures valid authentication mode, 'only_db', bookmark database and
// table names and relation table name are used
if ($cfg['Server']['user'] != $GLOBALS['PHP_AUTH_USER']) {
if (! hash_equals($cfg['Server']['user'], $GLOBALS['PHP_AUTH_USER'])) {
foreach ($cfg['Servers'] as $idx => $current) {
if ($current['host'] == $cfg['Server']['host']
&& $current['port'] == $cfg['Server']['port']
&& $current['socket'] == $cfg['Server']['socket']
&& $current['ssl'] == $cfg['Server']['ssl']
&& $current['connect_type'] == $cfg['Server']['connect_type']
&& $current['user'] == $GLOBALS['PHP_AUTH_USER']
&& hash_equals($current['user'], $GLOBALS['PHP_AUTH_USER'])
) {
$GLOBALS['server'] = $idx;
$cfg['Server'] = $current;
@ -450,11 +450,7 @@ class AuthenticationCookie extends AuthenticationPlugin
// Avoid showing the password in phpinfo()'s output
unset($GLOBALS['PHP_AUTH_PW']);
unset($_SERVER['PHP_AUTH_PW']);
if (isset($_REQUEST['access_time'])) {
$_SESSION['last_access_time'] = time() - $_REQUEST['access_time'];
} else {
$_SESSION['last_access_time'] = time();
}
$this->setSessionAccessTime();
}
/**

View File

@ -165,10 +165,13 @@ class AuthenticationHttp extends AuthenticationPlugin
unset($usr_pass);
}
// sanitize username
$PHP_AUTH_USER = PMA_sanitizeMySQLUser($PHP_AUTH_USER);
// User logged out -> ensure the new username is not the same
$old_usr = isset($_REQUEST['old_usr']) ? $_REQUEST['old_usr'] : '';
if (!empty($old_usr)
&& (isset($PHP_AUTH_USER) && $old_usr == $PHP_AUTH_USER)
if (! empty($old_usr)
&& (isset($PHP_AUTH_USER) && hash_equals($old_usr, $PHP_AUTH_USER))
) {
$PHP_AUTH_USER = '';
// -> delete user's choices that were stored in session
@ -202,12 +205,12 @@ class AuthenticationHttp extends AuthenticationPlugin
// Ensures valid authentication mode, 'only_db', bookmark database and
// table names and relation table name are used
if ($cfg['Server']['user'] != $PHP_AUTH_USER) {
if (! hash_equals($cfg['Server']['user'], $PHP_AUTH_USER)) {
$servers_cnt = count($cfg['Servers']);
for ($i = 1; $i <= $servers_cnt; $i++) {
if (isset($cfg['Servers'][$i])
&& ($cfg['Servers'][$i]['host'] == $cfg['Server']['host']
&& $cfg['Servers'][$i]['user'] == $PHP_AUTH_USER)
&& hash_equals($cfg['Servers'][$i]['user'], $PHP_AUTH_USER))
) {
$server = $i;
$cfg['Server'] = $cfg['Servers'][$i];
@ -223,9 +226,7 @@ class AuthenticationHttp extends AuthenticationPlugin
unset($GLOBALS['PHP_AUTH_PW']);
unset($_SERVER['PHP_AUTH_PW']);
// try to workaround PHP 5 session garbage collection which
// looks at the session file's last modified time
$_SESSION['last_access_time'] = time();
$this->setSessionAccessTime();
return true;
}

View File

@ -14,17 +14,31 @@ if (!isset($partitionDetails)) {
// Extract some partitioning and subpartitioning parameters from the request
$partitionParams = array(
'partition_by', 'partition_expr', 'partition_count',
'subpartition_by', 'subpartition_expr', 'subpartition_count'
'partition_by', 'partition_expr',
'subpartition_by', 'subpartition_expr',
);
foreach ($partitionParams as $partitionParam) {
$partitionDetails[$partitionParam] = isset($_REQUEST[$partitionParam])
? $_REQUEST[$partitionParam] : '';
}
if (PMA_isValid($_REQUEST['partition_count'], 'numeric')) {
// MySQL's limit is 8192, so do not allow more
$partition_count = min(intval($_REQUEST['partition_count']), 8192);
} else {
$partition_count = 0;
}
$partitionDetails['partition_count'] = $partition_count;
if (PMA_isValid($_REQUEST['subpartition_count'], 'numeric')) {
// MySQL's limit is 8192, so do not allow more
$subpartition_count = min(intval($_REQUEST['subpartition_count']), 8192);
} else {
$subpartition_count = 0;
}
$partitionDetails['subpartition_count'] = $subpartition_count;
// Only LIST and RANGE type parameters allow subpartitioning
$partitionDetails['can_have_subpartitions'] = isset($_REQUEST['partition_count'])
&& $_REQUEST['partition_count'] > 1
$partitionDetails['can_have_subpartitions'] = $partition_count > 1
&& isset($_REQUEST['partition_by'])
&& ($_REQUEST['partition_by'] == 'RANGE'
|| $_REQUEST['partition_by'] == 'RANGE COLUMNS'
@ -38,18 +52,17 @@ if (!isset($partitionDetails)) {
|| $_REQUEST['partition_by'] == 'LIST'
|| $_REQUEST['partition_by'] == 'LIST COLUMNS');
if (PMA_isValid($_REQUEST['partition_count'], 'numeric')
&& $_REQUEST['partition_count'] > 1
) { // Has partitions
// Has partitions
if ($partition_count > 1) {
$partitions = isset($_REQUEST['partitions'])
? $_REQUEST['partitions']
: array();
// Remove details of the additional partitions
// when number of partitions have been reduced
array_splice($partitions, $_REQUEST['partition_count']);
array_splice($partitions, $partition_count);
for ($i = 0; $i < $_REQUEST['partition_count']; $i++) {
for ($i = 0; $i < $partition_count; $i++) {
if (! isset($partitions[$i])) { // Newly added partition
$partitions[$i] = array(
'name' => 'p' . $i,
@ -85,11 +98,10 @@ if (!isset($partitionDetails)) {
$partition['node_group'] = '';
}
if (PMA_isValid($_REQUEST['subpartition_count'], 'numeric')
&& $_REQUEST['subpartition_count'] > 1
if ($subpartition_count > 1
&& $partitionDetails['can_have_subpartitions'] == true
) { // Has subpartitions
$partition['subpartition_count'] = $_REQUEST['subpartition_count'];
$partition['subpartition_count'] = $subpartition_count;
if (! isset($partition['subpartitions'])) {
$partition['subpartitions'] = array();
@ -98,9 +110,9 @@ if (!isset($partitionDetails)) {
// Remove details of the additional subpartitions
// when number of subpartitions have been reduced
array_splice($subpartitions, $_REQUEST['subpartition_count']);
array_splice($subpartitions, $subpartition_count);
for ($j = 0; $j < $_REQUEST['subpartition_count']; $j++) {
for ($j = 0; $j < $subpartition_count; $j++) {
if (! isset($subpartitions[$j])) { // Newly added subpartition
$subpartitions[$j] = array(
'name' => $partition['name'] . '_s' . $j,

View File

@ -1186,14 +1186,16 @@ function PMA_exportAsFileDownload($entries)
{
@ini_set('url_rewriter.tags', '');
// Replace all multiple whitespaces by a single space
$table = htmlspecialchars(preg_replace('/\s+/', ' ', $_REQUEST['table']));
$dump = "# " . sprintf(
__('Tracking report for table `%s`'), htmlspecialchars($_REQUEST['table'])
__('Tracking report for table `%s`'), $table
)
. "\n" . "# " . date('Y-m-d H:i:s') . "\n";
foreach ($entries as $entry) {
$dump .= $entry['statement'];
}
$filename = 'log_' . htmlspecialchars($_REQUEST['table']) . '.sql';
$filename = 'log_' . $table . '.sql';
PMA\libraries\Response::getInstance()->disable();
PMA_downloadHeader(
$filename,

View File

@ -173,7 +173,7 @@ if (isset($_POST['submit_export'])
$result = PMA_saveUserprefs($cf->getConfigArray());
if ($result === true) {
if ($return_url) {
$query = explode('&', parse_url($return_url, PHP_URL_QUERY));
$query = PMA\libraries\Util::splitURLQuery($return_url);
$return_url = parse_url($return_url, PHP_URL_PATH);
foreach ($query as $q) {

View File

@ -102,7 +102,7 @@ class ErrorTest extends PMATestCase
return array(
array('./ChangeLog', './ChangeLog'),
array(__FILE__, './test/classes/ErrorTest.php'),
array('./NONEXISTING', './NONEXISTING'),
array('./NONEXISTING', 'NONEXISTING'),
);
}

View File

@ -110,6 +110,7 @@ class MessageTest extends PMATestCase
{
$this->object = new PMA\libraries\Message('', PMA\libraries\Message::ERROR);
$this->object->setMessage('test<&>');
$this->object->setBBCode(false);
$this->assertEquals($this->object, PMA\libraries\Message::rawError('test<&>'));
}
@ -123,6 +124,7 @@ class MessageTest extends PMATestCase
{
$this->object = new PMA\libraries\Message('', PMA\libraries\Message::NOTICE);
$this->object->setMessage('test<&>');
$this->object->setBBCode(false);
$this->assertEquals($this->object, PMA\libraries\Message::rawNotice('test<&>'));
}
@ -136,6 +138,7 @@ class MessageTest extends PMATestCase
{
$this->object = new PMA\libraries\Message('', PMA\libraries\Message::SUCCESS);
$this->object->setMessage('test<&>');
$this->object->setBBCode(false);
$this->assertEquals($this->object, PMA\libraries\Message::rawSuccess('test<&>'));
}

View File

@ -43,6 +43,9 @@ class PMA_isAllowedDomain_test extends PHPUnit_Framework_TestCase
array('https://www.phpmyadmin.net/', true),
array('http://duckduckgo.com\\@github.com', false),
array('https://github.com/', true),
array('https://github.com:123/', false),
array('https://user:pass@github.com:123/', false),
array('https://user:pass@github.com/', false),
array('https://server.local/', true),
array('./relative/', false),
);

View File

@ -44,6 +44,7 @@ class PMA_safeUnserialize_test extends PHPUnit_Framework_TestCase
array('b:0;', false),
array('O:1:"a":1:{s:5:"value";s:3:"100";}', null),
array('O:8:"stdClass":1:{s:5:"field";O:8:"stdClass":0:{}}', null),
array('a:2:{i:0;s:90:"1234567890;a345678901234567890123456789012345678901234567890123456789012345678901234567890";i:1;O:8:"stdClass":0:{}}', null),
array(serialize(array(1, 2, 3)), array(1, 2, 3)),
array(serialize('string""'), 'string""'),
array(serialize(array('foo' => 'bar')), array('foo' => 'bar')),

View File

@ -40,6 +40,7 @@ class PMA_sanitizeMySQLHost_test extends PHPUnit_Framework_TestCase
{
return array(
array('p:foo.bar', 'foo.bar'),
array('p:p:foo.bar', 'foo.bar'),
array('bar.baz', 'bar.baz'),
array('P:example.com', 'example.com'),
);