From ad2d4c4a6f0589ff9bcc5ecb2602442cf2ba20f6 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Reimar=20D=C3=B6ffinger?= Date: Wed, 13 Jun 2018 23:46:56 +0200 Subject: [PATCH] Allow multiple dictionaries in a .zip file. Also protect against zip files containing files with a path. --- .../dictionary/DictionaryManagerActivity.java | 26 +++++++++++++------ 1 file changed, 18 insertions(+), 8 deletions(-) diff --git a/src/com/hughes/android/dictionary/DictionaryManagerActivity.java b/src/com/hughes/android/dictionary/DictionaryManagerActivity.java index 8cbcb53..3cc5e82 100644 --- a/src/com/hughes/android/dictionary/DictionaryManagerActivity.java +++ b/src/com/hughes/android/dictionary/DictionaryManagerActivity.java @@ -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), -- 2.43.0