jenkins-bot has submitted this change and it was merged.
Change subject: Clean up incorrect use of regular expressions in
CategoryInputWidget
......................................................................
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
---
M modules/ve/ui/widgets/ve.ui.MWCategoryInputWidget.js
1 file changed, 16 insertions(+), 10 deletions(-)
Approvals:
Trevor Parscal: Looks good to me, approved
jenkins-bot: Verified
diff --git a/modules/ve/ui/widgets/ve.ui.MWCategoryInputWidget.js
b/modules/ve/ui/widgets/ve.ui.MWCategoryInputWidget.js
index bc3ecec..a67a8cf 100644
--- a/modules/ve/ui/widgets/ve.ui.MWCategoryInputWidget.js
+++ b/modules/ve/ui/widgets/ve.ui.MWCategoryInputWidget.js
@@ -33,7 +33,7 @@
// Properties
this.categoryWidget = categoryWidget;
this.forceCapitalization = mw.config.get( 'wgCaseSensitiveNamespaces'
).indexOf( 14 ) === -1;
- this.categoryPrefix = 'Category:';
+ this.categoryPrefix = mw.config.get( 'wgFormattedNamespaces' )['14'] +
':';
// Initialization
this.$.addClass( 've-ui-mwCategoryInputWidget' );
@@ -74,11 +74,17 @@
* @param {Mixed} data Response from server
*/
ve.ui.MWCategoryInputWidget.prototype.getLookupCacheItemFromData = function (
data ) {
- return ve.isArray( data ) && data.length ?
- data[1].map( ve.bind( function ( item ) {
- return item.replace( new RegExp( this.categoryPrefix,
'gi' ), '' );
- }, this ) ) :
- [];
+ var i, len, title, result = [];
+ if ( ve.isArray( data ) && data.length ) {
+ for ( i = 0, len = data[1].length; i < len; i++ ) {
+ 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 @@
menu$$ = this.lookupMenu.$$,
category = this.getCategoryItemFromValue( this.value ),
existingCategories = this.categoryWidget.getCategories(),
- matchingCategories = data || [],
- pattern = new RegExp( '^' + category.value );
+ matchingCategories = data || [];
// Existing categories
for ( i = 0, len = existingCategories.length; i < len; 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 ) {
exactMatch = true;
}
@@ -115,7 +121,7 @@
item = matchingCategories[i];
if (
existingCategoryItems.indexOf( item ) === -1 &&
- item.match( pattern )
+ item.lastIndexOf( category.value, 0 ) === 0
) {
if ( item === category.value ) {
exactMatch = true;
--
To view, visit https://gerrit.wikimedia.org/r/68028
To unsubscribe, visit https://gerrit.wikimedia.org/r/settings
Gerrit-MessageType: merged
Gerrit-Change-Id: I6547f9df2e94fe81f6aefb9286e547425137344b
Gerrit-PatchSet: 2
Gerrit-Project: mediawiki/extensions/VisualEditor
Gerrit-Branch: master
Gerrit-Owner: Catrope <[email protected]>
Gerrit-Reviewer: Trevor Parscal <[email protected]>
Gerrit-Reviewer: jenkins-bot
_______________________________________________
MediaWiki-commits mailing list
[email protected]
https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits