diff mbox

[pacman-dev] be_sync: error out if a db cannot be parsed

Message ID 20170417032832.31445-1-andrew.gregory.8@gmail.com
State Accepted, archived
Headers show

Commit Message

Andrew Gregory April 17, 2017, 3:28 a.m. UTC
Signed-off-by: Andrew Gregory <andrew.gregory.8@gmail.com>
---

See FS#49342 for an example of how to break a database in a way that was
previously silently ignored.  The linked github issue includes a copy of an
actual broken db.

 lib/libalpm/be_sync.c | 17 ++++++++++++-----
 1 file changed, 12 insertions(+), 5 deletions(-)

Comments

Allan McRae April 17, 2017, 9:06 a.m. UTC | #1
On 17/04/17 13:28, Andrew Gregory wrote:
> Signed-off-by: Andrew Gregory <andrew.gregory.8@gmail.com>
> ---
> 
> See FS#49342 for an example of how to break a database in a way that was
> previously silently ignored.  The linked github issue includes a copy of an
> actual broken db.
> 

Looks like the ideal solution requires libarchive changes.  This is the
best we can do at our end for the time being.

Thanks,
Allan
diff mbox

Patch

diff --git a/lib/libalpm/be_sync.c b/lib/libalpm/be_sync.c
index 5f7d31ab..06f509a6 100644
--- a/lib/libalpm/be_sync.c
+++ b/lib/libalpm/be_sync.c
@@ -465,6 +465,7 @@  static int sync_db_populate(alpm_db_t *db)
 	size_t est_count, count;
 	int fd;
 	int ret = 0;
+	int archive_ret;
 	struct stat buf;
 	struct archive *archive;
 	struct archive_entry *entry;
@@ -502,20 +503,26 @@  static int sync_db_populate(alpm_db_t *db)
 		goto cleanup;
 	}
 
-	while(archive_read_next_header(archive, &entry) == ARCHIVE_OK) {
+	while((archive_ret = archive_read_next_header(archive, &entry)) == ARCHIVE_OK) {
 		mode_t mode = archive_entry_mode(entry);
-		if(S_ISDIR(mode)) {
-			continue;
-		} else {
+		if(!S_ISDIR(mode)) {
 			/* we have desc, depends or deltas - parse it */
 			if(sync_db_read(db, archive, entry, &pkg) != 0) {
 				_alpm_log(db->handle, ALPM_LOG_ERROR,
 						_("could not parse package description file '%s' from db '%s'\n"),
 						archive_entry_pathname(entry), db->treename);
-				continue;
+				ret = -1;
 			}
 		}
 	}
+	if(archive_ret != ARCHIVE_EOF) {
+		_alpm_log(db->handle, ALPM_LOG_ERROR, _("could not read db '%s' (%s)\n"),
+				db->treename, archive_error_string(archive));
+		_alpm_db_free_pkgcache(db);
+		db->handle->pm_errno = ALPM_ERR_LIBARCHIVE;
+		ret = -1;
+		goto cleanup;
+	}
 
 	count = alpm_list_count(db->pkgcache->list);
 	if(count > 0) {