$type = $this->getModuleManager()->getNames( $paramName );
}
}
+
+ $request = $this->getMain()->getRequest();
+ $rawValue = $request->getRawVal( $encParamName );
+ if ( $rawValue === null ) {
+ $rawValue = $default;
+ }
+
+ // Preserve U+001F for self::parseMultiValue(), or error out if that won't be called
+ if ( isset( $value ) && substr( $rawValue, 0, 1 ) === "\x1f" ) {
+ if ( $multi ) {
+ // This loses the potential $wgContLang->checkTitleEncoding() transformation
+ // done by WebRequest for $_GET. Let's call that a feature.
+ $value = join( "\x1f", $request->normalizeUnicode( explode( "\x1f", $rawValue ) ) );
+ } else {
+ $this->dieUsage(
+ "U+001F multi-value separation may only be used for multi-valued parameters.",
+ 'badvalue_notmultivalue'
+ );
+ }
+ }
+
+ // Check for NFC normalization, and warn
+ if ( $rawValue !== $value ) {
+ $this->handleParamNormalization( $paramName, $value, $rawValue );
+ }
}
if ( isset( $value ) && ( $multi || is_array( $type ) ) ) {
return $value;
}
+ /**
+ * Handle when a parameter was Unicode-normalized
+ * @since 1.28
+ * @param string $paramName Unprefixed parameter name
+ * @param string $value Input that will be used.
+ * @param string $rawValue Input before normalization.
+ */
+ protected function handleParamNormalization( $paramName, $value, $rawValue ) {
+ $encParamName = $this->encodeParamName( $paramName );
+ $this->setWarning(
+ "The value passed for '$encParamName' contains invalid or non-normalized data. "
+ . 'Textual data should be valid, NFC-normalized Unicode without '
+ . 'C0 control characters other than HT (\\t), LF (\\n), and CR (\\r).'
+ );
+ }
+
+ /**
+ * Split a multi-valued parameter string, like explode()
+ * @since 1.28
+ * @param string $value
+ * @param int $limit
+ * @return string[]
+ */
+ protected function explodeMultiValue( $value, $limit ) {
+ if ( substr( $value, 0, 1 ) === "\x1f" ) {
+ $sep = "\x1f";
+ $value = substr( $value, 1 );
+ } else {
+ $sep = '|';
+ }
+
+ return explode( $sep, $value, $limit );
+ }
+
/**
* Return an array of values that were given in a 'a|b|c' notation,
* after it optionally validates them against the list allowed values.
* @return string|string[] (allowMultiple ? an_array_of_values : a_single_value)
*/
protected function parseMultiValue( $valueName, $value, $allowMultiple, $allowedValues ) {
- if ( trim( $value ) === '' && $allowMultiple ) {
+ if ( ( trim( $value ) === '' || trim( $value ) === "\x1f" ) && $allowMultiple ) {
return [];
}
// This is a bit awkward, but we want to avoid calling canApiHighLimits()
// because it unstubs $wgUser
- $valuesList = explode( '|', $value, self::LIMIT_SML2 + 1 );
+ $valuesList = $this->explodeMultiValue( $value, self::LIMIT_SML2 + 1 );
$sizeLimit = count( $valuesList ) > self::LIMIT_SML1 && $this->mMainModule->canApiHighLimits()
? self::LIMIT_SML2
: self::LIMIT_SML1;
if ( self::truncateArray( $valuesList, $sizeLimit ) ) {
+ $this->logFeatureUsage( "too-many-$valueName-for-{$this->getModulePath()}" );
$this->setWarning( "Too many values supplied for parameter '$valueName': " .
"the limit is $sizeLimit" );
}