PDA

View Full Version : [OPEN] [OPEN-32][DUP][3.0rc2] DomQuery regex bug



prometheus
24 Jun 2009, 1:53 AM
It has a tiny bug in DomQuery which is due to problems matching attribute queries like input[name="morethanone[two]"] and input[name=morethanone[two]]. Last example occurred at Ext.form.Radio.onClick() in my case and throws exception.

Please welcome the patch below (source/core/DomQuery.js):

},{
re: /^(?:([\[\{])(?:@)?([\w-]+)\s?(?:(=|.=)\s?['"]?(.*?)["']?)?[\]\}])$/,
select: 'n = byAttribute(n, "{2}", "{4}", "{3}", "{1}");'
}, {


Which is a replacement of:

},{
re: /^(?:([\[\{])(?:@)?([\w-]+)\s?(?:(=|.=)\s?['"]?(.*?)["']?)?[\]\}])/,
select: 'n = byAttribute(n, "{2}", "{4}", "{3}", "{1}");'
}, {

...in definition of matchers array.

The only one difference is the $ sign at the end of regex, which is a must in this case because maybe more than one ] can appears in the subject and greedy quantor - .*? - stops on the first occurrance ignoring " too if exists because it`s optional on both two places.

evant
24 Jun 2009, 1:57 AM
As always, please post a test case that demonstrates the issue.

Condor
24 Jun 2009, 2:56 AM
Duplicate of this Ext 2.2 bugreport (http://www.extjs.com/forum/showthread.php?t=44422).

ps. Your solution doesn't work because it breaks other selectors, e.g.

input[type=text].myClass

The patch in the linked thread does work (well, the updated version from today at least).

prometheus
24 Jun 2009, 7:09 AM
Thank you for response and sorry for duplication and buggy patch. My test case is:

Ext.namespace('Test');

Test.AddWindow = Ext.extend(Ext.Window, {
width: 600,
height: 370,
autoScroll : true,
title: 'Test title',

initComponent : function()
{
Test.AddWindow.superclass.initComponent.call(this);

this.content = new Ext.form.FormPanel({
xtype: 'form',
frame: false,
autoHeight: true,
items: [{
xtype: 'fieldset',
title: 'Choose one',
autoHeight: true,
items: [{
xtype: 'radio',
name: 'filterOptions[postTitleMask]',
inputValue: 'titleBegin',
checked: true,
hideLabel: true,
boxLabel: 'titleBegin'
}, {
xtype: 'radio',
name: 'filterOptions[postTitleMask]',
inputValue: 'titleEnd',
checked: false,
hideLabel: true,
boxLabel: 'titleEnd'
}, {
xtype: 'radio',
name: 'filterOptions[postTitleMask]',
inputValue: 'titleBoth',
checked: false,
hideLabel: true,
boxLabel: 'titleBoth'
}]
}]
});

this.add(this.content);
}
});

var win = new Test.AddWindow();
win.show();


I used your regex patch posted on that other topic, but same exception (Exception... "'Error parsing selector, parsing failed at "]"' when calling method: [nsIDOMEventListener::handleEvent]" nsresult: "0x8057001e (NS_ERROR_XPC_JS_THREW_STRING)" location: "<unknown>" data: no) throwed again.

I think of that if I ungreedy the quantor at 5th subexpression on regex maybe buggy. So I patched the Ext.form.Radio to use a safer selector - this is with your matcher patch:

Ext.DomQuery.matchers[2] = {
re: /^(?:([\[\{])(?:@)?([\w-]+)\s?(?:(=|.=)\s?(["']?)(.*?)\4)?[\]\}])/,
select: 'n = byAttribute(n, "{2}", "{5}", "{3}", "{1}");'
};
Ext.override(Ext.form.Radio, {
onClick : function(){
if(this.el.dom.checked != this.checked){
var p = this.el.up('form') || Ext.getBody();
var els = p.select('input[name="'+this.el.dom.name+'"]');
els.each(function(el){
if(el.dom.id == this.id){
this.setValue(true);
}else{
Ext.getCmp(el.dom.id).setValue(false);
}
}, this);
}
},

setValue : function(v){
if (typeof v == 'boolean') {
Ext.form.Radio.superclass.setValue.call(this, v);
} else {
var r = this.el.up('form').child('input[name="'+this.el.dom.name+'"][value='+v+']', true);
if (r){
r.checked = true;
};
}
return this;
}
});

prometheus
24 Jun 2009, 7:17 AM
And "ofcourse" this patch issues a problem if somebody use apostrophes on names, for example replace radio names with filterOptions["postTitleMask"] - but it`s more marginaly than use of [] brackets.

Condor
24 Jun 2009, 7:30 AM
Your patch is incomplete/incorrect for use with Ext 3.0.

Use:

Ext.DomQuery.matchers[2] = {
re: /^(?:([\[\{])(?:@)?([\w-]+)\s?(?:(=|.=)\s?(["']?)(.*?)\4)?[\]\}])/,
select: 'n = byAttribute(n, "{2}", "{5}", "{3}", "{1}");'
};
Ext.override(Ext.form.Radio, {
getGroupValue : function(){
var p = this.el.up('form') || Ext.getBody();
var c = p.child('input[name="'+this.el.dom.name+'"]:checked', true);
return c ? c.value : null;
},
onClick : function(){
if(this.el.dom.checked != this.checked){
var els = this.getCheckEl().select('input[name="' + this.el.dom.name + '"]');
els.each(function(el){
if(el.dom.id == this.id){
this.setValue(true);
}else{
Ext.getCmp(el.dom.id).setValue(false);
}
}, this);
}
},
setValue : function(v){
if (typeof v == 'boolean') {
Ext.form.Radio.superclass.setValue.call(this, v);
} else {
var r = this.getCheckEl().child('input[name="' + this.el.dom.name + '"][value="' + v + '"]', true);
if(r){
Ext.getCmp(r.id).setValue(true);
}
}
return this;
}
});

And yes, this would make double quotes in radio names or value fail.

You could partially fix that by only adding the "" or '' quotes if the name or value actually contains ] or } and doesn't contain " (or ').

prometheus
24 Jun 2009, 8:41 AM
Thanks again the reply and your time. Your patch throws an error with my RC1.1 (this.getCheckEl is not a function). I think that this patch made for RC2 or later and works perfect so I will keep in mind that.