http://qs321.pair.com?node_id=311603

hello fellow monks,

some days ago I was playing with an "advanced search"-like form, one of these where you can fill one or more search fields. something like:

# example of form: # Name: __________ # Address: __________ # Telephone: __________ # etc. # [Search]
of course, some of the fields could be blank. the searching code, reduced to its minimum, was something like:
if( $name =~ /\Q$pattern_name\E/i and $address =~ /\Q$pattern_address\E/i and $telephone =~ /\Q$pattern_telephone\E/i) { print "matched\n"; }
the match mysteriously failed when filling just the "Name" field, and I was puzzled for a few hours before finding out what was wrong.

the bug is really subtle indeed, and if you can spot it at a first glance, ++ to you.

what happens here is that, if one of the $pattern variables are blank, the regexp pattern evaluates to the empty string, and guess what this means? the last successfully matched regular expression is used instead. and more, if no match has previously succeeded, this will (silently) act instead as a genuine empty pattern (which will always match). (the italic is taken from perlop).

so, if I put, for example "da" in the "Name" field, my if statement tries to match name, address AND telephone from my database with "da". and this obviously fails. even putting debug statements outside the if, just to check what I thought was matched (eg. print the pattern, print the result of $data =~ /pattern/) didn't help, because it's the order of the matches that screw things up.

I ended up changing my code to something like:

if( (not $pattern_name or $name =~ /\Q$pattern_name\E/i) and (not $pattern_address or $address =~ /\Q$pattern_address\E/i) and (not $pattern_telephone or $telephone =~ /\Q$pattern_telephone\E/i +) ) { print "matched\n"; }
(I know, I could I've just used index instead of a regexp in this case, but the principle still applies).

and what I've learned is: something like /$pattern/ (I mean, just a variable inside a regexp and nothing else) is probably a bad idea, unless you're really, really sure that $pattern will actually contain something.

I hope this word of warning could save some headache to someone else in the future :-)

cheers,
Aldo

King of Laziness, Wizard of Impatience, Lord of Hubris