diff options
author | Sebastian Freundt <freundt@ga-group.nl> | 2014-05-21 12:32:50 +0000 |
---|---|---|
committer | Sebastian Freundt <freundt@ga-group.nl> | 2014-05-21 12:32:50 +0000 |
commit | faa12ea4c2ce2898cd009d4d14cb4aa6e07620a0 (patch) | |
tree | 4285312b1fcdaff8e587625aa21660cc3cf66415 /libarchive/archive_write_set_format_warc.c | |
parent | af78448244b39da3c2a867d5c9fccc1909e1c0aa (diff) | |
download | libarchive-faa12ea4c2ce2898cd009d4d14cb4aa6e07620a0.tar.gz |
fix, never write more bytes in _warc_data() than ...
previously announce in _warc_header().
The test suite (as is) is one offender. It populates a 9-byte string, mimicking an IFREG file
but by the time the header makes it into the archive, the size changes from 0 to 9.
Diffstat (limited to 'libarchive/archive_write_set_format_warc.c')
-rw-r--r-- | libarchive/archive_write_set_format_warc.c | 14 |
1 files changed, 13 insertions, 1 deletions
diff --git a/libarchive/archive_write_set_format_warc.c b/libarchive/archive_write_set_format_warc.c index 6c7b8c7e..82c603ee 100644 --- a/libarchive/archive_write_set_format_warc.c +++ b/libarchive/archive_write_set_format_warc.c @@ -54,6 +54,8 @@ struct warc_s { time_t now; mode_t typ; unsigned int rng; + /* populated size */ + size_t populz; }; static const char warcinfo[] = "\ @@ -213,6 +215,7 @@ _warc_header(struct archive_write *a, struct archive_entry *entry) } w->typ = archive_entry_filetype(entry); + w->populz = 0U; if (w->typ == AE_IFREG) { warc_essential_hdr_t rh = { WT_RSRC, @@ -235,6 +238,8 @@ _warc_header(struct archive_write *a, struct archive_entry *entry) } /* otherwise append to output stream */ __archive_write_output(a, hdr, r); + /* and let subsequent calls to _data() know about the size */ + w->populz = rh.cntlen; } /* just pretend it's all good */ return (ARCHIVE_OK); @@ -246,8 +251,15 @@ _warc_data(struct archive_write *a, const void *buf, size_t len) struct warc_s *w = a->format_data; if (w->typ == AE_IFREG) { - int rc = __archive_write_output(a, buf, len); + int rc; + /* never write more bytes than announced */ + if (len > w->populz) { + len = w->populz; + } + + /* now then, out we put the whole shebang */ + rc = __archive_write_output(a, buf, len); if (rc != ARCHIVE_OK) { return rc; } |