summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRoss Lagerwall <rosslagerwall@gmail.com>2014-08-20 20:50:07 +0100
committerRoss Lagerwall <rosslagerwall@gmail.com>2014-08-23 08:25:58 +0100
commit3e5c3085b680101d95ae6b3ddcef3cae2b12f099 (patch)
tree1f6f2f22bc2970b04d518abcb81dc0c0386fc007
parent26b4b1d00eb77e54f72d5ed7c1867bcf796094c1 (diff)
downloadgvfs-3e5c3085b680101d95ae6b3ddcef3cae2b12f099.tar.gz
archive: Retry operations that return ARCHIVE_RETRY
Retry operations that return ARCHIVE_RETRY since it indicates that the operation has failed, the archive_entry is not valid, and the operation should be retried to see if it succeeds. This fixes a segfault on a truncated archive where archive_read_next_header would return ARCHIVE_RETRY and the backend would continue to try and use the invalid archive_entry that was returned. https://bugzilla.gnome.org/show_bug.cgi?id=735120
-rw-r--r--daemon/gvfsbackendarchive.c6
1 files changed, 6 insertions, 0 deletions
diff --git a/daemon/gvfsbackendarchive.c b/daemon/gvfsbackendarchive.c
index 0377c70c..32c9c5c2 100644
--- a/daemon/gvfsbackendarchive.c
+++ b/daemon/gvfsbackendarchive.c
@@ -375,6 +375,8 @@ archive_entry_determine_size (GVfsArchive *archive,
DEBUG ("archive_read_data_block: result = %d, error = '%s'\n", result, archive_error_string (archive->archive));
archive_set_error (archive->archive, ARCHIVE_OK, "No error");
archive_clear_error (archive->archive);
+ if (result == ARCHIVE_RETRY)
+ continue;
}
size += read;
@@ -540,6 +542,8 @@ create_file_tree (GVfsBackendArchive *ba, GVfsJob *job)
DEBUG ("archive_read_next_header: result = %d, error = '%s'\n", result, archive_error_string (archive->archive));
archive_set_error (archive->archive, ARCHIVE_OK, "No error");
archive_clear_error (archive->archive);
+ if (result == ARCHIVE_RETRY)
+ continue;
}
ArchiveFile *file = archive_file_get_from_path (ba->files,
@@ -725,6 +729,8 @@ do_open_for_read (GVfsBackend * backend,
DEBUG ("do_open_for_read: result = %d, error = '%s'\n", result, archive_error_string (archive->archive));
archive_set_error (archive->archive, ARCHIVE_OK, "No error");
archive_clear_error (archive->archive);
+ if (result == ARCHIVE_RETRY)
+ continue;
}
entry_pathname = archive_entry_pathname (entry);