Skip to content

Commit

Permalink
Pl_Flate: constructor's out_bufsize is now unsigned int
Browse files Browse the repository at this point in the history
This is the type we need for the underlying zlib implementation.
  • Loading branch information
jberkenbilt committed Jun 21, 2019
1 parent da30764 commit f40ffc9
Show file tree
Hide file tree
Showing 3 changed files with 31 additions and 11 deletions.
4 changes: 4 additions & 0 deletions ChangeLog
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
2019-06-20 Jay Berkenbilt <[email protected]>

* 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
objects as int and unsigned int with range checking and fallback
behavior to avoid silent underflow/overflow conditions.
Expand Down
8 changes: 4 additions & 4 deletions include/qpdf/Pl_Flate.hh
Original file line number Diff line number Diff line change
Expand Up @@ -27,13 +27,13 @@
class Pl_Flate: public Pipeline
{
public:
static int const def_bufsize = 65536;
static unsigned int const def_bufsize = 65536;

enum action_e { a_inflate, a_deflate };

QPDF_DLL
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
virtual ~Pl_Flate();

Expand All @@ -43,11 +43,11 @@ class Pl_Flate: public Pipeline
virtual void finish();

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);

unsigned char* outbuf;
int out_bufsize;
size_t out_bufsize;
action_e action;
bool initialized;
void* zdata;
Expand Down
30 changes: 23 additions & 7 deletions libqpdf/Pl_Flate.cc
Original file line number Diff line number Diff line change
@@ -1,13 +1,15 @@
#include <qpdf/Pl_Flate.hh>
#include <zlib.h>
#include <string.h>
#include <limits.h>

#include <qpdf/QUtil.hh>
#include <qpdf/QIntC.hh>

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),
out_bufsize(out_bufsize),
out_bufsize(QIntC::to_size(out_bufsize_int)),
action(action),
initialized(false)
{
Expand All @@ -19,14 +21,21 @@ Pl_Flate::Pl_Flate(char const* identifier, Pipeline* next,
// Windows environment.
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));
zstream.zalloc = 0;
zstream.zfree = 0;
zstream.opaque = 0;
zstream.next_in = 0;
zstream.avail_in = 0;
zstream.next_out = this->outbuf;
zstream.avail_out = out_bufsize;
zstream.avail_out = QIntC::to_uint(out_bufsize);
}

Pl_Flate::~Pl_Flate()
Expand Down Expand Up @@ -77,11 +86,17 @@ Pl_Flate::write(unsigned char* data, size_t len)
}

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));
zstream.next_in = data;
zstream.avail_in = len;
zstream.avail_in = QIntC::to_uint(len);

if (! this->initialized)
{
Expand Down Expand Up @@ -156,12 +171,13 @@ Pl_Flate::handleData(unsigned char* data, int len, int flush)
// needed, so we're done for now.
done = true;
}
uLong ready = (this->out_bufsize - zstream.avail_out);
uLong ready =
QIntC::to_ulong(this->out_bufsize - zstream.avail_out);
if (ready > 0)
{
this->getNext()->write(this->outbuf, ready);
zstream.next_out = this->outbuf;
zstream.avail_out = this->out_bufsize;
zstream.avail_out = QIntC::to_uint(this->out_bufsize);
}
}
break;
Expand Down

0 comments on commit f40ffc9

Please sign in to comment.