diff options
author | Ross Lagerwall <rosslagerwall@gmail.com> | 2014-08-20 20:50:07 +0100 |
---|---|---|
committer | Ross Lagerwall <rosslagerwall@gmail.com> | 2014-08-23 08:25:58 +0100 |
commit | 3e5c3085b680101d95ae6b3ddcef3cae2b12f099 (patch) | |
tree | 1f6f2f22bc2970b04d518abcb81dc0c0386fc007 | |
parent | 26b4b1d00eb77e54f72d5ed7c1867bcf796094c1 (diff) | |
download | gvfs-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.c | 6 |
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); |