Merge branch 'hash-fixes' into 'master'

Hash fixes

Two semi-related commits about hashes.  This standardizes all APK hashes to be all lowercase like in the _fdroidserver index.xml_.  The other then stops swallowing hash-related exceptions so we have a chance of debugging the issue.  @pserwylo we discussed a0f716c0db705f137749eef3d4964b8ba1050b18 in relation to #699.

See merge request !377
This commit is contained in:
Peter Serwylo 2016-08-12 22:40:11 +00:00
commit 943e0d0a1c
4 changed files with 24 additions and 14 deletions

View File

@ -145,7 +145,7 @@ public final class Utils {
InputStream input = null; InputStream input = null;
OutputStream output = null; OutputStream output = null;
try { try {
input = new FileInputStream(inFile); input = new FileInputStream(inFile);
output = new FileOutputStream(outFile); output = new FileOutputStream(outFile);
Utils.copy(input, output); Utils.copy(input, output);
return true; return true;
@ -372,6 +372,11 @@ public final class Utils {
} }
} }
/**
* Get the checksum hash of the file {@code apk} using the algorithm in {@code algo}.
* {@code apk} must exist on the filesystem and {@code algo} must be supported
* by this device, otherwise an {@link IllegalArgumentException} is thrown.
*/
public static String getBinaryHash(File apk, String algo) { public static String getBinaryHash(File apk, String algo) {
FileInputStream fis = null; FileInputStream fis = null;
try { try {
@ -386,14 +391,9 @@ public final class Utils {
} }
byte[] mdbytes = md.digest(); byte[] mdbytes = md.digest();
return toHexString(mdbytes); return toHexString(mdbytes).toLowerCase(Locale.ENGLISH);
} catch (IOException e) { } catch (IOException | NoSuchAlgorithmException e) {
Log.e(TAG, "Error reading \"" + apk.getAbsolutePath() throw new IllegalArgumentException(e);
+ "\" to compute " + algo + " hash.", e);
return null;
} catch (NoSuchAlgorithmException e) {
Log.e(TAG, "Device does not support " + algo + " MessageDisgest algorithm");
return null;
} finally { } finally {
closeQuietly(fis); closeQuietly(fis);
} }
@ -476,7 +476,7 @@ public final class Utils {
@Override @Override
public void handleTag(boolean opening, String tag, Editable output, public void handleTag(boolean opening, String tag, Editable output,
XMLReader reader) { XMLReader reader) {
switch (tag) { switch (tag) {
case "ul": case "ul":
if (opening) { if (opening) {
@ -525,7 +525,7 @@ public final class Utils {
String versionName = null; String versionName = null;
try { try {
versionName = context.getPackageManager() versionName = context.getPackageManager()
.getPackageInfo(context.getPackageName(), 0).versionName; .getPackageInfo(context.getPackageName(), 0).versionName;
} catch (PackageManager.NameNotFoundException e) { } catch (PackageManager.NameNotFoundException e) {
Log.e(TAG, "Could not get client version name", e); Log.e(TAG, "Could not get client version name", e);
} }

View File

@ -25,7 +25,7 @@ public class Apk extends ValueObject implements Comparable<Apk>, Parcelable {
public int versionCode; public int versionCode;
public int size; // Size in bytes - 0 means we don't know! public int size; // Size in bytes - 0 means we don't know!
public long repo; // ID of the repo it comes from public long repo; // ID of the repo it comes from
public String hash; public String hash; // checksum of the APK, in lowercase hex
public String hashType; public String hashType;
public int minSdkVersion = SDK_VERSION_MIN_VALUE; // 0 if unknown public int minSdkVersion = SDK_VERSION_MIN_VALUE; // 0 if unknown
public int targetSdkVersion = SDK_VERSION_MIN_VALUE; // 0 if unknown public int targetSdkVersion = SDK_VERSION_MIN_VALUE; // 0 if unknown

View File

@ -120,7 +120,7 @@ class DBHelper extends SQLiteOpenHelper {
+ " );"; + " );";
private static final String DROP_TABLE_INSTALLED_APP = "DROP TABLE " + InstalledAppTable.NAME + ";"; private static final String DROP_TABLE_INSTALLED_APP = "DROP TABLE " + InstalledAppTable.NAME + ";";
private static final int DB_VERSION = 60; private static final int DB_VERSION = 61;
private final Context context; private final Context context;
@ -327,6 +327,16 @@ class DBHelper extends SQLiteOpenHelper {
migrateAppPrimaryKeyToRowId(db, oldVersion); migrateAppPrimaryKeyToRowId(db, oldVersion);
removeApkPackageNameColumn(db, oldVersion); removeApkPackageNameColumn(db, oldVersion);
addAppPrefsTable(db, oldVersion); addAppPrefsTable(db, oldVersion);
lowerCaseApkHashes(db, oldVersion);
}
private void lowerCaseApkHashes(SQLiteDatabase db, int oldVersion) {
if (oldVersion >= 61) {
return;
}
Utils.debugLog(TAG, "Lowercasing all APK hashes");
db.execSQL("UPDATE " + InstalledAppTable.NAME + " SET " + InstalledAppTable.Cols.HASH
+ " = lower(" + InstalledAppTable.Cols.HASH + ")");
} }
private void addAppPrefsTable(SQLiteDatabase db, int oldVersion) { private void addAppPrefsTable(SQLiteDatabase db, int oldVersion) {

View File

@ -470,7 +470,7 @@ public final class LocalRepoManager {
private void tagHash(App app) throws IOException { private void tagHash(App app) throws IOException {
serializer.startTag("", "hash"); serializer.startTag("", "hash");
serializer.attribute("", "type", app.installedApk.hashType); serializer.attribute("", "type", app.installedApk.hashType);
serializer.text(app.installedApk.hash.toLowerCase(Locale.US)); serializer.text(app.installedApk.hash);
serializer.endTag("", "hash"); serializer.endTag("", "hash");
} }
} }