Beefy Boxes and Bandwidth Generously Provided by pair Networks
Don't ask to ask, just ask
 
PerlMonks  

Validate windows filenames.

by zzspectrez (Hermit)
on Jul 14, 2005 at 06:47 UTC ( [id://474773]=perlquestion: print w/replies, xml ) Need Help??

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

How do you validate filenames?

I got bit in the butt.

So here is my sob story. I have some old perl code that moves mp3 files and renames them based on the mp3 tag info. Well, I noticed the other day that a few songs had silenty disapeared during the move.

The culprit was failure to validate the filenames. If an invalid character was in the destination filename, the file was moved into oblivion with no error. oooopps...

So I did a quick search for some module that would validate filenames and could find nothing but this module VMS::FileUtils::SafeName that does not quite apply :) ...

So of course I wrote some quick code to do the job.. But was wondering how everyone else is handling this situation. I was suprised to not find a relevant module on CPAN but maybee I am just search impaired this evening.

Would also appreciate code review, since I suck with regexes! :)

use strict; use warnings; my $INV_CHAR; print "Testing for valid win32 filenames...\nThe following characters +are invalid.\n"; print '\\/:*?"<>|',"\n\n"; while (<DATA>) { chomp; print "filename: [",$_,"] is"; print validate_it($_) ? " valid.\n" : " not valid!\n\t Filename contains \"$INV +_CHAR\"\n" . "\ttry: [" . sanitize_it($_,'_') . "]\n"; } sub validate_it { local $_; $_ = shift; return /\\|\/|:|\*|\?|"|<|>|\|/ ? do { $INV_CHAR = $&; undef; } : 1; } sub sanitize_it { $_[0] =~ s/\\|\/|:|\*|\?|"|<|>|\|/$_[1]/g; return $_[0]; } __DATA__ file1 file2$is this)ok this-ok_too.. this-good.mp4 bad: b:a:d?--\ not<good> *is*bad/ ?what?is:good this|ok|not
UPDATE

To clear up any confusion about the purpose of this post. I'm not looking for solutions to the file copy/moving. I am looking for some discusion on handling filename validation/sanitizing.

My Questions are: (1) Do fellow perlmonks routinely validate filenames? If so, how do you do it? (2) Any inherit problems with how my routines deal with validating/sanitizing windows filenames??

zzSPECTREz

Replies are listed 'Best First'.
Re: Validate windows filenames.
by duelafn (Parson) on Aug 01, 2005 at 17:50 UTC

    Two things. Character classes, [], makes alternatives read easier, and always, always, always specify what you ALLOW.

    sub sanitize_it { $_[0] =~ s/[^\w.,\-={}()\[\]!@#\$%^&'`~]/$_[1]/g; return $_[0]; }

    Good Day,
        Dean

      +++
      Im still learning to use regexes and havent used character classes. Good example.

      Thanks..

      zzSPECTREz
Re: Validate windows filenames.
by Anonymous Monk on Jul 14, 2005 at 07:01 UTC
    If an invalid character was in the destination filename, the file was moved into oblivion with no error. oooopps...
    Moved into oblivion? You'll get no error if you don't check, so always check

      Actually my code did check for an error but the module that I used did not return an error. And even worse, instead of not moving the file and leaving it were it was, it just deleted it or moved it into oblivion.So even if I caught the error what was I to do:

      die "You are gonna hate life now. The file move failed and the source file has been deleted. Goodbye.\n";

      But thanks for the obvious....

      other peoples modules are great, untill they dont work as advertised.

      Not pointing fingers... I THINK the module should have handled this situation better, however I failed to validate the filename before trying to move the file.. Maybee the OS did not return an error to the module. who knows. This was one of my earlier scripts and worked great for a long time ( many years ) till it found and MP3 TAG with invalid characters in it.

      So back to the original question.... How do you validate filenames???

        If you try to copy the file in stead of moving / renaming? Check if success, then delete the original.

        "We all agree on the necessity of compromise. We just can't agree on when it's necessary to compromise." - Larry Wall.

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://474773]
Approved by jbrugger
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others chilling in the Monastery: (5)
As of 2024-04-19 10:48 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found