2
1
mirror of https://github.com/qpdf/qpdf.git synced 2024-12-22 10:58:58 +00:00

Pl_Flate: constructor's out_bufsize is now unsigned int

This is the type we need for the underlying zlib implementation.
This commit is contained in:
Jay Berkenbilt 2019-06-21 00:01:36 -04:00
parent da30764bce
commit f40ffc9d63
3 changed files with 31 additions and 11 deletions

View File

@ -1,5 +1,9 @@
2019-06-20 Jay Berkenbilt <ejb@ql.org> 2019-06-20 Jay Berkenbilt <ejb@ql.org>
* Change out_bufsize argument to Pl_Flate's constructor for int to
unsigned int for compatibility with underlying zlib
implementation.
* Add methods to QPDFObjectHandle to return the value of Integer * Add methods to QPDFObjectHandle to return the value of Integer
objects as int and unsigned int with range checking and fallback objects as int and unsigned int with range checking and fallback
behavior to avoid silent underflow/overflow conditions. behavior to avoid silent underflow/overflow conditions.

View File

@ -27,13 +27,13 @@
class Pl_Flate: public Pipeline class Pl_Flate: public Pipeline
{ {
public: public:
static int const def_bufsize = 65536; static unsigned int const def_bufsize = 65536;
enum action_e { a_inflate, a_deflate }; enum action_e { a_inflate, a_deflate };
QPDF_DLL QPDF_DLL
Pl_Flate(char const* identifier, Pipeline* next, Pl_Flate(char const* identifier, Pipeline* next,
action_e action, int out_bufsize = def_bufsize); action_e action, unsigned int out_bufsize = def_bufsize);
QPDF_DLL QPDF_DLL
virtual ~Pl_Flate(); virtual ~Pl_Flate();
@ -43,11 +43,11 @@ class Pl_Flate: public Pipeline
virtual void finish(); virtual void finish();
private: private:
void handleData(unsigned char* data, int len, int flush); void handleData(unsigned char* data, size_t len, int flush);
void checkError(char const* prefix, int error_code); void checkError(char const* prefix, int error_code);
unsigned char* outbuf; unsigned char* outbuf;
int out_bufsize; size_t out_bufsize;
action_e action; action_e action;
bool initialized; bool initialized;
void* zdata; void* zdata;

View File

@ -1,13 +1,15 @@
#include <qpdf/Pl_Flate.hh> #include <qpdf/Pl_Flate.hh>
#include <zlib.h> #include <zlib.h>
#include <string.h> #include <string.h>
#include <limits.h>
#include <qpdf/QUtil.hh> #include <qpdf/QUtil.hh>
#include <qpdf/QIntC.hh>
Pl_Flate::Pl_Flate(char const* identifier, Pipeline* next, Pl_Flate::Pl_Flate(char const* identifier, Pipeline* next,
action_e action, int out_bufsize) : action_e action, unsigned int out_bufsize_int) :
Pipeline(identifier, next), Pipeline(identifier, next),
out_bufsize(out_bufsize), out_bufsize(QIntC::to_size(out_bufsize_int)),
action(action), action(action),
initialized(false) initialized(false)
{ {
@ -19,6 +21,13 @@ Pl_Flate::Pl_Flate(char const* identifier, Pipeline* next,
// Windows environment. // Windows environment.
this->zdata = new z_stream; this->zdata = new z_stream;
if (out_bufsize > UINT_MAX)
{
throw std::runtime_error(
"Pl_Flate: zlib doesn't support buffer"
" sizes larger than unsigned int");
}
z_stream& zstream = *(static_cast<z_stream*>(this->zdata)); z_stream& zstream = *(static_cast<z_stream*>(this->zdata));
zstream.zalloc = 0; zstream.zalloc = 0;
zstream.zfree = 0; zstream.zfree = 0;
@ -26,7 +35,7 @@ Pl_Flate::Pl_Flate(char const* identifier, Pipeline* next,
zstream.next_in = 0; zstream.next_in = 0;
zstream.avail_in = 0; zstream.avail_in = 0;
zstream.next_out = this->outbuf; zstream.next_out = this->outbuf;
zstream.avail_out = out_bufsize; zstream.avail_out = QIntC::to_uint(out_bufsize);
} }
Pl_Flate::~Pl_Flate() Pl_Flate::~Pl_Flate()
@ -77,11 +86,17 @@ Pl_Flate::write(unsigned char* data, size_t len)
} }
void void
Pl_Flate::handleData(unsigned char* data, int len, int flush) Pl_Flate::handleData(unsigned char* data, size_t len, int flush)
{ {
if (len > UINT_MAX)
{
throw std::runtime_error(
"Pl_Flate: zlib doesn't support data"
" blocks larger than int");
}
z_stream& zstream = *(static_cast<z_stream*>(this->zdata)); z_stream& zstream = *(static_cast<z_stream*>(this->zdata));
zstream.next_in = data; zstream.next_in = data;
zstream.avail_in = len; zstream.avail_in = QIntC::to_uint(len);
if (! this->initialized) if (! this->initialized)
{ {
@ -156,12 +171,13 @@ Pl_Flate::handleData(unsigned char* data, int len, int flush)
// needed, so we're done for now. // needed, so we're done for now.
done = true; done = true;
} }
uLong ready = (this->out_bufsize - zstream.avail_out); uLong ready =
QIntC::to_ulong(this->out_bufsize - zstream.avail_out);
if (ready > 0) if (ready > 0)
{ {
this->getNext()->write(this->outbuf, ready); this->getNext()->write(this->outbuf, ready);
zstream.next_out = this->outbuf; zstream.next_out = this->outbuf;
zstream.avail_out = this->out_bufsize; zstream.avail_out = QIntC::to_uint(this->out_bufsize);
} }
} }
break; break;