aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorH. Peter Anvin <hpa@zytor.com>2011-09-28 09:26:38 -0700
committerH. Peter Anvin <hpa@zytor.com>2011-09-28 09:26:38 -0700
commit8d9ce21d15eb5da8a7c5ab5ee3c65bbfbabf1fc5 (patch)
tree98a3da12577acfcaeed46b893e10e983a8396fe9
parentea44bbe191501eefdb1d06bc0a77b124c26c785f (diff)
downloadkup-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-xkorgupload18
-rwxr-xr-xkup18
2 files changed, 34 insertions, 2 deletions
diff --git a/korgupload b/korgupload
index 73dd4ad..731ec9d 100755
--- a/korgupload
+++ b/korgupload
@@ -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;
}
diff --git a/kup b/kup
index a46d423..ab16d2b 100755
--- a/kup
+++ b/kup
@@ -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;
}