archive_write: test format switch UAF cleanup

Test that unregistering 7-Zip and XAR clears format state and is safe
to repeat.

Also test switching from 7-Zip to GNU tar and selecting GNU tar again.
This commit is contained in:
datauwu committed 2026-07-18 00:05:01 +08:00
1 parent 0362c77f9f
commit 9c805a24ea
3 files changed
+93

No files matched your search

+39
View File
@@ -26,6 +26,9 @@
#include "test.h"
#define __LIBARCHIVE_TEST
#include "archive_write_private.h"
static void
test_basic(const char *compression_type)
{
@@ -573,3 +576,39 @@ DEFINE_TEST(test_write_format_7zip_basic_zstd)
/* Test that making a 7-Zip archive file with zstandard compression. */
test_basic("zstd");
}
DEFINE_TEST(test_write_format_7zip_unregister)
{
struct archive *a;
struct archive_write *aw;
assert((a = archive_write_new()) != NULL);
assertEqualIntA(a, ARCHIVE_OK, archive_write_set_format_7zip(a));
aw = (struct archive_write *)a;
assert(aw->format_data != NULL);
assert(aw->format_free != NULL);
assertEqualIntA(a, ARCHIVE_OK,
__archive_write_unregister_format(aw));
assert(aw->format_data == NULL);
assert(aw->format_name == NULL);
assert(aw->format_init == NULL);
assert(aw->format_options == NULL);
assert(aw->format_finish_entry == NULL);
assert(aw->format_write_header == NULL);
assert(aw->format_write_data == NULL);
assert(aw->format_close == NULL);
assert(aw->format_free == NULL);
assertEqualInt(0, aw->archive.archive_format);
assert(aw->archive.archive_format_name == NULL);
assertEqualIntA(a, ARCHIVE_FAILED,
archive_write_set_format_option(a, NULL, "compression",
"store"));
assertEqualIntA(a, ARCHIVE_OK,
__archive_write_unregister_format(aw));
assertEqualInt(ARCHIVE_OK, archive_write_free(a));
}
@@ -278,3 +278,14 @@ DEFINE_TEST(test_write_format_gnutar)
free(buff);
}
DEFINE_TEST(test_write_format_gnutar_switch)
{
struct archive *a;
assert((a = archive_write_new()) != NULL);
assertEqualIntA(a, ARCHIVE_OK, archive_write_set_format_7zip(a));
assertEqualIntA(a, ARCHIVE_OK, archive_write_set_format_gnutar(a));
assertEqualIntA(a, ARCHIVE_OK, archive_write_set_format_gnutar(a));
assertEqualInt(ARCHIVE_OK, archive_write_free(a));
}
+43
View File
@@ -25,6 +25,9 @@
*/
#include "test.h"
#define __LIBARCHIVE_TEST
#include "archive_write_private.h"
#include <locale.h>
static void
@@ -380,3 +383,43 @@ DEFINE_TEST(test_write_format_xar_entry_trunc)
assertEqualIntA(a, ARCHIVE_OK, archive_write_close(a));
assertEqualInt(ARCHIVE_OK, archive_write_free(a));
}
DEFINE_TEST(test_write_format_xar_unregister)
{
struct archive *a;
struct archive_write *aw;
assert((a = archive_write_new()) != NULL);
if (archive_write_set_format_xar(a) != ARCHIVE_OK) {
skipping("xar is not supported on this platform");
assertEqualInt(ARCHIVE_OK, archive_write_free(a));
return;
}
aw = (struct archive_write *)a;
assert(aw->format_data != NULL);
assert(aw->format_free != NULL);
assertEqualIntA(a, ARCHIVE_OK,
__archive_write_unregister_format(aw));
assert(aw->format_data == NULL);
assert(aw->format_name == NULL);
assert(aw->format_init == NULL);
assert(aw->format_options == NULL);
assert(aw->format_finish_entry == NULL);
assert(aw->format_write_header == NULL);
assert(aw->format_write_data == NULL);
assert(aw->format_close == NULL);
assert(aw->format_free == NULL);
assertEqualInt(0, aw->archive.archive_format);
assert(aw->archive.archive_format_name == NULL);
assertEqualIntA(a, ARCHIVE_FAILED,
archive_write_set_format_option(a, NULL, "compression",
"gzip"));
assertEqualIntA(a, ARCHIVE_OK,
__archive_write_unregister_format(aw));
assertEqualInt(ARCHIVE_OK, archive_write_free(a));
}