make sure cached file exists before trying to scan it
Files in the cache can be deleted at any time, without warning. F-Droid's CleanCacheService can do it, the user can do it in Settings --> Apps, etc. So when working with files from the cache, the methods need to be extra defensive, checking that the file that they were given still exists. closes #1305
This commit is contained in:
parent
8600ce8d8a
commit
532d1dfc72
@ -9,7 +9,6 @@ import android.net.Uri;
|
|||||||
import android.support.annotation.Nullable;
|
import android.support.annotation.Nullable;
|
||||||
import android.text.TextUtils;
|
import android.text.TextUtils;
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
|
|
||||||
import org.fdroid.fdroid.data.Apk;
|
import org.fdroid.fdroid.data.Apk;
|
||||||
import org.fdroid.fdroid.data.ApkProvider;
|
import org.fdroid.fdroid.data.ApkProvider;
|
||||||
import org.fdroid.fdroid.data.InstalledAppProviderService;
|
import org.fdroid.fdroid.data.InstalledAppProviderService;
|
||||||
@ -129,7 +128,8 @@ public class AppUpdateStatusService extends IntentService {
|
|||||||
AppUpdateStatusManager.getInstance(this).markAsNoLongerPendingInstall(downloadedApk.getUrl());
|
AppUpdateStatusManager.getInstance(this).markAsNoLongerPendingInstall(downloadedApk.getUrl());
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
} catch (PackageManager.NameNotFoundException ignored) { }
|
} catch (PackageManager.NameNotFoundException ignored) {
|
||||||
|
}
|
||||||
|
|
||||||
Utils.debugLog(TAG, downloadedApk.packageName + " is pending install, so we need to notify the user about installing it.");
|
Utils.debugLog(TAG, downloadedApk.packageName + " is pending install, so we need to notify the user about installing it.");
|
||||||
return downloadedApk;
|
return downloadedApk;
|
||||||
@ -140,12 +140,16 @@ public class AppUpdateStatusService extends IntentService {
|
|||||||
* This method looks for all matching records in the database. It then asks each of these
|
* This method looks for all matching records in the database. It then asks each of these
|
||||||
* {@link Apk} instances where they expect to be downloaded. If they expect to be downloaded
|
* {@link Apk} instances where they expect to be downloaded. If they expect to be downloaded
|
||||||
* to {@param apkPath} then that instance is returned.
|
* to {@param apkPath} then that instance is returned.
|
||||||
*
|
* <p>
|
||||||
* If no files have a matching hash, or only those which don't belong to the correct repo, then
|
* If no files have a matching hash, or only those which don't belong to the correct repo, then
|
||||||
* this will return null.
|
* this will return null. This method needs to do its own check whether the file exists,
|
||||||
|
* since files can be deleted from the cache at any time without warning.
|
||||||
*/
|
*/
|
||||||
@Nullable
|
@Nullable
|
||||||
private Apk findApkMatchingHash(File apkPath) {
|
private Apk findApkMatchingHash(File apkPath) {
|
||||||
|
if (!apkPath.canRead()) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
// NOTE: This presumes SHA256 is the only supported hash. It seems like that is an assumption
|
// NOTE: This presumes SHA256 is the only supported hash. It seems like that is an assumption
|
||||||
// in more than one place in the F-Droid client. If this becomes a problem in the future, we
|
// in more than one place in the F-Droid client. If this becomes a problem in the future, we
|
||||||
|
@ -706,11 +706,19 @@ public class App extends ValueObject implements Comparable<App>, Parcelable {
|
|||||||
this.compatible = true;
|
this.compatible = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Initializes an {@link App} instances from an APK file. Since the file
|
||||||
|
* could in the cache, and files can disappear from the cache at any time,
|
||||||
|
* this needs to be quite defensive ensuring that {@code apkFile} still
|
||||||
|
* exists.
|
||||||
|
*/
|
||||||
private void initApkFromApkFile(Context context, Apk apk, PackageInfo packageInfo, SanitizedFile apkFile)
|
private void initApkFromApkFile(Context context, Apk apk, PackageInfo packageInfo, SanitizedFile apkFile)
|
||||||
throws IOException, CertificateEncodingException {
|
throws IOException, CertificateEncodingException {
|
||||||
// TODO include signature hash calculation here
|
// TODO include signature hash calculation here
|
||||||
|
if (apkFile.canRead()) {
|
||||||
apk.hashType = "sha256";
|
apk.hashType = "sha256";
|
||||||
apk.hash = Utils.getBinaryHash(apkFile, apk.hashType);
|
apk.hash = Utils.getBinaryHash(apkFile, apk.hashType);
|
||||||
|
}
|
||||||
initInstalledApk(context, apk, packageInfo, apkFile);
|
initInstalledApk(context, apk, packageInfo, apkFile);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -750,10 +758,22 @@ public class App extends ValueObject implements Comparable<App>, Parcelable {
|
|||||||
apk.packageName = this.packageName;
|
apk.packageName = this.packageName;
|
||||||
apk.requestedPermissions = packageInfo.requestedPermissions;
|
apk.requestedPermissions = packageInfo.requestedPermissions;
|
||||||
apk.apkName = apk.packageName + "_" + apk.versionCode + ".apk";
|
apk.apkName = apk.packageName + "_" + apk.versionCode + ".apk";
|
||||||
apk.installedFile = apkFile;
|
|
||||||
|
|
||||||
initInstalledObbFiles(apk);
|
initInstalledObbFiles(apk);
|
||||||
|
|
||||||
|
final FeatureInfo[] features = packageInfo.reqFeatures;
|
||||||
|
if (features != null && features.length > 0) {
|
||||||
|
apk.features = new String[features.length];
|
||||||
|
for (int i = 0; i < features.length; i++) {
|
||||||
|
apk.features[i] = features[i].name;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!apkFile.canRead()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
apk.installedFile = apkFile;
|
||||||
JarFile apkJar = new JarFile(apkFile);
|
JarFile apkJar = new JarFile(apkFile);
|
||||||
HashSet<String> abis = new HashSet<>(3);
|
HashSet<String> abis = new HashSet<>(3);
|
||||||
Pattern pattern = Pattern.compile("^lib/([a-z0-9-]+)/.*");
|
Pattern pattern = Pattern.compile("^lib/([a-z0-9-]+)/.*");
|
||||||
@ -766,14 +786,6 @@ public class App extends ValueObject implements Comparable<App>, Parcelable {
|
|||||||
}
|
}
|
||||||
apk.nativecode = abis.toArray(new String[abis.size()]);
|
apk.nativecode = abis.toArray(new String[abis.size()]);
|
||||||
|
|
||||||
final FeatureInfo[] features = packageInfo.reqFeatures;
|
|
||||||
if (features != null && features.length > 0) {
|
|
||||||
apk.features = new String[features.length];
|
|
||||||
for (int i = 0; i < features.length; i++) {
|
|
||||||
apk.features[i] = features[i].name;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
final JarEntry aSignedEntry = (JarEntry) apkJar.getEntry("AndroidManifest.xml");
|
final JarEntry aSignedEntry = (JarEntry) apkJar.getEntry("AndroidManifest.xml");
|
||||||
|
|
||||||
if (aSignedEntry == null) {
|
if (aSignedEntry == null) {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user