xar: add regression test for atou64 numeric field over-read
Exercise atou64() through a TOC numeric element (<inode>) read via the expat backend, which hands the parser its raw, non-NUL-terminated character-data buffer. Mirrors test_read_format_xar_base64_oob; build with ASan for the out-of-bounds coverage.
This commit is contained in:
1 parent
bad51bcc8d
commit
0352fe5033
3 files changed
+45
No files matched your search
@@ -1083,6 +1083,7 @@ libarchive_test_EXTRA_DIST=\
|
||||
libarchive/test/test_read_format_ustar_filename_koi8r.tar.Z.uu \
|
||||
libarchive/test/test_read_format_warc.warc.uu \
|
||||
libarchive/test/test_read_format_warc_incomplete.warc.uu \
|
||||
libarchive/test/test_read_format_xar_atou64_overread.xar.uu \
|
||||
libarchive/test/test_read_format_xar_base64_oob.xar.uu \
|
||||
libarchive/test/test_read_format_xar_doublelink.xar.uu \
|
||||
libarchive/test/test_read_format_xar_duplicate_filename_node.xar.uu \
|
||||
|
||||
@@ -1003,3 +1003,40 @@ DEFINE_TEST(test_read_format_xar_base64_oob)
|
||||
assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a));
|
||||
assertEqualInt(ARCHIVE_OK, archive_read_free(a));
|
||||
}
|
||||
|
||||
/*
|
||||
* A numeric TOC field (here <inode>) is parsed by atou64(). Under the
|
||||
* expat backend that function is handed the raw, non-NUL-terminated
|
||||
* character-data buffer (libxml2 masks this by passing a strlen'd copy).
|
||||
* The loop fetched the next digit with *++p before checking the remaining
|
||||
* count, so an all-digit field whose content ends at the parser buffer
|
||||
* read one byte past the supplied range. The parsed value is unchanged;
|
||||
* only the stray read is gone. Build with ASan to catch the over-read.
|
||||
*/
|
||||
DEFINE_TEST(test_read_format_xar_atou64_overread)
|
||||
{
|
||||
const char *reffile = "test_read_format_xar_atou64_overread.xar";
|
||||
struct archive_entry *ae;
|
||||
struct archive *a;
|
||||
int r;
|
||||
|
||||
extract_reference_file(reffile);
|
||||
assert((a = archive_read_new()) != NULL);
|
||||
assertA(0 == archive_read_support_filter_all(a));
|
||||
|
||||
r = archive_read_support_format_xar(a);
|
||||
if (r == ARCHIVE_WARN) {
|
||||
skipping("xar reading not fully supported on this platform");
|
||||
assertEqualInt(ARCHIVE_OK, archive_read_free(a));
|
||||
return;
|
||||
}
|
||||
|
||||
assertA(0 == archive_read_open_filename(a, reffile, 10240));
|
||||
|
||||
assertA(0 == archive_read_next_header(a, &ae));
|
||||
assertEqualString("num", archive_entry_pathname(ae));
|
||||
assertEqualInt(1234567890, archive_entry_ino64(ae));
|
||||
|
||||
assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a));
|
||||
assertEqualInt(ARCHIVE_OK, archive_read_free(a));
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
begin 644 test_read_format_xar_atou64_overread.xar
|
||||
M>&%R(0`<``$`````````AP````````"R`````'C:-8Y+#H,P#$3WG"+RGAKH
|
||||
MCTHF['J"]@"(N%4DXE245O3VS4>L_/0THS'UJYO4E^>W]=)!O:M`L8S>6'EV
|
||||
M<+]=RQ9Z7=`ZS+I0BA8_QAOH82=6UH0.9!.<#(ZU?!QAHDTOOQ?KF"=,N'DK
|
||||
<WK"NF_WA>#JWEXHPFSR`L9%&,:T2IB?^<Y@PE```
|
||||
`
|
||||
end
|
||||
Reference in new issue
Block a user