From 76b1659177327a64037bf36d7f3e15a73d86bbed Mon Sep 17 00:00:00 2001 From: Jay Berkenbilt Date: Thu, 11 Aug 2011 11:56:37 -0400 Subject: enhance PointerHolder so that it can explicitly be told to use delete [] instead of delete, thus making it useful to run valgrind over qpdf during its test suite --- libqpdf/QPDF.cc | 7 ++--- libqpdf/QPDF_encryption.cc | 7 ++--- libqpdf/QPDF_linearization.cc | 2 +- libqpdf/qpdf-c.cc | 69 ++++++++++++++++++++++++++++++++++++++++--- 4 files changed, 71 insertions(+), 14 deletions(-) (limited to 'libqpdf') diff --git a/libqpdf/QPDF.cc b/libqpdf/QPDF.cc index d614efe5..d161aebc 100644 --- a/libqpdf/QPDF.cc +++ b/libqpdf/QPDF.cc @@ -403,10 +403,9 @@ QPDF::parse(char const* password) this->file->rewind(); } char* buf = new char[tbuf_size + 1]; - // Put buf in a PointerHolder to guarantee deletion of buf. This - // calls delete rather than delete [], but it's okay since buf is - // an array of fundamental types. - PointerHolder b(buf); + // Put buf in an array-style PointerHolder to guarantee deletion + // of buf. + PointerHolder b(true, buf); memset(buf, '\0', tbuf_size + 1); this->file->read(buf, tbuf_size); diff --git a/libqpdf/QPDF_encryption.cc b/libqpdf/QPDF_encryption.cc index d559388b..772d87e0 100644 --- a/libqpdf/QPDF_encryption.cc +++ b/libqpdf/QPDF_encryption.cc @@ -589,12 +589,9 @@ QPDF::decryptString(std::string& str, int objid, int generation) { QTC::TC("qpdf", "QPDF_encryption rc4 decode string"); unsigned int vlen = str.length(); - // Using PointerHolder will cause a new char[] to be deleted - // with delete instead of delete [], but it's okay since the - // array is of a fundamental type, so there is no destructor - // to be called. Using PointerHolder guarantees that tmp will + // Using PointerHolder guarantees that tmp will // be freed even if rc4.process throws an exception. - PointerHolder tmp = QUtil::copy_string(str); + PointerHolder tmp(true, QUtil::copy_string(str)); RC4 rc4((unsigned char const*)key.c_str(), key.length()); rc4.process((unsigned char*)tmp.getPointer(), vlen); str = std::string(tmp.getPointer(), vlen); diff --git a/libqpdf/QPDF_linearization.cc b/libqpdf/QPDF_linearization.cc index 51b6ea6a..eeae05e9 100644 --- a/libqpdf/QPDF_linearization.cc +++ b/libqpdf/QPDF_linearization.cc @@ -88,7 +88,7 @@ QPDF::isLinearized() char* buf = new char[tbuf_size]; this->file->seek(0, SEEK_SET); - PointerHolder b(buf); // guarantee deletion + PointerHolder b(true, buf); memset(buf, '\0', tbuf_size); this->file->read(buf, tbuf_size - 1); diff --git a/libqpdf/qpdf-c.cc b/libqpdf/qpdf-c.cc index 62dba270..784351bc 100644 --- a/libqpdf/qpdf-c.cc +++ b/libqpdf/qpdf-c.cc @@ -33,11 +33,15 @@ struct _qpdf_data char const* buffer; unsigned long size; char const* password; + bool write_memory; + Buffer* output_buffer; }; _qpdf_data::_qpdf_data() : qpdf(0), - qpdf_writer(0) + qpdf_writer(0), + write_memory(false), + output_buffer(0) { } @@ -45,6 +49,7 @@ _qpdf_data::~_qpdf_data() { delete qpdf_writer; delete qpdf; + delete output_buffer; } // must set qpdf->filename and qpdf->password @@ -66,6 +71,12 @@ static void call_init_write(qpdf_data qpdf) qpdf->qpdf_writer = new QPDFWriter(*(qpdf->qpdf), qpdf->filename); } +static void call_init_write_memory(qpdf_data qpdf) +{ + qpdf->qpdf_writer = new QPDFWriter(*(qpdf->qpdf)); + qpdf->qpdf_writer->setOutputMemory(); +} + static void call_write(qpdf_data qpdf) { qpdf->qpdf_writer->write(); @@ -408,21 +419,71 @@ QPDF_BOOL qpdf_allow_modify_all(qpdf_data qpdf) return qpdf->qpdf->allowModifyAll(); } -QPDF_ERROR_CODE qpdf_init_write(qpdf_data qpdf, char const* filename) +static void qpdf_init_write_internal(qpdf_data qpdf) { - QPDF_ERROR_CODE status = QPDF_SUCCESS; if (qpdf->qpdf_writer) { QTC::TC("qpdf", "qpdf-c called qpdf_init_write multiple times"); delete qpdf->qpdf_writer; qpdf->qpdf_writer = 0; + if (qpdf->output_buffer) + { + delete qpdf->output_buffer; + qpdf->output_buffer = 0; + qpdf->write_memory = false; + qpdf->filename = 0; + } } +} + +QPDF_ERROR_CODE qpdf_init_write(qpdf_data qpdf, char const* filename) +{ + qpdf_init_write_internal(qpdf); qpdf->filename = filename; - status = trap_errors(qpdf, &call_init_write); + QPDF_ERROR_CODE status = trap_errors(qpdf, &call_init_write); QTC::TC("qpdf", "qpdf-c called qpdf_init_write", status); return status; } +QPDF_ERROR_CODE qpdf_init_write_memory(qpdf_data qpdf) +{ + qpdf_init_write_internal(qpdf); + QPDF_ERROR_CODE status = trap_errors(qpdf, &call_init_write_memory); + QTC::TC("qpdf", "qpdf-c called qpdf_init_write_memory"); + qpdf->write_memory = true; + return status; +} + +static void qpdf_get_buffer_internal(qpdf_data qpdf) +{ + if (qpdf->write_memory && (qpdf->output_buffer == 0)) + { + qpdf->output_buffer = qpdf->qpdf_writer->getBuffer(); + } +} + +unsigned long qpdf_get_buffer_length(qpdf_data qpdf) +{ + qpdf_get_buffer_internal(qpdf); + unsigned long result = 0L; + if (qpdf->output_buffer) + { + result = qpdf->output_buffer->getSize(); + } + return result; +} + +unsigned char const* qpdf_get_buffer(qpdf_data qpdf) +{ + unsigned char const* result = 0; + qpdf_get_buffer_internal(qpdf); + if (qpdf->output_buffer) + { + result = qpdf->output_buffer->getBuffer(); + } + return result; +} + void qpdf_set_object_stream_mode(qpdf_data qpdf, qpdf_object_stream_e mode) { QTC::TC("qpdf", "qpdf-c called qpdf_set_object_stream_mode"); -- cgit v1.2.3-54-g00ecf