Improve test coverage for ApiBase.php
One bug fixed: a timestamp of '00' or similar would get interpreted as 'now' by mistake instead of Unix timestamp 0, without throwing the warning for using 0 instead of 'now'. This is because it called wfTimestamp() once to parse the input date, got a Unix timestamp of 0 back, and then tried passing that 0 back to wfTimestamp again to reformat as a wiki date, but it got reinterpreted as 'now'. Also fixed parameters with type "user" to validate usernames more correctly. This might be risky, though, if I missed any valid usernames, or if API clients were for some reason relying on passing in invalid usernames. If we don't actually want to do this, we should add a comment explaining why we're allowing any title without a fragment rather than validating properly. Still lots more work to do here. Change-Id: I56b4290263df8698efdbddda71a7eabd9e303abc
This commit is contained in:
parent
e4277f170b
commit
d3da5e08d3
6 changed files with 1116 additions and 53 deletions
|
|
@ -432,7 +432,7 @@ class WebRequest {
|
|||
* selected by a drop-down menu). For freeform input, see getText().
|
||||
*
|
||||
* @param string $name
|
||||
* @param string $default Optional default (or null)
|
||||
* @param string|null $default Optional default (or null)
|
||||
* @return string|null
|
||||
*/
|
||||
public function getVal( $name, $default = null ) {
|
||||
|
|
|
|||
|
|
@ -1129,8 +1129,8 @@ abstract class ApiBase extends ContextSource {
|
|||
) {
|
||||
$type = array_merge( $type, $paramSettings[self::PARAM_EXTRA_NAMESPACES] );
|
||||
}
|
||||
// By default, namespace parameters allow ALL_DEFAULT_STRING to be used to specify
|
||||
// all namespaces.
|
||||
// Namespace parameters allow ALL_DEFAULT_STRING to be used to
|
||||
// specify all namespaces irrespective of PARAM_ALL.
|
||||
$allowAll = true;
|
||||
}
|
||||
if ( isset( $value ) && $type == 'submodule' ) {
|
||||
|
|
@ -1436,22 +1436,15 @@ abstract class ApiBase extends ContextSource {
|
|||
return $value;
|
||||
}
|
||||
|
||||
if ( is_array( $allowedValues ) ) {
|
||||
$values = array_map( function ( $v ) {
|
||||
return '<kbd>' . wfEscapeWikiText( $v ) . '</kbd>';
|
||||
}, $allowedValues );
|
||||
$this->dieWithError( [
|
||||
'apierror-multival-only-one-of',
|
||||
$valueName,
|
||||
Message::listParam( $values ),
|
||||
count( $values ),
|
||||
], "multival_$valueName" );
|
||||
} else {
|
||||
$this->dieWithError( [
|
||||
'apierror-multival-only-one',
|
||||
$valueName,
|
||||
], "multival_$valueName" );
|
||||
}
|
||||
$values = array_map( function ( $v ) {
|
||||
return '<kbd>' . wfEscapeWikiText( $v ) . '</kbd>';
|
||||
}, $allowedValues );
|
||||
$this->dieWithError( [
|
||||
'apierror-multival-only-one-of',
|
||||
$valueName,
|
||||
Message::listParam( $values ),
|
||||
count( $values ),
|
||||
], "multival_$valueName" );
|
||||
}
|
||||
|
||||
if ( is_array( $allowedValues ) ) {
|
||||
|
|
@ -1537,7 +1530,7 @@ abstract class ApiBase extends ContextSource {
|
|||
}
|
||||
|
||||
/**
|
||||
* Validate and normalize of parameters of type 'timestamp'
|
||||
* Validate and normalize parameters of type 'timestamp'
|
||||
* @param string $value Parameter value
|
||||
* @param string $encParamName Parameter name
|
||||
* @return string Validated and normalized parameter
|
||||
|
|
@ -1559,15 +1552,15 @@ abstract class ApiBase extends ContextSource {
|
|||
return wfTimestamp( TS_MW );
|
||||
}
|
||||
|
||||
$unixTimestamp = wfTimestamp( TS_UNIX, $value );
|
||||
if ( $unixTimestamp === false ) {
|
||||
$timestamp = wfTimestamp( TS_MW, $value );
|
||||
if ( $timestamp === false ) {
|
||||
$this->dieWithError(
|
||||
[ 'apierror-badtimestamp', $encParamName, wfEscapeWikiText( $value ) ],
|
||||
"badtimestamp_{$encParamName}"
|
||||
);
|
||||
}
|
||||
|
||||
return wfTimestamp( TS_MW, $unixTimestamp );
|
||||
return $timestamp;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -1609,7 +1602,7 @@ abstract class ApiBase extends ContextSource {
|
|||
}
|
||||
|
||||
/**
|
||||
* Validate and normalize of parameters of type 'user'
|
||||
* Validate and normalize parameters of type 'user'
|
||||
* @param string $value Parameter value
|
||||
* @param string $encParamName Parameter name
|
||||
* @return string Validated and normalized parameter
|
||||
|
|
@ -1619,15 +1612,32 @@ abstract class ApiBase extends ContextSource {
|
|||
return $value;
|
||||
}
|
||||
|
||||
$title = Title::makeTitleSafe( NS_USER, $value );
|
||||
if ( $title === null || $title->hasFragment() ) {
|
||||
$titleObj = Title::makeTitleSafe( NS_USER, $value );
|
||||
|
||||
if ( $titleObj ) {
|
||||
$value = $titleObj->getText();
|
||||
}
|
||||
|
||||
if (
|
||||
!User::isValidUserName( $value ) &&
|
||||
// We allow ranges as well, for blocks.
|
||||
!IP::isIPAddress( $value ) &&
|
||||
// See comment for User::isIP. We don't just call that function
|
||||
// here because it also returns true for things like
|
||||
// 300.300.300.300 that are neither valid usernames nor valid IP
|
||||
// addresses.
|
||||
!preg_match(
|
||||
'/^' . RE_IP_BYTE . '\.' . RE_IP_BYTE . '\.' . RE_IP_BYTE . '\.xxx$/',
|
||||
$value
|
||||
)
|
||||
) {
|
||||
$this->dieWithError(
|
||||
[ 'apierror-baduser', $encParamName, wfEscapeWikiText( $value ) ],
|
||||
"baduser_{$encParamName}"
|
||||
);
|
||||
}
|
||||
|
||||
return $title->getText();
|
||||
return $value;
|
||||
}
|
||||
|
||||
/**@}*/
|
||||
|
|
|
|||
|
|
@ -1720,8 +1720,8 @@ class ApiMain extends ApiBase {
|
|||
/**
|
||||
* Get a request value, and register the fact that it was used, for logging.
|
||||
* @param string $name
|
||||
* @param mixed $default
|
||||
* @return mixed
|
||||
* @param string|null $default
|
||||
* @return string|null
|
||||
*/
|
||||
public function getVal( $name, $default = null ) {
|
||||
$this->mParamsUsed[$name] = true;
|
||||
|
|
|
|||
|
|
@ -1736,7 +1736,6 @@
|
|||
"apierror-missingtitle-byname": "The page $1 doesn't exist.",
|
||||
"apierror-moduledisabled": "The <kbd>$1</kbd> module has been disabled.",
|
||||
"apierror-multival-only-one-of": "{{PLURAL:$3|Only|Only one of}} $2 is allowed for parameter <var>$1</var>.",
|
||||
"apierror-multival-only-one": "Only one value is allowed for parameter <var>$1</var>.",
|
||||
"apierror-multpages": "<var>$1</var> may only be used with a single page.",
|
||||
"apierror-mustbeloggedin-changeauth": "You must be logged in to change authentication data.",
|
||||
"apierror-mustbeloggedin-generic": "You must be logged in.",
|
||||
|
|
|
|||
|
|
@ -1625,7 +1625,6 @@
|
|||
"apierror-missingtitle-byname": "{{doc-apierror}}",
|
||||
"apierror-moduledisabled": "{{doc-apierror}}\n\nParameters:\n* $1 - Name of the module.",
|
||||
"apierror-multival-only-one-of": "{{doc-apierror}}\n\nParameters:\n* $1 - Parameter name.\n* $2 - Possible values for the parameter.\n* $3 - Number of values.",
|
||||
"apierror-multival-only-one": "{{doc-apierror}}\n\nParameters:\n* $1 - Parameter name.",
|
||||
"apierror-multpages": "{{doc-apierror}}\n\nParameters:\n* $1 - Parameter name",
|
||||
"apierror-mustbeloggedin-changeauth": "{{doc-apierror}}",
|
||||
"apierror-mustbeloggedin-generic": "{{doc-apierror}}",
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
Loading…
Reference in a new issue