mirror of
https://gerrit.wikimedia.org/r/mediawiki/extensions/VisualEditor
synced 2024-11-15 10:35:48 +00:00
Clean up incorrect use of regular expressions in CategoryInputWidget
getLookupMenuItemsFromData() constructed a regex from user input without escaping. I don't *think* there are any injection vulnerabilities here but at the very least it triggers exceptions when the input is, say, a backslash. Instead, use .lastIndexOf() which allows us to efficiently check whether a string starts with a certain prefix. getLookupCacheItemFromData() was stripping out the Category: prefix using a regex that hardcoded Category: (so failed to detect localized prefixes) and used global replacement, which meant that strings with multiple occurrences of 'Category:' were handled incorrectly. Instead, use mw.Title to strip the prefix. Also move away from .map() because we may need to drop a result if it doesn't pass mw.Title validation. this.categoryPrefix still has a few legitimate uses left, so keep it around but set it to the localized namespace prefix rather than Category: Change-Id: I6547f9df2e94fe81f6aefb9286e547425137344b
This commit is contained in:
parent
a61adfea45
commit
514039b2ba
|
@ -33,7 +33,7 @@ ve.ui.MWCategoryInputWidget = function VeUiMWCategoryInputWidget( categoryWidget
|
||||||
// Properties
|
// Properties
|
||||||
this.categoryWidget = categoryWidget;
|
this.categoryWidget = categoryWidget;
|
||||||
this.forceCapitalization = mw.config.get( 'wgCaseSensitiveNamespaces' ).indexOf( 14 ) === -1;
|
this.forceCapitalization = mw.config.get( 'wgCaseSensitiveNamespaces' ).indexOf( 14 ) === -1;
|
||||||
this.categoryPrefix = 'Category:';
|
this.categoryPrefix = mw.config.get( 'wgFormattedNamespaces' )['14'] + ':';
|
||||||
|
|
||||||
// Initialization
|
// Initialization
|
||||||
this.$.addClass( 've-ui-mwCategoryInputWidget' );
|
this.$.addClass( 've-ui-mwCategoryInputWidget' );
|
||||||
|
@ -74,11 +74,17 @@ ve.ui.MWCategoryInputWidget.prototype.getLookupRequest = function () {
|
||||||
* @param {Mixed} data Response from server
|
* @param {Mixed} data Response from server
|
||||||
*/
|
*/
|
||||||
ve.ui.MWCategoryInputWidget.prototype.getLookupCacheItemFromData = function ( data ) {
|
ve.ui.MWCategoryInputWidget.prototype.getLookupCacheItemFromData = function ( data ) {
|
||||||
return ve.isArray( data ) && data.length ?
|
var i, len, title, result = [];
|
||||||
data[1].map( ve.bind( function ( item ) {
|
if ( ve.isArray( data ) && data.length ) {
|
||||||
return item.replace( new RegExp( this.categoryPrefix, 'gi' ), '' );
|
for ( i = 0, len = data[1].length; i < len; i++ ) {
|
||||||
}, this ) ) :
|
try {
|
||||||
[];
|
title = new mw.Title( data[1][i] );
|
||||||
|
result.push( title.getNameText() );
|
||||||
|
} catch ( e ) { }
|
||||||
|
// If the received title isn't valid, just ignore it
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return result;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -97,13 +103,13 @@ ve.ui.MWCategoryInputWidget.prototype.getLookupMenuItemsFromData = function ( da
|
||||||
menu$$ = this.lookupMenu.$$,
|
menu$$ = this.lookupMenu.$$,
|
||||||
category = this.getCategoryItemFromValue( this.value ),
|
category = this.getCategoryItemFromValue( this.value ),
|
||||||
existingCategories = this.categoryWidget.getCategories(),
|
existingCategories = this.categoryWidget.getCategories(),
|
||||||
matchingCategories = data || [],
|
matchingCategories = data || [];
|
||||||
pattern = new RegExp( '^' + category.value );
|
|
||||||
|
|
||||||
// Existing categories
|
// Existing categories
|
||||||
for ( i = 0, len = existingCategories.length; i < len; i++ ) {
|
for ( i = 0, len = existingCategories.length; i < len; i++ ) {
|
||||||
item = existingCategories[i];
|
item = existingCategories[i];
|
||||||
if ( item.match( pattern ) ) {
|
// Verify that item starts with category.value
|
||||||
|
if ( item.lastIndexOf( category.value, 0 ) === 0 ) {
|
||||||
if ( item === category.value ) {
|
if ( item === category.value ) {
|
||||||
exactMatch = true;
|
exactMatch = true;
|
||||||
}
|
}
|
||||||
|
@ -115,7 +121,7 @@ ve.ui.MWCategoryInputWidget.prototype.getLookupMenuItemsFromData = function ( da
|
||||||
item = matchingCategories[i];
|
item = matchingCategories[i];
|
||||||
if (
|
if (
|
||||||
existingCategoryItems.indexOf( item ) === -1 &&
|
existingCategoryItems.indexOf( item ) === -1 &&
|
||||||
item.match( pattern )
|
item.lastIndexOf( category.value, 0 ) === 0
|
||||||
) {
|
) {
|
||||||
if ( item === category.value ) {
|
if ( item === category.value ) {
|
||||||
exactMatch = true;
|
exactMatch = true;
|
||||||
|
|
Loading…
Reference in a new issue