+ zipFile = new ZipInputStream(new BufferedInputStream(zipFileStream));
+ ZipEntry zipEntry;
+ 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);
+ }
+ application.backgroundUpdateDictionaries(dictionaryUpdater);
+ if (!isFinishing())
+ Toast.makeText(context, getString(R.string.installationFinished, dest),
+ Toast.LENGTH_LONG).show();
+ result = true;
+ } catch (Exception e) {
+ String msg = getString(R.string.unzippingFailed, dest + ": " + e.getMessage());
+ File dir = application.getDictDir();
+ if (!dir.canWrite() || !DictionaryApplication.checkFileCreate(dir)) {
+ msg = getString(R.string.notWritable, dir.getAbsolutePath());
+ }
+ new AlertDialog.Builder(context).setTitle(getString(R.string.error)).setMessage(msg).setNeutralButton("Close", null).show();
+ Log.e(LOG, "Failed to unzip.", e);
+ } finally {
+ try {
+ if (zipOut != null) zipOut.close();
+ } catch (IOException ignored) {}
+ try {
+ if (zipFile != null) zipFile.close();
+ } catch (IOException ignored) {}
+ try {
+ if (zipFileStream != null) zipFileStream.close();
+ } catch (IOException ignored) {}
+ if (localZipFile != null && delete) //noinspection ResultOfMethodCallIgnored
+ localZipFile.delete();