directory input sanitation
I have a very simple perl script that moves files (don't ask why i cant use cp, its long, sad, and will make you cry). I take 2 inputs from command line, dir1 and dir2. Then i have an internal file list i pull and concatenate the two together.
my $file = dir1 . filename
That works great as long as开发者_开发问答 the user puts a traling / on their directory. But obviously if they don't it still concatenates it as /my/awesome/folderFILE and the scripts fails.
What is the best practice for sanitizing user supplied directories?
While you can, as other answers alluded to, just force-add a trailing slash, it has some minor problems stemming from resulting double-slash - from just looking plain ugly, at least IMHO, if you print the resulting filenames for logging; to a much worse problem of making said logs harder to parse/process automatically if needed.
A more portable and idiomatic approach in Perl is to build the paths using File::Spec:
use File::Spec;
my $file = File::Spec::catfile($dir1,$filename);
If you feel like using a module for something THAT simple is a bit of a nuke-the-fly approach, use the regex (so you can now have 2 problems! :)
$dir =~ s!([^/])$!$1/!;
This approach has the added benefit of a teaching device to showcase that you don't have to use forward slashes as regex delimiters.
In addition, and probably already obvious to you, but worth re-iterating: NEVER TRUST THE USER INPUT!!!
So, always do something like die "Not a directory: $dir1\n" unless -d $dir1;
when processing command line parameters.
Just always add on a trailing '/' for the directory path. Your shell should accept '/my/awesome/folder//FILE' and will interpret it as '/my/awesome/folder/FILE'.
my $file = $dir1 . '/' . $filename
/a/b//c
works the same as /a/b/c
You can translate the requirement to "add a trailing / to the path unless it already has one" from English to Perl quite directly, no regex required:
$path .= '/' unless substr($path, -1) eq '/';
精彩评论