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

Oi,

Recently, the machine I am developing my perl applications on has been upgraded and now has perl 5.6.1.
Today, when I tried one of my (webbased) applications I noticed that some functions did not work anymore.

Whenever the following line of code is reached:
[...] if($value =~ /^$allowed$/){ [...]
The program exits with the following error:
Can't locate object method "IsWord" via package "main" perhaps you for +got to load "main"?) at /usr/share/perl/5.6.1/utf8_heavy.pl line 30.
The $value is a string given by the user, which is validated using a regular expression stored in $allowed.

According to the perldelta manual page, perl 5.6.1 introduces UTF8 support. I understand that this feature is still experimental, but that should not change the workings of regular expressions.

My $Question = What am i doing wrong?

Thanks in advance,
- Pitr

Replies are listed 'Best First'.
Re: Perl 5.6.1 Regular Expression problems (UTF8 ?)
by chipmunk (Parson) on Jul 06, 2001 at 17:23 UTC
    It is a quirk of Perl's error reporting that an error inside an if block may give the number of the line on which the if block starts, rather than the line within the if block where the error actually occured. Thus, you may have to look within the if block that starts on line 30 for the source of the error.

    Looking at tachyon's post, I see that this if statement is followed by a call to quotemeta. I expect that's what is causing the problem; quotemeta() backslashes everything except word characters, so it might use a function called IsWord to figure out if a certain UTF8 character should be backslashes or not.

    Unfortunately, I don't know why the IsWord function has not been loaded. You may want to produce a small test case and submit a bug report using the perlbug utility that comes with Perl.

      Thanks for the feedback so far. I tried to simulate the problem with the following piece of code:

      #!/usr/bin/perl -w print "Content-Type: text/html\n\n"; my $value = "ciaoslave"; my $allowed = '[\w\d\s\-]{1,15}'; my $escape = "yes"; if($value =~ /^$allowed$/){ print (($escape eq "no") ? $value : quotemeta($value)); }else{ print "Fail!"; } print "\n";

      When I call this script through a webbrowser it works.. and does not give the error that occurred earlier.

      Perhaps the XML::Simple module effects the behaviour in some way ?

      Thanks again,
      - Pitr
      Replacing '\w' by 'a-zA-Z' seems to do it - One step closer to the solution :)
      Pitr
        perl -wle 'BEGIN { $SIG{__DIE__} = sub { print "Catched SIGDIE: @_";ex +it(-1) }} use utf8; /^\w$/;'

        Results in:
        Catched SIGDIE: Can't locate object method "IsWord" via package "main" + (perhaps you forgot to load "main"?) at /usr/local/lib/perl5/5.6.1/u +tf8_heavy.pl line 30.

        This code illustrates the problem: the eval() done by utf8_heavy.pl fails and calls the die-handler which is set within the BEGIN block. I think this should not happen, because the 'die' within eval() is in a different scope than the position where the Die-handler is set.
Re: Perl 5.6.1 Regular Expression problems (UTF8 ?)
by tachyon (Chancellor) on Jul 06, 2001 at 16:31 UTC

    We need more information. What makes you think the line you give is the source of the error? It does not look like it to me. If it *really* is (ie comment this line out and see if your error goes away) what is the value in $allowed and what is the value in $value? and how do you set $allowed

    Update

    Further to CB discussion here is the code (relevant bit first followed by entire prog), the var $allowed is passed from the client and used to validate client input which is very insecure.

    sub validate($$){ my($self,$name) = @_; if(! defined($self->{params}->{$name}) ){ return $self->setError("'$name' was not given."); } my $value = $self->{params}->{$name} || $self->{params}->{retvals}->{$name}; my $field = $self->getField($name); my $allowed = $field->{allowed}; my $comment = $field->{comment}; my $escape = $field->{escape} || "yes"; if($value =~ /^$allowed$/){ return (($escape eq "no") ? $value : quotemeta($value)); }elsif(! $allowed){ return $self->setError("No constraints defined for '$name'"); }else{ return $self->setError("Forbidden characters in $name: '". quotemeta($value)."' ". ($comment ? "($comment)" : "")); } }

    Here is the whole thing