X-Git-Url: http://gitweb.fperrin.net/?p=Dictionary.git;a=blobdiff_plain;f=src%2Fcom%2Fhughes%2Fandroid%2Fdictionary%2FDictionaryManagerActivity.java;h=faf507da40dca60fd84a5ab53b1f551da1c4c5e1;hp=8cbcb537a2dd955b1edf849d8e741701986d3801;hb=c76660b2772122109529d3616289980a7084eeeb;hpb=72600db6412b4be173c31a53b4e742dc586cffae diff --git a/src/com/hughes/android/dictionary/DictionaryManagerActivity.java b/src/com/hughes/android/dictionary/DictionaryManagerActivity.java index 8cbcb53..faf507d 100644 --- a/src/com/hughes/android/dictionary/DictionaryManagerActivity.java +++ b/src/com/hughes/android/dictionary/DictionaryManagerActivity.java @@ -27,10 +27,11 @@ import android.content.SharedPreferences.Editor; import android.content.pm.PackageManager; import android.database.Cursor; import android.net.Uri; +import android.os.Build; import android.os.Bundle; import android.os.Environment; import android.os.Handler; -import android.preference.PreferenceManager; +import android.support.v7.preference.PreferenceManager; import android.provider.Settings; import android.support.annotation.NonNull; import android.support.v4.app.ActivityCompat; @@ -83,6 +84,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; @@ -142,7 +144,7 @@ public class DictionaryManagerActivity extends AppCompatActivity { final String action = intent.getAction(); if (DownloadManager.ACTION_NOTIFICATION_CLICKED.equals(action)) { - startActivity(DictionaryManagerActivity.getLaunchIntent(getApplicationContext()).addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TOP)); + startActivity(getLaunchIntent(getApplicationContext()).addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TOP)); } if (DownloadManager.ACTION_DOWNLOAD_COMPLETE.equals(action)) { final long downloadId = intent.getLongExtra( @@ -223,15 +225,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; + 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), @@ -248,14 +259,15 @@ public class DictionaryManagerActivity extends AppCompatActivity { } finally { try { if (zipOut != null) zipOut.close(); - } catch (IOException e) {} + } catch (IOException ignored) {} try { if (zipFile != null) zipFile.close(); - } catch (IOException e) {} + } catch (IOException ignored) {} try { if (zipFileStream != null) zipFileStream.close(); - } catch (IOException e) {} - if (localZipFile != null && delete) localZipFile.delete(); + } catch (IOException ignored) {} + if (localZipFile != null && delete) //noinspection ResultOfMethodCallIgnored + localZipFile.delete(); } return result; } @@ -291,7 +303,7 @@ public class DictionaryManagerActivity extends AppCompatActivity { } @Override - public void onRequestPermissionsResult(int requestCode, @NonNull String permissions[], @NonNull int[] grantResults) { + public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) { readableCheckAndError(false); application.backgroundUpdateDictionaries(dictionaryUpdater); @@ -334,6 +346,9 @@ public class DictionaryManagerActivity extends AppCompatActivity { } }); + /* + Disable version update notification, I don't maintain the text really + and I don't think it is very useful. final SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(this); final String thanksForUpdatingLatestVersion = getString(R.string.thanksForUpdatingVersion); if (!prefs.getString(C.THANKS_FOR_UPDATING_VERSION, "").equals( @@ -343,6 +358,7 @@ public class DictionaryManagerActivity extends AppCompatActivity { prefs.edit().putString(C.THANKS_FOR_UPDATING_VERSION, thanksForUpdatingLatestVersion) .commit(); } + */ IntentFilter downloadManagerIntents = new IntentFilter(DownloadManager.ACTION_DOWNLOAD_COMPLETE); downloadManagerIntents.addAction(DownloadManager.ACTION_NOTIFICATION_CLICKED); registerReceiver(broadcastReceiver, downloadManagerIntents); @@ -506,7 +522,7 @@ public class DictionaryManagerActivity extends AppCompatActivity { public boolean onMenuItemClick(final MenuItem menuItem) { final Intent intent = new Intent(Intent.ACTION_VIEW); intent.setData(Uri - .parse("https://github.com/rdoeffinger/Dictionary/releases/v0.2-dictionaries")); + .parse("https://github.com/rdoeffinger/Dictionary/releases/v0.3-dictionaries")); startActivity(intent); return false; } @@ -672,7 +688,7 @@ public class DictionaryManagerActivity extends AppCompatActivity { if (cursor == null) { if (cancel) { String msg = getString(R.string.downloadManagerQueryFailed); - new AlertDialog.Builder(DictionaryManagerActivity.this).setTitle(getString(R.string.error)) + new AlertDialog.Builder(this).setTitle(getString(R.string.error)) .setMessage(getString(R.string.downloadFailed, msg)) .setNeutralButton("Close", null).show(); } @@ -809,8 +825,12 @@ public class DictionaryManagerActivity extends AppCompatActivity { bytes / 1024.0 / 1024.0)); return; } - Request request = new Request( - Uri.parse(downloadUrl)); + // API 19 and earlier have issues with github URLs, both http and https. + // Really old (~API 10) DownloadManager cannot handle https at all. + // Work around both with in one. + String altUrl = downloadUrl.replace("https://github.com/rdoeffinger/Dictionary/releases/download/v0.2-dictionaries/", "http://ffmpeg.org/~reimar/dict/"); + altUrl = altUrl.replace("https://github.com/rdoeffinger/Dictionary/releases/download/v0.3-dictionaries/", "http://ffmpeg.org/~reimar/dict/"); + Request request = new Request(Uri.parse(Build.VERSION.SDK_INT < 21 ? altUrl : downloadUrl)); String destFile; try { @@ -829,6 +849,14 @@ public class DictionaryManagerActivity extends AppCompatActivity { DownloadManager downloadManager = (DownloadManager) getSystemService(DOWNLOAD_SERVICE); + if (downloadManager == null) { + String msg = getString(R.string.downloadManagerQueryFailed); + new AlertDialog.Builder(this).setTitle(getString(R.string.error)) + .setMessage(getString(R.string.downloadFailed, msg)) + .setNeutralButton("Close", null).show(); + return; + } + try { downloadManager.enqueue(request); } catch (SecurityException e) {