bigmacbear has asked for the wisdom of the Perl Monks concerning the following question:

I have a program that does some simple regex checking to untaint some user input prior to storing it in a database. I extracted the offending code into a test program:

#!/usr/local/bin/perl -T use strict; use warnings; my ( $id, $port, $description ); while(<>) { chomp; # Ignore comments. next if /^#/; # Do very rudimentary syntax checking on the ID and port fields ( $id, $port, $description ) = m#^\s*(\w+-\w+)\s+(\w+/\d+/\d+)\s+(.*)$#; # Here in my real program I do some database stuff. print "ID: $id, Port: $port, Description: $description\n"; }

When I run the code above it works. When I paste the exact RE assignment into my actual program (it appears in two places in the real program) it fails, even though every statement before and since is syntactically correct (obviously I am missing something). It worked a few hours ago, then all of a sudden it stopped.

Perl just gives me:

syntax error at ./vipatch.cgi line 237, near "( $id, $port, $descripti +on ) = m#^\s*(\w+-\"
I first noticed the problem trying to run perltidy on the same code, it gives me
There is no previous '(' to match a ')' on line 237 237: ( $id, $port, $description ) = m#^\s*(\w+-\w+)\s+(\w+/\d +... ^ There is no previous '(' to match a ')' on line 237 237: ... n ) = m#^\s*(\w+-\w+)\s+(\w+/\d+/\d+)\s+(.*)$#; ^ 268: ( $id, $port, $description ) = m#^\s*(\w+-\w+)\s+(\w+/\d +... ^ found Scalar where operator expected There is no previous '(' to match a ')' on line 268 268: ( $id, $port, $description ) = m#^\s*(\w+-\w+)\s+(\w+/\d +... ^ 398: The logfile vipatch.cgi.LOG may contain useful information

Of course, the log file just says the same thing. It's exasperating to see the open parenthesis right there in front of you that perltidy and apparently the Perl interpreter itself missed outright.

Perl version is 5.8.0, platform is sun4-solaris.

Where have I gone wrong here?

Update: I tried YAPE::Regex::Explain on the regex in question and it parsed it properly, no problem.

Solution: The regex wasn't the problem and there weren't any missing semicolons; there was, however, a missing $ on an object call half a page above the regex.

Replies are listed 'Best First'.
Re: Regex syntax frustration
by Abigail-II (Bishop) on May 26, 2004 at 22:27 UTC
    My guess is that somewhere on a previous line, you forgot a string delimiter. Or perhaps you forgot a semi-colon on the previous line. It would help if you could provide us with a short piece of code that doesn't compile.

    Abigail

      I tried to do that by including the several lines preceding the regex (the while loop) in the test program, which compiled and ran. So I must not have grabbed code back far enough to include the error.

      I cut and pasted the entire subroutine containing the while loop. Lo and behold I found the problem: this is a CGI script (which is why taint checking is on) and I forgot the $ on my CGI object, five lines above my while loop. So instead of "$q->p()" I had "q->p()". Aargh.

      The lesson to be learned here is when you are done looking for missing semicolons and string delimiters, look next for missing dollar signs on variables (especially objects).

      Thanks much for breaking me out of a "tight mental loop" around that damned regex. ;-)

Re: Regex syntax frustration
by davido (Cardinal) on May 26, 2004 at 22:31 UTC
    Your regex is probably not to blame. I believe the error is a missing semicolon on one of the lines above this point in the script... usually a line or two above. Another possibility is unmatched brackets or parens or quotes in a line within a line or several above these points in the script.

    Sometimes such errors aren't detected on the line in which they occur, usually because whatever the result is of the missing semicolon (or whatever) isn't syntactically erroneous until something else comes along on the next line.


    Dave