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

Dear Monks,

I want to check if the data that my user is giving me does not contain any Linux special character. So I wrote:

$folder = $entryfolder->get();#get the value from the entry widget my @chars = split //,$folder; foreach (@chars){ if($_ eq "*" || $_ eq '$' || $_ eq "&" || $_ eq "." || $_ eq "?" || +$_ eq '\'){ $dialog = $sw-> Dialog( -title=> 'Alert', -text => "Special characters appear in the name of your folder.", -buttons => [ qw(OK) ]) ->Show(); } }

All but the backslash work. Any idea how I can check if in a string there is a \?

Thank you in advance,

Claire

janitored by ybiC: Minor format cleanups, including balanced <code> tags around codeblock

Replies are listed 'Best First'.
Re: checking for reserved characters
by dave_the_m (Monsignor) on Apr 13, 2005 at 23:05 UTC
    my @chars = split //,$folder; foreach (@chars){ if($_ eq "*" || $_ eq '$' || $_ eq "&" || $_ eq "." || $_ eq "?" || + $_ eq '\'){
    Ignoring for now whether that's the right set of reserved characters, your code can be written far more succinctly and efficiently as
    if ($folder =~ /[$&.?\\]/) {

    Dave.

Re: checking for reserved characters
by ikegami (Patriarch) on Apr 13, 2005 at 22:11 UTC

    The only character that's not allowed in linux (file and) directory names is "/".

    '\' is a syntax error, since the \ is escaping the '. '\\' would be the correct way of creating a string consisting of a single backslash.

      Hi ikegami and thanks

      What user gives me will eventually be used at the command line and I read at http://www.tuxfiles.org/linuxhelp/weirdchars.html that it might create problem since Linux might be confused. Is that true?

      I should also worry about spaces, but I don't know how to check for that? Do you?

      Thanks again,

      Claire

        Personally, I see no reason to avoid spaces et al. My wife has no clue what characters are special, and has no problems saving files such as "Foo's resume & cover letter.sxd". (No, her name isn't really "Foo" ;-}) And it works just fine.

        What you want to use to check for bad characters is simply

        $folder =~ m<[bad characters here]>;
        In your case, the only bad character is the slash, so we can eliminate the brackets:
        $folder =~ m</>;
        As for using at the command line - this is no different than writing documents in OpenOffice.org. If you want to load it, just put it in quotes. Or, using bash on Linux, just type the first few characters and hit the tab key - all escapes will be put in automatically for filename completion (assuming it is unique to the first few letters you typed in).

        If you're going to programmatically call another program, you should be learning to use the list version of system and/or exec anyway. By eliminating the shell, you don't need to worry about special characters.

        system('/usr/bin/ooffice', $filename);
        Whether $filename has spaces, or any other special character, or not, doesn't matter. It just works.

        If all you want to do is rule out certain file names, just test them against a suitable regexp, like this:

        $folder = $entryfolder->get(); #get the value from the entry widget if ( $folder =~ /[\$\\*&.?\s]/ ) { $dialog = $sw-> Dialog( -title=> 'Alert', -text => "Special characters appear in the name + of your folder.", -buttons => qw(OK) ) ->Show(); }
        That checks for whitespace too.

        BTW, I find it hard to understand why you'd want rule out periods in filenames. They are ubiquitous, and cause no problem. The only thing about having a period in a filename is that if it is the first character in the name, some commands, notably ls, will not display them unless one specifically requests it. If you want to rule out filenames that begin with a period, but allow them otherwise, change the regexp above to

        /[\$\\*&?\s]|^\./

        the lowliest monk

        Yes, they can cause problems if they are passed to the shell improperly quoted and/or improperly escaped. In fact, I suspect there's more bad character than just those you listed. That's why it's bad to execute commands via the shell if you can avoid it. It's better to use the multiple argument form of system or exec instead if possible, since their argument don't need to be quoted or escaped then.

Re: checking for reserved characters
by BUU (Prior) on Apr 14, 2005 at 02:25 UTC
    Ignoring your actual code, if you're going to be passing user specified code to the command line, use quotemeta. It was designed for this. But preferably, use the LIST form of system or open and avoid the shell entirely.
Re: checking for reserved characters
by tlm (Prior) on Apr 13, 2005 at 22:13 UTC

    I see no reason why your code shouldn't work. What did you use to test it?

    Update: I'm tired today... The minute I dropped that code in my editor, I saw the problem.

    the lowliest monk

Re: checking for reserved characters
by grinder (Bishop) on Apr 14, 2005 at 13:17 UTC
    I want to check if the data that my user is giving me does not contain any Linux special character.

    I would tend to turn the problem on its head and solve it the other way around. Rather than trying to exclude naughty characters, I think you would be more better serverd by only allowing permitted characters.

    if( $folder !~ /^[\w. -]+$/ ) { print "I don't like your $folder\n"; }

    It is much easier and safer to relax a too-strict check, than it is to tighten up a too-lax requirement. There will always be someone smarter who finds (and exploits) the loop-hole before you do...

    - another intruder with the mooring in the heart of the Perl