Sebastian Stenzel 10 vuotta sitten
vanhempi
commit
6f9b16a7dc

+ 1 - 1
main/crypto-aes/src/main/java/org/cryptomator/crypto/aes256/Aes256Cryptor.java

@@ -621,7 +621,7 @@ public class Aes256Cryptor implements Cryptor, AesCryptographicConfiguration, Fi
 		return new Filter<Path>() {
 			@Override
 			public boolean accept(Path entry) throws IOException {
-				return ENCRYPTED_FILE_GLOB_MATCHER.matches(entry);
+				return ENCRYPTED_FILE_MATCHER.matches(entry);
 			}
 		};
 	}

+ 28 - 6
main/crypto-aes/src/main/java/org/cryptomator/crypto/aes256/FileNamingConventions.java

@@ -8,11 +8,13 @@
  ******************************************************************************/
 package org.cryptomator.crypto.aes256;
 
-import java.nio.file.FileSystems;
+import java.nio.file.Path;
 import java.nio.file.PathMatcher;
+import java.util.regex.Pattern;
 
 import org.apache.commons.codec.binary.Base32;
 import org.apache.commons.codec.binary.BaseNCodec;
+import org.apache.commons.lang3.StringUtils;
 
 interface FileNamingConventions {
 
@@ -22,10 +24,11 @@ interface FileNamingConventions {
 	BaseNCodec ENCRYPTED_FILENAME_CODEC = new Base32();
 
 	/**
-	 * Maximum length possible on file systems with a filename or even path length limit of 255 chars.<br/>
-	 * Also we would need a few chars for our file extension, so lets use {@value #ENCRYPTED_FILENAME_LENGTH_LIMIT}.
+	 * Maximum path length on some file systems or cloud storage providers is restricted.<br/>
+	 * Parent folder path uses up to 58 chars (sha256 -&gt; 32 bytes base32 encoded to 56 bytes + two slashes). That in mind we don't want the total path to be longer than 255 chars.<br/>
+	 * 128 chars would be enought for up to 80 plaintext chars. Also we need up to 8 chars for our file extension. So lets use {@value #ENCRYPTED_FILENAME_LENGTH_LIMIT}.
 	 */
-	int ENCRYPTED_FILENAME_LENGTH_LIMIT = 128;
+	int ENCRYPTED_FILENAME_LENGTH_LIMIT = 136;
 
 	/**
 	 * For plaintext file names <= {@value #ENCRYPTED_FILENAME_LENGTH_LIMIT} chars.
@@ -43,8 +46,27 @@ interface FileNamingConventions {
 	int LONG_NAME_PREFIX_LENGTH = 8;
 
 	/**
-	 * Matches both, {@value #BASIC_FILE_EXT} and {@value #LONG_NAME_FILE_EXT} files.
+	 * Matches valid encrypted filenames (both normal and long filenames - see {@link #ENCRYPTED_FILENAME_LENGTH_LIMIT}).
 	 */
-	PathMatcher ENCRYPTED_FILE_GLOB_MATCHER = FileSystems.getDefault().getPathMatcher("glob:**/*{" + BASIC_FILE_EXT + "," + LONG_NAME_FILE_EXT + "}");
+	PathMatcher ENCRYPTED_FILE_MATCHER = new PathMatcher() {
+
+		private final Pattern BASIC_NAME_PATTERN = Pattern.compile("^[a-z2-7]+=*$", Pattern.CASE_INSENSITIVE);
+		private final Pattern LONG_NAME_PATTERN = Pattern.compile("^[a-z2-7]{8}[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$", Pattern.CASE_INSENSITIVE);
+
+		@Override
+		public boolean matches(Path path) {
+			final String filename = path.getFileName().toString();
+			if (StringUtils.endsWithIgnoreCase(filename, LONG_NAME_FILE_EXT)) {
+				final String basename = StringUtils.removeEndIgnoreCase(filename, LONG_NAME_FILE_EXT);
+				return LONG_NAME_PATTERN.matcher(basename).matches();
+			} else if (StringUtils.endsWithIgnoreCase(filename, BASIC_FILE_EXT)) {
+				final String basename = StringUtils.removeEndIgnoreCase(filename, BASIC_FILE_EXT);
+				return BASIC_NAME_PATTERN.matcher(basename).matches();
+			} else {
+				return false;
+			}
+		}
+
+	};
 
 }