From: Reimar Döffinger Date: Wed, 13 Jun 2018 21:46:56 +0000 (+0200) Subject: Allow multiple dictionaries in a .zip file. X-Git-Url: http://gitweb.fperrin.net/?p=Dictionary.git;a=commitdiff_plain;h=ad2d4c4a6f0589ff9bcc5ecb2602442cf2ba20f6 Allow multiple dictionaries in a .zip file. Also protect against zip files containing files with a path. --- 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),