Mercurial > hg > openttd
changeset 15063:9bc57c18fb40 draft
(svn r19686) -Fix (r15126): truncated archives were not detected when using zlib 1.2.3. This also fixes zlib 1.2.4 compatibility, zlib 1.2.5 is bugfree
author | smatz <smatz@openttd.org> |
---|---|
date | Wed, 21 Apr 2010 11:42:00 +0000 |
parents | 4ae8e013d8e4 |
children | a34ec81b63b0 |
files | src/network/network_content.cpp |
diffstat | 1 files changed, 29 insertions(+), 10 deletions(-) [+] |
line wrap: on
line diff
--- a/src/network/network_content.cpp +++ b/src/network/network_content.cpp @@ -373,19 +373,38 @@ if (fin == NULL || fout == NULL) { ret = false; - goto exit; - } - - byte buff[8192]; - while (!gzeof(fin)) { - int read = gzread(fin, buff, sizeof(buff)); - if (read < 0 || (size_t)read != fwrite(buff, 1, read, fout)) { - ret = false; - break; + } else { + byte buff[8192]; + while (1) { + int read = gzread(fin, buff, sizeof(buff)); + if (read == 0) { + /* If gzread() returns 0, either the end-of-file has been + * reached or an underlying read error has occurred. + * + * gzeof() can't be used, because: + * 1.2.5 - it is safe, 1 means 'everything was OK' + * 1.2.3.5, 1.2.4 - 0 or 1 is returned 'randomly' + * 1.2.3.3 - 1 is returned for truncated archive + * + * So we use gzerror(). When proper end of archive + * has been reached, then: + * errnum == Z_STREAM_END in 1.2.3.3, + * errnum == 0 in 1.2.4 and 1.2.5 */ + int errnum; + gzerror(fin, &errnum); + if (errnum != 0 && errnum != Z_STREAM_END) ret = false; + break; + } + if (read < 0 || (size_t)read != fwrite(buff, 1, read, fout)) { + /* If gzread() returns -1, there was an error in archive */ + ret = false; + break; + } + /* DO NOT DO THIS! It will fail to detect broken archive with 1.2.3.3! + * if (read < sizeof(buff)) break; */ } } -exit: if (fin != NULL) { /* Closes ftmp too! */ gzclose(fin);