diff options
author | H. Peter Anvin <hpa@zytor.com> | 2011-09-28 09:26:38 -0700 |
---|---|---|
committer | H. Peter Anvin <hpa@zytor.com> | 2011-09-28 09:26:38 -0700 |
commit | 8d9ce21d15eb5da8a7c5ab5ee3c65bbfbabf1fc5 (patch) | |
tree | 98a3da12577acfcaeed46b893e10e983a8396fe9 | |
parent | ea44bbe191501eefdb1d06bc0a77b124c26c785f (diff) | |
download | kup-8d9ce21d15eb5da8a7c5ab5ee3c65bbfbabf1fc5.tar.gz |
Cap filename components to 251 bytes
Cap the length of any individual filename component to 251 *bytes*,
to make sure we don't overflow the 255-byte limit when we tack on an
extension.
Reported-by: Alan Cox <alan@lxorguk.ukuu.org.uk>
Signed-off-by: H. Peter Anvin <hpa@zytor.com>
-rwxr-xr-x | korgupload | 18 | ||||
-rwxr-xr-x | kup | 18 |
2 files changed, 34 insertions, 2 deletions
@@ -178,9 +178,13 @@ sub is_clean_string($) # This returns true if the given argument is a valid filename in its # canonical form. Double slashes, relative paths, control characters, -# and malformed UTF-8 is not permitted. +# and malformed UTF-8 is not permitted. We cap the length of each +# pathname component to 251 characters to we can add an extension +# without worrying about it. sub is_valid_filename($) { + use bytes; + my($f) = @_; return 0 if (!is_clean_string($f)); @@ -189,6 +193,18 @@ sub is_valid_filename($) return 0 if ($f =~ m://:); return 0 if ($f =~ m:/(\.|\.\.)(/|$):); + # Make sure we can create a 255-byte-long filename after adding + # .bz2 or similar. We can't use the obvious regexp here, because + # regexps operate on characters, not bytes. + my $n = 0; + my $nmax = 0; + for (my $i = 0; $i < length($f); $i++) { + my $c = substr($f, $i, 1); + $n = ($c eq '/') ? 0 : $n+1; + $nmax = ($n > $nmax) ? $n : $nmax; + } + return 0 if ($nmax > 251); + return 1; } @@ -75,9 +75,13 @@ sub is_clean_string($) # This returns true if the given argument is a valid filename in its # canonical form. Double slashes, relative paths, control characters, -# and malformed UTF-8 is not permitted. +# and malformed UTF-8 is not permitted. We cap the length of each +# pathname component to 251 characters to we can add an extension +# without worrying about it. sub is_valid_filename($) { + use bytes; + my($f) = @_; return 0 if (!is_clean_string($f)); @@ -86,6 +90,18 @@ sub is_valid_filename($) return 0 if ($f =~ m://:); return 0 if ($f =~ m:/(\.|\.\.)(/|$):); + # Make sure we can create a 255-byte-long filename after adding + # .bz2 or similar. We can't use the obvious regexp here, because + # regexps operate on characters, not bytes. + my $n = 0; + my $nmax = 0; + for (my $i = 0; $i < length($f); $i++) { + my $c = substr($f, $i, 1); + $n = ($c eq '/') ? 0 : $n+1; + $nmax = ($n > $nmax) ? $n : $nmax; + } + return 0 if ($nmax > 251); + return 1; } |