Gergő Tisza has uploaded a new change for review. (
https://gerrit.wikimedia.org/r/390938 )
Change subject: Add string length limits
......................................................................
Add string length limits
Adds two new ApiBase::getAllowedParams() keys:
PARAM_MAX_BYTES and PARAM_MAX_CHARS, to set a length
limit for a (string-like) parameter.
This makes it easy to document and enforce database
field length limits (where relying on the database
would either result in unfriendly error messages or
silent truncation, depending on DB settings) and
also exposes them in structured form so API clients
can verify the length without doing roundtrips.
Change-Id: I2e784972d7e11cad79fdef887bbcde297dbd9ce0
---
M includes/api/ApiBase.php
M includes/api/ApiHelp.php
M includes/api/ApiParamInfo.php
M includes/api/i18n/en.json
M includes/api/i18n/qqq.json
5 files changed, 58 insertions(+), 3 deletions(-)
git pull ssh://gerrit.wikimedia.org:29418/mediawiki/core
refs/changes/38/390938/1
diff --git a/includes/api/ApiBase.php b/includes/api/ApiBase.php
index 80aeff5..5f6583a 100644
--- a/includes/api/ApiBase.php
+++ b/includes/api/ApiBase.php
@@ -217,6 +217,18 @@
*/
const PARAM_ISMULTI_LIMIT2 = 22;
+ /**
+ * (integer) Maximum length of a string in bytes.
+ * @since 1.31
+ */
+ const PARAM_MAX_BYTES = 23;
+
+ /**
+ * (integer) Maximum length of a string in characters.
+ * @since 1.31
+ */
+ const PARAM_MAX_CHARS = 24;
+
/**@}*/
const ALL_DEFAULT_STRING = '*';
@@ -1173,9 +1185,9 @@
);
}
- // More validation only when choices were not given
- // choices were validated in parseMultiValue()
if ( isset( $value ) ) {
+ // More validation only when choices were not given
+ // choices were validated in parseMultiValue()
if ( !is_array( $type ) ) {
switch ( $type ) {
case 'NULL': // nothing to do
@@ -1285,6 +1297,23 @@
$value = array_unique( $value );
}
+ if ( in_array( $type, [ 'NULL', 'string', 'text',
'password' ], true ) ) {
+ foreach ( (array)$value as $val ) {
+ if ( isset(
$paramSettings[self::PARAM_MAX_BYTES] ) ) {
+ if ( strlen( $val ) >
$paramSettings[self::PARAM_MAX_BYTES] ) {
+ $this->dieWithError( [
'apierror-maxbytes', $encParamName,
+
$paramSettings[self::PARAM_MAX_BYTES] ] );
+ }
+ }
+ if ( isset(
$paramSettings[self::PARAM_MAX_CHARS] ) ) {
+ if ( mb_strlen( $val, 'UTF-8' )
> $paramSettings[self::PARAM_MAX_CHARS] ) {
+ $this->dieWithError( [
'apierror-maxchars', $encParamName,
+
$paramSettings[self::PARAM_MAX_CHARS] ] );
+ }
+ }
+ }
+ }
+
// Set a warning if a deprecated parameter has been
passed
if ( $deprecated && $value !== false ) {
$feature = $encParamName;
diff --git a/includes/api/ApiHelp.php b/includes/api/ApiHelp.php
index 318555a..b0ffdb2 100644
--- a/includes/api/ApiHelp.php
+++ b/includes/api/ApiHelp.php
@@ -528,6 +528,17 @@
->parse();
$hintPipeSeparated =
false;
} else {
+ if ( in_array( $type, [
null, 'string', 'text', 'password' ], true ) ) {
+ if ( isset(
$settings[self::PARAM_MAX_BYTES] ) ) {
+ $info[]
= $context->msg( 'api-help-param-maxbytes' )
+
->numParams( $settings[self::PARAM_MAX_BYTES] );
+ }
+ if ( isset(
$settings[self::PARAM_MAX_CHARS] ) ) {
+ $info[]
= $context->msg( 'api-help-param-maxchars' )
+
->numParams( $settings[self::PARAM_MAX_CHARS] );
+ }
+ }
+
switch ( $type ) {
case
'submodule':
$groups[] = $name;
@@ -668,7 +679,6 @@
$info[] =
$msg->params( $multi ? 2 : 1 )->parse();
}
}
-
if ( $multi ) {
$extra = [];
$lowcount = !empty(
$settings[ApiBase::PARAM_ISMULTI_LIMIT1] )
diff --git a/includes/api/ApiParamInfo.php b/includes/api/ApiParamInfo.php
index 2fa20a9..674698a 100644
--- a/includes/api/ApiParamInfo.php
+++ b/includes/api/ApiParamInfo.php
@@ -471,6 +471,14 @@
if ( !empty( $settings[ApiBase::PARAM_RANGE_ENFORCE] )
) {
$item['enforcerange'] = true;
}
+ if ( in_array( $item['type'], [ null, 'string', 'text',
'password' ], true ) ) {
+ if ( isset( $settings[self::PARAM_MAX_BYTES] )
) {
+ $item['maxbytes'] =
$settings[self::PARAM_MAX_BYTES];
+ }
+ if ( isset( $settings[self::PARAM_MAX_CHARS] )
) {
+ $item['maxchars'] =
$settings[self::PARAM_MAX_CHARS];
+ }
+ }
if ( !empty(
$settings[ApiBase::PARAM_DEPRECATED_VALUES] ) ) {
$deprecatedValues = array_keys(
$settings[ApiBase::PARAM_DEPRECATED_VALUES] );
if ( is_array( $item['type'] ) ) {
diff --git a/includes/api/i18n/en.json b/includes/api/i18n/en.json
index dbd5451..85f17de 100644
--- a/includes/api/i18n/en.json
+++ b/includes/api/i18n/en.json
@@ -1605,6 +1605,8 @@
"api-help-param-direction": "In which direction to
enumerate:\n;newer:List oldest first. Note: $1start has to be before
$1end.\n;older:List newest first (default). Note: $1start has to be later than
$1end.",
"api-help-param-continue": "When more results are available, use this
to continue.",
"api-help-param-no-description": "<span class=\"apihelp-empty\">(no
description)</span>",
+ "api-help-param-maxbytes": "Cannot be longer than $1
{{PLURAL:$1|byte|bytes}}.",
+ "api-help-param-maxchars": "Cannot be longer than $1
{{PLURAL:$1|character|characters}}.",
"api-help-examples": "{{PLURAL:$1|Example|Examples}}:",
"api-help-permissions": "{{PLURAL:$1|Permission|Permissions}}:",
"api-help-permissions-granted-to": "{{PLURAL:$1|Granted to}}: $2",
@@ -1710,6 +1712,8 @@
"apierror-invalidurlparam": "Invalid value for <var>$1urlparam</var>
(<kbd>$2=$3</kbd>).",
"apierror-invaliduser": "Invalid username \"$1\".",
"apierror-invaliduserid": "User ID <var>$1</var> is not valid.",
+ "apierror-maxbytes": "Parameter <var>$1</var> cannot be longer than $2
{{PLURAL:$2|byte|bytes}}",
+ "apierror-maxchars": "Parameter <var>$1</var> cannot be longer than $2
{{PLURAL:$2|character|characters}}",
"apierror-maxlag-generic": "Waiting for a database server: $1
{{PLURAL:$1|second|seconds}} lagged.",
"apierror-maxlag": "Waiting for $2: $1 {{PLURAL:$1|second|seconds}}
lagged.",
"apierror-mimesearchdisabled": "MIME search is disabled in Miser Mode.",
diff --git a/includes/api/i18n/qqq.json b/includes/api/i18n/qqq.json
index 6aaaac7..3bdf7c6 100644
--- a/includes/api/i18n/qqq.json
+++ b/includes/api/i18n/qqq.json
@@ -1496,6 +1496,8 @@
"api-help-param-direction": "{{doc-apihelp-param|description=any
standard \"dir\" parameter|noseealso=1}}",
"api-help-param-continue": "{{doc-apihelp-param|description=any
standard \"continue\" parameter, or other parameter with the same
semantics|noseealso=1}}",
"api-help-param-no-description": "Displayed on API parameters that lack
any description",
+ "api-help-param-maxbytes": "Used to display the maximum allowed length
of a parameter, in bytes.",
+ "api-help-param-maxchars": "Used to display the maximum allowed length
of a parameter, in characters.",
"api-help-examples": "Label for the API help examples
section\n\nParameters:\n* $1 - Number of examples to be
displayed\n{{Identical|Example}}",
"api-help-permissions": "Label for the \"permissions\" section in the
main module's help output.\n\nParameters:\n* $1 - Number of permissions
displayed\n{{Identical|Permission}}",
"api-help-permissions-granted-to": "Used to introduce the list of
groups each permission is assigned to.\n\nParameters:\n* $1 - Number of
groups\n* $2 - List of group names, comma-separated",
@@ -1599,6 +1601,8 @@
"apierror-invalidurlparam": "{{doc-apierror}}\n\nParameters:\n* $1 -
Module parameter prefix, e.g. \"bl\".\n* $2 - Key\n* $3 - Value.",
"apierror-invaliduser": "{{doc-apierror}}\n\nParameters:\n* $1 - User
name that is invalid.",
"apierror-invaliduserid": "{{doc-apierror}}",
+ "apierror-maxbytes": "{{doc-apierror}}\n\nParameters:\n* $1 - Parameter
name.\n* $2 - Maximum allowed bytes.",
+ "apierror-maxchars": "{{doc-apierror}}\n\nParameters:\n* $1 - Parameter
name.\n* $2 - Maximum allowed characters.",
"apierror-maxlag-generic": "{{doc-apierror}}\n\nParameters:\n* $1 -
Database is lag in seconds.",
"apierror-maxlag": "{{doc-apierror}}\n\nParameters:\n* $1 - Database
lag in seconds.\n* $2 - Database server that is lagged.",
"apierror-mimesearchdisabled": "{{doc-apierror}}",
--
To view, visit https://gerrit.wikimedia.org/r/390938
To unsubscribe, visit https://gerrit.wikimedia.org/r/settings
Gerrit-MessageType: newchange
Gerrit-Change-Id: I2e784972d7e11cad79fdef887bbcde297dbd9ce0
Gerrit-PatchSet: 1
Gerrit-Project: mediawiki/core
Gerrit-Branch: master
Gerrit-Owner: Gergő Tisza <[email protected]>
_______________________________________________
MediaWiki-commits mailing list
[email protected]
https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits