Skip to content

Commit

Permalink
Fix a crash condition due invalid ZIP data
Browse files Browse the repository at this point in the history
  • Loading branch information
amadvance committed Feb 12, 2018
1 parent ea4f30c commit 7deeafc
Show file tree
Hide file tree
Showing 6 changed files with 26 additions and 11 deletions.
3 changes: 2 additions & 1 deletion HISTORY
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,11 @@
=======================


ADVANCECOMP VERSION 2.1 2018/01
ADVANCECOMP VERSION 2.1 2018/02
===============================

* Support ZIPs with data descriptor signature.
* Fixed a crash condition with invalid ZIP data.


ADVANCECOMP VERSION 2.0 2017/06
Expand Down
4 changes: 3 additions & 1 deletion doc/history.1
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
.TH "History For AdvanceCOMP" 1
.SH NAME
advcomp \- History For AdvanceCOMP
.SH ADVANCECOMP VERSION 2.1 2018/01
.SH ADVANCECOMP VERSION 2.1 2018/02
.PD 0
.IP \(bu
Support ZIPs with data descriptor signature.
.IP \(bu
Fixed a crash condition with invalid ZIP data.
.PD
.SH ADVANCECOMP VERSION 2.0 2017/06
.PD 0
Expand Down
3 changes: 2 additions & 1 deletion doc/history.d
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
Name
advcomp - History For AdvanceCOMP

AdvanceCOMP Version 2.1 2018/01
AdvanceCOMP Version 2.1 2018/02
) Support ZIPs with data descriptor signature.
) Fixed a crash condition with invalid ZIP data.

AdvanceCOMP Version 2.0 2017/06
) Added support for reading MNG files with depth of 1, 2, and 4 bits.
Expand Down
3 changes: 2 additions & 1 deletion doc/history.txt
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,11 @@
=======================


ADVANCECOMP VERSION 2.1 2018/01
ADVANCECOMP VERSION 2.1 2018/02
===============================

* Support ZIPs with data descriptor signature.
* Fixed a crash condition with invalid ZIP data.


ADVANCECOMP VERSION 2.0 2017/06
Expand Down
20 changes: 15 additions & 5 deletions zip.cc
Original file line number Diff line number Diff line change
Expand Up @@ -456,13 +456,15 @@ string zip_entry::name_get() const
}

/** Check central directory entry. */
void zip_entry::check_cent(const unsigned char* buf) const
void zip_entry::check_cent(const unsigned char* buf, unsigned buf_size) const
{
if (buf_size < ZIP_CO_FIXED) {
throw error_invalid() << "Invalid central directory data";
}
// check signature
if (le_uint32_read(buf+ZIP_CO_central_file_header_signature) != ZIP_C_signature) {
throw error_invalid() << "Invalid central directory signature";
}

// check filename_length > 0, can't exist a file without a name
if (le_uint16_read(buf+ZIP_CO_filename_length) == 0) {
throw error_invalid() << "Empty filename in central directory";
Expand Down Expand Up @@ -679,11 +681,11 @@ void zip_entry::save_local(FILE* f)
* \param buf Fixed size cent dir.
* \param f File seeked after the fixed size cent dir.
*/
void zip_entry::load_cent(const unsigned char* buf, unsigned& skip)
void zip_entry::load_cent(const unsigned char* buf, unsigned buf_size, unsigned& skip)
{
const unsigned char* o_buf = buf;

check_cent(buf);
check_cent(buf, buf_size);

// read header
info.version_made_by = le_uint8_read(buf+ZIP_CO_version_made_by);
Expand All @@ -705,6 +707,14 @@ void zip_entry::load_cent(const unsigned char* buf, unsigned& skip)
info.relative_offset_of_local_header = le_uint32_read(buf+ZIP_CO_relative_offset_of_local_header);
buf += ZIP_CO_FIXED;

if (buf_size < info.filename_length
|| buf_size < info.central_extra_field_length
|| buf_size < info.file_comment_length
|| buf_size < ZIP_CO_FIXED + info.filename_length + info.central_extra_field_length + info.file_comment_length
) {
throw error_invalid() << "Invalid central directory data";
}

// read filename
data_free(file_name);
file_name = data_alloc(info.filename_length);
Expand Down Expand Up @@ -853,7 +863,7 @@ void zip::open()

unsigned skip = 0;
try {
i->load_cent(data + data_pos, skip);
i->load_cent(data + data_pos, data_size - data_pos, skip);
} catch (...) {
map.erase(i);
throw;
Expand Down
4 changes: 2 additions & 2 deletions zip.h
Original file line number Diff line number Diff line change
Expand Up @@ -192,7 +192,7 @@ class zip_entry {
unsigned char* central_extra_field;
unsigned char* data;

void check_cent(const unsigned char* buf) const;
void check_cent(const unsigned char* buf, unsigned buf_size) const;
void check_local(const unsigned char* buf) const;
void check_descriptor(const unsigned char* buf) const;

Expand All @@ -208,7 +208,7 @@ class zip_entry {

void load_local(const unsigned char* buf, FILE* f, unsigned size);
void save_local(FILE* f);
void load_cent(const unsigned char* buf, unsigned& skip);
void load_cent(const unsigned char* buf, unsigned size, unsigned& skip);
void save_cent(FILE* f);
void unload();

Expand Down

0 comments on commit 7deeafc

Please sign in to comment.