Merge "Add string length limits"
[lhc/web/wiklou.git] / includes / api / ApiBase.php
index 9dd670a..83d2ae9 100644 (file)
@@ -217,6 +217,18 @@ abstract class ApiBase extends ContextSource {
         */
        const PARAM_ISMULTI_LIMIT2 = 22;
 
+       /**
+        * (integer) Maximum length of a string in bytes (in UTF-8 encoding).
+        * @since 1.31
+        */
+       const PARAM_MAX_BYTES = 23;
+
+       /**
+        * (integer) Maximum length of a string in characters (unicode codepoints).
+        * @since 1.31
+        */
+       const PARAM_MAX_CHARS = 24;
+
        /**@}*/
 
        const ALL_DEFAULT_STRING = '*';
@@ -1069,10 +1081,10 @@ abstract class ApiBase extends ContextSource {
                        } else {
                                $type = 'NULL'; // allow everything
                        }
+               }
 
-                       if ( $type == 'password' || !empty( $paramSettings[self::PARAM_SENSITIVE] ) ) {
-                               $this->getMain()->markParamsSensitive( $encParamName );
-                       }
+               if ( $type == 'password' || !empty( $paramSettings[self::PARAM_SENSITIVE] ) ) {
+                       $this->getMain()->markParamsSensitive( $encParamName );
                }
 
                if ( $type == 'boolean' ) {
@@ -1173,9 +1185,9 @@ abstract class ApiBase extends ContextSource {
                        );
                }
 
-               // 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 @@ abstract class ApiBase extends ContextSource {
                                $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] )
+                                               && strlen( $val ) > $paramSettings[self::PARAM_MAX_BYTES]
+                                       ) {
+                                               $this->dieWithError( [ 'apierror-maxbytes', $encParamName,
+                                                       $paramSettings[self::PARAM_MAX_BYTES] ] );
+                                       }
+                                       if ( isset( $paramSettings[self::PARAM_MAX_CHARS] )
+                                               && 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;
@@ -1385,7 +1414,7 @@ abstract class ApiBase extends ContextSource {
                $limit2 = $limit2 ?: self::LIMIT_SML2;
 
                // This is a bit awkward, but we want to avoid calling canApiHighLimits()
-               // because it loads the user object
+               // because it unstubs $wgUser
                $valuesList = $this->explodeMultiValue( $value, $limit2 + 1 );
                $sizeLimit = count( $valuesList ) > $limit1 && $this->mMainModule->canApiHighLimits()
                        ? $limit2