]> gitweb.fperrin.net Git - Dictionary.git/commitdiff
Allow multiple dictionaries in a .zip file.
authorReimar Döffinger <Reimar.Doeffinger@gmx.de>
Wed, 13 Jun 2018 21:46:56 +0000 (23:46 +0200)
committerReimar Döffinger <Reimar.Doeffinger@gmx.de>
Wed, 13 Jun 2018 21:46:56 +0000 (23:46 +0200)
Also protect against zip files containing
files with a path.

src/com/hughes/android/dictionary/DictionaryManagerActivity.java

index 8cbcb537a2dd955b1edf849d8e741701986d3801..3cc5e823fee1c5e752c40d933c17634e8c0c51e9 100644 (file)
@@ -83,6 +83,7 @@ import java.util.Collections;
 import java.util.HashSet;
 import java.util.List;
 import java.util.Set;
+import java.util.regex.Pattern;
 import java.util.zip.ZipEntry;
 import java.util.zip.ZipInputStream;
 
@@ -223,15 +224,24 @@ public class DictionaryManagerActivity extends AppCompatActivity {
                 }
             }
             zipFile = new ZipInputStream(new BufferedInputStream(zipFileStream));
-            final ZipEntry zipEntry = zipFile.getNextEntry();
-            Log.d(LOG, "Unzipping entry: " + zipEntry.getName());
-            File targetFile = new File(application.getDictDir(), zipEntry.getName());
-            if (targetFile.exists()) {
-                targetFile.renameTo(new File(targetFile.getAbsolutePath().replace(".quickdic", ".bak.quickdic")));
-                targetFile = new File(application.getDictDir(), zipEntry.getName());
+            ZipEntry zipEntry = null;
+            while ((zipEntry = zipFile.getNextEntry()) != null) {
+                // Note: this check prevents security issues like accidental path
+                // traversal, which unfortunately ZipInputStream has no protection against.
+                // So take extra care when changing it.
+                if (!Pattern.matches("[-A-Za-z]+\\.quickdic", zipEntry.getName())) {
+                    Log.w(LOG, "Invalid zip entry: " + zipEntry.getName());
+                    continue;
+                }
+                Log.d(LOG, "Unzipping entry: " + zipEntry.getName());
+                File targetFile = new File(application.getDictDir(), zipEntry.getName());
+                if (targetFile.exists()) {
+                    targetFile.renameTo(new File(targetFile.getAbsolutePath().replace(".quickdic", ".bak.quickdic")));
+                    targetFile = new File(application.getDictDir(), zipEntry.getName());
+                }
+                zipOut = new FileOutputStream(targetFile);
+                copyStream(zipFile, zipOut);
             }
-            zipOut = new FileOutputStream(targetFile);
-            copyStream(zipFile, zipOut);
             application.backgroundUpdateDictionaries(dictionaryUpdater);
             if (!isFinishing())
                 Toast.makeText(context, getString(R.string.installationFinished, dest),