Merge branch '2662-invalid-repo-crash' into 'master'

Don't crash on invalid repo certificates

Closes #2662

See merge request fdroid/fdroidclient!1270
This commit is contained in:
Torsten Grote
2023-08-07 09:25:10 +00:00
4 changed files with 48 additions and 16 deletions

View File

@@ -82,16 +82,22 @@ public class DBHelper {
addresses.add(address);
}
}
InitialRepository repo = new InitialRepository(
initialRepos.get(i), // name
addresses.get(0), // primary address (by convention: the first item)
addresses.subList(1, addresses.size()), // list of mirrors
initialRepos.get(i + 2), // description
initialRepos.get(i + 6), // certificate
Integer.parseInt(initialRepos.get(i + 3)), // version
enabled, // enabled
weight++ // weight
);
InitialRepository repo;
try {
repo = new InitialRepository(
initialRepos.get(i), // name
addresses.get(0), // primary address (by convention: the first item)
addresses.subList(1, addresses.size()), // list of mirrors
initialRepos.get(i + 2), // description
initialRepos.get(i + 6), // certificate
Integer.parseInt(initialRepos.get(i + 3)), // version
enabled, // enabled
weight++ // weight
);
} catch (IllegalArgumentException e) {
Log.e(TAG, "Invalid repo: " + addresses.get(0), e);
continue;
}
hasEnabledRepo = hasEnabledRepo || enabled;
db.getRepositoryDao().insert(repo);
}

View File

@@ -12,6 +12,7 @@ import android.os.Bundle;
import android.os.Parcelable;
import android.text.TextUtils;
import android.text.format.DateUtils;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuItem;
@@ -158,8 +159,12 @@ public class RepoDetailsActivity extends AppCompatActivity {
}
Uri uri = Uri.parse(repo.getAddress());
if (repo.getFingerprint() != null) {
uri = uri.buildUpon().appendQueryParameter("fingerprint", repo.getFingerprint()).build();
try {
if (repo.getFingerprint() != null) {
uri = uri.buildUpon().appendQueryParameter("fingerprint", repo.getFingerprint()).build();
}
} catch (Exception e) {
Log.e(TAG, "Invalid repo fingerprint: " + repo.getAddress());
}
String qrUriString = uri.toString();
disposable = Utils.generateQrBitmap(this, qrUriString)
@@ -297,8 +302,13 @@ public class RepoDetailsActivity extends AppCompatActivity {
private void prepareShareMenuItems(Menu menu) {
if (!TextUtils.isEmpty(repo.getAddress())) {
if (!TextUtils.isEmpty(repo.getCertificate())) {
shareUrl = Uri.parse(repo.getAddress()).buildUpon()
.appendQueryParameter("fingerprint", repo.getFingerprint()).toString();
try {
shareUrl = Uri.parse(repo.getAddress()).buildUpon()
.appendQueryParameter("fingerprint", repo.getFingerprint()).toString();
} catch (Exception e) {
Log.e(TAG, "Invalid repo fingerprint: " + repo.getAddress());
shareUrl = repo.getAddress();
}
} else {
shareUrl = repo.getAddress();
}

View File

@@ -32,7 +32,7 @@ internal class RepositoryDaoTest : DbTest() {
address = getRandomString(),
mirrors = listOf(getRandomString(), getRandomString(), getRandomString()),
description = getRandomString(),
certificate = getRandomString(),
certificate = "abcdef", // not random, because format gets checked
version = Random.nextLong(),
enabled = Random.nextBoolean(),
weight = Random.nextInt(),

View File

@@ -36,6 +36,11 @@ internal data class CoreRepository(
internal companion object {
const val TABLE = "CoreRepository"
}
init {
// TODO comment in some time after #2662 had time to resolve itself
// validateCertificate(certificate)
}
}
internal fun RepoV2.toCoreRepository(
@@ -384,4 +389,15 @@ public data class InitialRepository @JvmOverloads constructor(
val version: Long,
val enabled: Boolean,
val weight: Int,
)
) {
init {
validateCertificate(certificate)
}
}
@Throws(IllegalArgumentException::class)
private fun validateCertificate(certificate: String?) {
if (certificate != null) require(certificate.length % 2 == 0 &&
certificate.chunked(2).find { it.toIntOrNull(16) == null } == null
) { "Invalid certificate: $certificate" }
}