Commit 6c39aa87638f7a6f96a97627ac112fb2022bd3a7

Authored by Jay Berkenbilt
1 parent 12400475

In shippable code, favor smart pointers (fixes #235)

Use PointerHolder in several places where manually memory allocation
and deallocation were being used. This helps to protect against memory
leaks when exceptions are thrown in surprising places.
ChangeLog
1 2019-06-22 Jay Berkenbilt <ejb@ql.org> 1 2019-06-22 Jay Berkenbilt <ejb@ql.org>
2 2
  3 + * Favor PointerHolder over manual memory allocation in shippable
  4 + code where possible. Fixes #235.
  5 +
3 * If pkg-config is available, use it to local libjpeg and zlib. If 6 * If pkg-config is available, use it to local libjpeg and zlib. If
4 not, fall back to old behavior. Fixes #324. 7 not, fall back to old behavior. Fixes #324.
5 8
include/qpdf/ClosedFileInputSource.hh
@@ -82,7 +82,7 @@ class ClosedFileInputSource: public InputSource @@ -82,7 +82,7 @@ class ClosedFileInputSource: public InputSource
82 82
83 std::string filename; 83 std::string filename;
84 qpdf_offset_t offset; 84 qpdf_offset_t offset;
85 - FileInputSource* fis; 85 + PointerHolder<FileInputSource> fis;
86 bool stay_open; 86 bool stay_open;
87 }; 87 };
88 PointerHolder<Members> m; 88 PointerHolder<Members> m;
include/qpdf/Pl_Flate.hh
@@ -58,7 +58,7 @@ class Pl_Flate: public Pipeline @@ -58,7 +58,7 @@ class Pl_Flate: public Pipeline
58 Members(size_t out_bufsize, action_e action); 58 Members(size_t out_bufsize, action_e action);
59 Members(Members const&); 59 Members(Members const&);
60 60
61 - unsigned char* outbuf; 61 + PointerHolder<unsigned char> outbuf;
62 size_t out_bufsize; 62 size_t out_bufsize;
63 action_e action; 63 action_e action;
64 bool initialized; 64 bool initialized;
libqpdf/ClosedFileInputSource.cc
@@ -4,14 +4,12 @@ @@ -4,14 +4,12 @@
4 ClosedFileInputSource::Members::Members(char const* filename) : 4 ClosedFileInputSource::Members::Members(char const* filename) :
5 filename(filename), 5 filename(filename),
6 offset(0), 6 offset(0),
7 - fis(0),  
8 stay_open(false) 7 stay_open(false)
9 { 8 {
10 } 9 }
11 10
12 ClosedFileInputSource::Members::~Members() 11 ClosedFileInputSource::Members::~Members()
13 { 12 {
14 - delete fis;  
15 } 13 }
16 14
17 ClosedFileInputSource::ClosedFileInputSource(char const* filename) : 15 ClosedFileInputSource::ClosedFileInputSource(char const* filename) :
@@ -26,7 +24,7 @@ ClosedFileInputSource::~ClosedFileInputSource() @@ -26,7 +24,7 @@ ClosedFileInputSource::~ClosedFileInputSource()
26 void 24 void
27 ClosedFileInputSource::before() 25 ClosedFileInputSource::before()
28 { 26 {
29 - if (0 == this->m->fis) 27 + if (0 == this->m->fis.getPointer())
30 { 28 {
31 this->m->fis = new FileInputSource(); 29 this->m->fis = new FileInputSource();
32 this->m->fis->setFilename(this->m->filename.c_str()); 30 this->m->fis->setFilename(this->m->filename.c_str());
@@ -44,7 +42,6 @@ ClosedFileInputSource::after() @@ -44,7 +42,6 @@ ClosedFileInputSource::after()
44 { 42 {
45 return; 43 return;
46 } 44 }
47 - delete this->m->fis;  
48 this->m->fis = 0; 45 this->m->fis = 0;
49 } 46 }
50 47
@@ -84,7 +81,7 @@ void @@ -84,7 +81,7 @@ void
84 ClosedFileInputSource::rewind() 81 ClosedFileInputSource::rewind()
85 { 82 {
86 this->m->offset = 0; 83 this->m->offset = 0;
87 - if (this->m->fis) 84 + if (this->m->fis.getPointer())
88 { 85 {
89 this->m->fis->rewind(); 86 this->m->fis->rewind();
90 } 87 }
@@ -112,7 +109,7 @@ void @@ -112,7 +109,7 @@ void
112 ClosedFileInputSource::stayOpen(bool val) 109 ClosedFileInputSource::stayOpen(bool val)
113 { 110 {
114 this->m->stay_open = val; 111 this->m->stay_open = val;
115 - if ((! val) && this->m->fis) 112 + if ((! val) && this->m->fis.getPointer())
116 { 113 {
117 after(); 114 after();
118 } 115 }
libqpdf/Pl_AES_PDF.cc
@@ -25,29 +25,31 @@ Pl_AES_PDF::Pl_AES_PDF(char const* identifier, Pipeline* next, @@ -25,29 +25,31 @@ Pl_AES_PDF::Pl_AES_PDF(char const* identifier, Pipeline* next,
25 { 25 {
26 size_t keybits = 8 * key_bytes; 26 size_t keybits = 8 * key_bytes;
27 assert(key_bytes == KEYLENGTH(keybits)); 27 assert(key_bytes == KEYLENGTH(keybits));
28 - this->key = new unsigned char[key_bytes];  
29 - this->rk = new uint32_t[RKLENGTH(keybits)]; 28 + this->key = PointerHolder<unsigned char>(
  29 + true, new unsigned char[key_bytes]);
  30 + this->rk = PointerHolder<uint32_t>(
  31 + true, new uint32_t[RKLENGTH(keybits)]);
30 size_t rk_bytes = RKLENGTH(keybits) * sizeof(uint32_t); 32 size_t rk_bytes = RKLENGTH(keybits) * sizeof(uint32_t);
31 - std::memcpy(this->key, key, key_bytes);  
32 - std::memset(this->rk, 0, rk_bytes); 33 + std::memcpy(this->key.getPointer(), key, key_bytes);
  34 + std::memset(this->rk.getPointer(), 0, rk_bytes);
33 std::memset(this->inbuf, 0, this->buf_size); 35 std::memset(this->inbuf, 0, this->buf_size);
34 std::memset(this->outbuf, 0, this->buf_size); 36 std::memset(this->outbuf, 0, this->buf_size);
35 std::memset(this->cbc_block, 0, this->buf_size); 37 std::memset(this->cbc_block, 0, this->buf_size);
36 if (encrypt) 38 if (encrypt)
37 { 39 {
38 - this->nrounds = rijndaelSetupEncrypt(this->rk, this->key, keybits); 40 + this->nrounds = rijndaelSetupEncrypt(
  41 + this->rk.getPointer(), this->key.getPointer(), keybits);
39 } 42 }
40 else 43 else
41 { 44 {
42 - this->nrounds = rijndaelSetupDecrypt(this->rk, this->key, keybits); 45 + this->nrounds = rijndaelSetupDecrypt(
  46 + this->rk.getPointer(), this->key.getPointer(), keybits);
43 } 47 }
44 assert(this->nrounds == NROUNDS(keybits)); 48 assert(this->nrounds == NROUNDS(keybits));
45 } 49 }
46 50
47 Pl_AES_PDF::~Pl_AES_PDF() 51 Pl_AES_PDF::~Pl_AES_PDF()
48 { 52 {
49 - delete [] this->key;  
50 - delete [] this->rk;  
51 } 53 }
52 54
53 void 55 void
@@ -222,7 +224,8 @@ Pl_AES_PDF::flush(bool strip_padding) @@ -222,7 +224,8 @@ Pl_AES_PDF::flush(bool strip_padding)
222 this->inbuf[i] ^= this->cbc_block[i]; 224 this->inbuf[i] ^= this->cbc_block[i];
223 } 225 }
224 } 226 }
225 - rijndaelEncrypt(this->rk, this->nrounds, this->inbuf, this->outbuf); 227 + rijndaelEncrypt(this->rk.getPointer(),
  228 + this->nrounds, this->inbuf, this->outbuf);
226 if (this->cbc_mode) 229 if (this->cbc_mode)
227 { 230 {
228 memcpy(this->cbc_block, this->outbuf, this->buf_size); 231 memcpy(this->cbc_block, this->outbuf, this->buf_size);
@@ -230,7 +233,8 @@ Pl_AES_PDF::flush(bool strip_padding) @@ -230,7 +233,8 @@ Pl_AES_PDF::flush(bool strip_padding)
230 } 233 }
231 else 234 else
232 { 235 {
233 - rijndaelDecrypt(this->rk, this->nrounds, this->inbuf, this->outbuf); 236 + rijndaelDecrypt(this->rk.getPointer(),
  237 + this->nrounds, this->inbuf, this->outbuf);
234 if (this->cbc_mode) 238 if (this->cbc_mode)
235 { 239 {
236 for (unsigned int i = 0; i < this->buf_size; ++i) 240 for (unsigned int i = 0; i < this->buf_size; ++i)
libqpdf/Pl_Flate.cc
@@ -13,7 +13,8 @@ Pl_Flate::Members::Members(size_t out_bufsize, @@ -13,7 +13,8 @@ Pl_Flate::Members::Members(size_t out_bufsize,
13 initialized(false), 13 initialized(false),
14 zdata(0) 14 zdata(0)
15 { 15 {
16 - this->outbuf = new unsigned char[out_bufsize]; 16 + this->outbuf = PointerHolder<unsigned char>(
  17 + true, new unsigned char[out_bufsize]);
17 // Indirect through zdata to reach the z_stream so we don't have 18 // Indirect through zdata to reach the z_stream so we don't have
18 // to include zlib.h in Pl_Flate.hh. This means people using 19 // to include zlib.h in Pl_Flate.hh. This means people using
19 // shared library versions of qpdf don't have to have zlib 20 // shared library versions of qpdf don't have to have zlib
@@ -34,15 +35,12 @@ Pl_Flate::Members::Members(size_t out_bufsize, @@ -34,15 +35,12 @@ Pl_Flate::Members::Members(size_t out_bufsize,
34 zstream.opaque = 0; 35 zstream.opaque = 0;
35 zstream.next_in = 0; 36 zstream.next_in = 0;
36 zstream.avail_in = 0; 37 zstream.avail_in = 0;
37 - zstream.next_out = this->outbuf; 38 + zstream.next_out = this->outbuf.getPointer();
38 zstream.avail_out = QIntC::to_uint(out_bufsize); 39 zstream.avail_out = QIntC::to_uint(out_bufsize);
39 } 40 }
40 41
41 Pl_Flate::Members::~Members() 42 Pl_Flate::Members::~Members()
42 { 43 {
43 - delete [] this->outbuf;  
44 - this->outbuf = 0;  
45 -  
46 if (this->initialized) 44 if (this->initialized)
47 { 45 {
48 z_stream& zstream = *(static_cast<z_stream*>(this->zdata)); 46 z_stream& zstream = *(static_cast<z_stream*>(this->zdata));
@@ -74,7 +72,7 @@ Pl_Flate::~Pl_Flate() @@ -74,7 +72,7 @@ Pl_Flate::~Pl_Flate()
74 void 72 void
75 Pl_Flate::write(unsigned char* data, size_t len) 73 Pl_Flate::write(unsigned char* data, size_t len)
76 { 74 {
77 - if (this->m->outbuf == 0) 75 + if (this->m->outbuf.getPointer() == 0)
78 { 76 {
79 throw std::logic_error( 77 throw std::logic_error(
80 this->identifier + 78 this->identifier +
@@ -186,8 +184,8 @@ Pl_Flate::handleData(unsigned char* data, size_t len, int flush) @@ -186,8 +184,8 @@ Pl_Flate::handleData(unsigned char* data, size_t len, int flush)
186 QIntC::to_ulong(this->m->out_bufsize - zstream.avail_out); 184 QIntC::to_ulong(this->m->out_bufsize - zstream.avail_out);
187 if (ready > 0) 185 if (ready > 0)
188 { 186 {
189 - this->getNext()->write(this->m->outbuf, ready);  
190 - zstream.next_out = this->m->outbuf; 187 + this->getNext()->write(this->m->outbuf.getPointer(), ready);
  188 + zstream.next_out = this->m->outbuf.getPointer();
191 zstream.avail_out = QIntC::to_uint(this->m->out_bufsize); 189 zstream.avail_out = QIntC::to_uint(this->m->out_bufsize);
192 } 190 }
193 } 191 }
@@ -205,7 +203,7 @@ Pl_Flate::finish() @@ -205,7 +203,7 @@ Pl_Flate::finish()
205 { 203 {
206 try 204 try
207 { 205 {
208 - if (this->m->outbuf) 206 + if (this->m->outbuf.getPointer())
209 { 207 {
210 if (this->m->initialized) 208 if (this->m->initialized)
211 { 209 {
@@ -226,7 +224,6 @@ Pl_Flate::finish() @@ -226,7 +224,6 @@ Pl_Flate::finish()
226 checkError("End", err); 224 checkError("End", err);
227 } 225 }
228 226
229 - delete [] this->m->outbuf;  
230 this->m->outbuf = 0; 227 this->m->outbuf = 0;
231 } 228 }
232 } 229 }
libqpdf/Pl_PNGFilter.cc
@@ -45,12 +45,14 @@ Pl_PNGFilter::Pl_PNGFilter(char const* identifier, Pipeline* next, @@ -45,12 +45,14 @@ Pl_PNGFilter::Pl_PNGFilter(char const* identifier, Pipeline* next,
45 "PNGFilter created with invalid columns value"); 45 "PNGFilter created with invalid columns value");
46 } 46 }
47 this->bytes_per_row = bpr & UINT_MAX; 47 this->bytes_per_row = bpr & UINT_MAX;
48 - this->buf1 = new unsigned char[this->bytes_per_row + 1];  
49 - this->buf2 = new unsigned char[this->bytes_per_row + 1];  
50 - memset(this->buf1, 0, this->bytes_per_row + 1);  
51 - memset(this->buf2, 0, this->bytes_per_row + 1);  
52 - this->cur_row = this->buf1;  
53 - this->prev_row = this->buf2; 48 + this->buf1 = PointerHolder<unsigned char>(
  49 + true, new unsigned char[this->bytes_per_row + 1]);
  50 + this->buf2 = PointerHolder<unsigned char>(
  51 + true, new unsigned char[this->bytes_per_row + 1]);
  52 + memset(this->buf1.getPointer(), 0, this->bytes_per_row + 1);
  53 + memset(this->buf2.getPointer(), 0, this->bytes_per_row + 1);
  54 + this->cur_row = this->buf1.getPointer();
  55 + this->prev_row = this->buf2.getPointer();
54 56
55 // number of bytes per incoming row 57 // number of bytes per incoming row
56 this->incoming = (action == a_encode ? 58 this->incoming = (action == a_encode ?
@@ -60,8 +62,6 @@ Pl_PNGFilter::Pl_PNGFilter(char const* identifier, Pipeline* next, @@ -60,8 +62,6 @@ Pl_PNGFilter::Pl_PNGFilter(char const* identifier, Pipeline* next,
60 62
61 Pl_PNGFilter::~Pl_PNGFilter() 63 Pl_PNGFilter::~Pl_PNGFilter()
62 { 64 {
63 - delete [] buf1;  
64 - delete [] buf2;  
65 } 65 }
66 66
67 void 67 void
@@ -81,7 +81,7 @@ Pl_PNGFilter::write(unsigned char* data, size_t len) @@ -81,7 +81,7 @@ Pl_PNGFilter::write(unsigned char* data, size_t len)
81 // Swap rows 81 // Swap rows
82 unsigned char* t = this->prev_row; 82 unsigned char* t = this->prev_row;
83 this->prev_row = this->cur_row; 83 this->prev_row = this->cur_row;
84 - this->cur_row = t ? t : this->buf2; 84 + this->cur_row = t ? t : this->buf2.getPointer();
85 memset(this->cur_row, 0, this->bytes_per_row + 1); 85 memset(this->cur_row, 0, this->bytes_per_row + 1);
86 left = this->incoming; 86 left = this->incoming;
87 this->pos = 0; 87 this->pos = 0;
@@ -269,7 +269,7 @@ Pl_PNGFilter::finish() @@ -269,7 +269,7 @@ Pl_PNGFilter::finish()
269 processRow(); 269 processRow();
270 } 270 }
271 this->prev_row = 0; 271 this->prev_row = 0;
272 - this->cur_row = buf1; 272 + this->cur_row = buf1.getPointer();
273 this->pos = 0; 273 this->pos = 0;
274 memset(this->cur_row, 0, this->bytes_per_row + 1); 274 memset(this->cur_row, 0, this->bytes_per_row + 1);
275 275
libqpdf/Pl_RC4.cc
@@ -8,19 +8,18 @@ Pl_RC4::Pl_RC4(char const* identifier, Pipeline* next, @@ -8,19 +8,18 @@ Pl_RC4::Pl_RC4(char const* identifier, Pipeline* next,
8 out_bufsize(out_bufsize), 8 out_bufsize(out_bufsize),
9 rc4(key_data, key_len) 9 rc4(key_data, key_len)
10 { 10 {
11 - this->outbuf = new unsigned char[out_bufsize]; 11 + this->outbuf = PointerHolder<unsigned char>(
  12 + true, new unsigned char[out_bufsize]);
12 } 13 }
13 14
14 Pl_RC4::~Pl_RC4() 15 Pl_RC4::~Pl_RC4()
15 { 16 {
16 - delete [] this->outbuf;  
17 - this->outbuf = 0;  
18 } 17 }
19 18
20 void 19 void
21 Pl_RC4::write(unsigned char* data, size_t len) 20 Pl_RC4::write(unsigned char* data, size_t len)
22 { 21 {
23 - if (this->outbuf == 0) 22 + if (this->outbuf.getPointer() == 0)
24 { 23 {
25 throw std::logic_error( 24 throw std::logic_error(
26 this->identifier + 25 this->identifier +
@@ -35,16 +34,15 @@ Pl_RC4::write(unsigned char* data, size_t len) @@ -35,16 +34,15 @@ Pl_RC4::write(unsigned char* data, size_t len)
35 size_t bytes = 34 size_t bytes =
36 (bytes_left < this->out_bufsize ? bytes_left : out_bufsize); 35 (bytes_left < this->out_bufsize ? bytes_left : out_bufsize);
37 bytes_left -= bytes; 36 bytes_left -= bytes;
38 - rc4.process(p, bytes, outbuf); 37 + rc4.process(p, bytes, outbuf.getPointer());
39 p += bytes; 38 p += bytes;
40 - getNext()->write(outbuf, bytes); 39 + getNext()->write(outbuf.getPointer(), bytes);
41 } 40 }
42 } 41 }
43 42
44 void 43 void
45 Pl_RC4::finish() 44 Pl_RC4::finish()
46 { 45 {
47 - delete [] this->outbuf;  
48 this->outbuf = 0; 46 this->outbuf = 0;
49 this->getNext()->finish(); 47 this->getNext()->finish();
50 } 48 }
libqpdf/Pl_TIFFPredictor.cc
@@ -16,7 +16,6 @@ Pl_TIFFPredictor::Pl_TIFFPredictor(char const* identifier, Pipeline* next, @@ -16,7 +16,6 @@ Pl_TIFFPredictor::Pl_TIFFPredictor(char const* identifier, Pipeline* next,
16 columns(columns), 16 columns(columns),
17 samples_per_pixel(samples_per_pixel), 17 samples_per_pixel(samples_per_pixel),
18 bits_per_sample(bits_per_sample), 18 bits_per_sample(bits_per_sample),
19 - cur_row(0),  
20 pos(0) 19 pos(0)
21 { 20 {
22 if (samples_per_pixel < 1) 21 if (samples_per_pixel < 1)
@@ -38,13 +37,13 @@ Pl_TIFFPredictor::Pl_TIFFPredictor(char const* identifier, Pipeline* next, @@ -38,13 +37,13 @@ Pl_TIFFPredictor::Pl_TIFFPredictor(char const* identifier, Pipeline* next,
38 "TIFFPredictor created with invalid columns value"); 37 "TIFFPredictor created with invalid columns value");
39 } 38 }
40 this->bytes_per_row = bpr & UINT_MAX; 39 this->bytes_per_row = bpr & UINT_MAX;
41 - this->cur_row = new unsigned char[this->bytes_per_row];  
42 - memset(this->cur_row, 0, this->bytes_per_row); 40 + this->cur_row = PointerHolder<unsigned char>(
  41 + true, new unsigned char[this->bytes_per_row]);
  42 + memset(this->cur_row.getPointer(), 0, this->bytes_per_row);
43 } 43 }
44 44
45 Pl_TIFFPredictor::~Pl_TIFFPredictor() 45 Pl_TIFFPredictor::~Pl_TIFFPredictor()
46 { 46 {
47 - delete [] cur_row;  
48 } 47 }
49 48
50 void 49 void
@@ -55,20 +54,20 @@ Pl_TIFFPredictor::write(unsigned char* data, size_t len) @@ -55,20 +54,20 @@ Pl_TIFFPredictor::write(unsigned char* data, size_t len)
55 while (len >= left) 54 while (len >= left)
56 { 55 {
57 // finish off current row 56 // finish off current row
58 - memcpy(this->cur_row + this->pos, data + offset, left); 57 + memcpy(this->cur_row.getPointer() + this->pos, data + offset, left);
59 offset += left; 58 offset += left;
60 len -= left; 59 len -= left;
61 60
62 processRow(); 61 processRow();
63 62
64 // Prepare for next row 63 // Prepare for next row
65 - memset(this->cur_row, 0, this->bytes_per_row); 64 + memset(this->cur_row.getPointer(), 0, this->bytes_per_row);
66 left = this->bytes_per_row; 65 left = this->bytes_per_row;
67 this->pos = 0; 66 this->pos = 0;
68 } 67 }
69 if (len) 68 if (len)
70 { 69 {
71 - memcpy(this->cur_row + this->pos, data + offset, len); 70 + memcpy(this->cur_row.getPointer() + this->pos, data + offset, len);
72 } 71 }
73 this->pos += len; 72 this->pos += len;
74 } 73 }
@@ -79,7 +78,7 @@ Pl_TIFFPredictor::processRow() @@ -79,7 +78,7 @@ Pl_TIFFPredictor::processRow()
79 QTC::TC("libtests", "Pl_TIFFPredictor processRow", 78 QTC::TC("libtests", "Pl_TIFFPredictor processRow",
80 (action == a_decode ? 0 : 1)); 79 (action == a_decode ? 0 : 1));
81 BitWriter bw(this->getNext()); 80 BitWriter bw(this->getNext());
82 - BitStream in(this->cur_row, this->bytes_per_row); 81 + BitStream in(this->cur_row.getPointer(), this->bytes_per_row);
83 std::vector<long long> prev; 82 std::vector<long long> prev;
84 for (unsigned int i = 0; i < this->samples_per_pixel; ++i) 83 for (unsigned int i = 0; i < this->samples_per_pixel; ++i)
85 { 84 {
@@ -118,6 +117,6 @@ Pl_TIFFPredictor::finish() @@ -118,6 +117,6 @@ Pl_TIFFPredictor::finish()
118 processRow(); 117 processRow();
119 } 118 }
120 this->pos = 0; 119 this->pos = 0;
121 - memset(this->cur_row, 0, this->bytes_per_row); 120 + memset(this->cur_row.getPointer(), 0, this->bytes_per_row);
122 getNext()->finish(); 121 getNext()->finish();
123 } 122 }
libqpdf/QPDFWriter.cc
@@ -1835,21 +1835,21 @@ QPDFWriter::unparseObject(QPDFObjectHandle object, int level, @@ -1835,21 +1835,21 @@ QPDFWriter::unparseObject(QPDFObjectHandle object, int level,
1835 this->m->cur_data_key.length()); 1835 this->m->cur_data_key.length());
1836 pl.write(QUtil::unsigned_char_pointer(val), val.length()); 1836 pl.write(QUtil::unsigned_char_pointer(val), val.length());
1837 pl.finish(); 1837 pl.finish();
1838 - Buffer* buf = bufpl.getBuffer(); 1838 + PointerHolder<Buffer> buf = bufpl.getBuffer();
1839 val = QPDF_String( 1839 val = QPDF_String(
1840 std::string(reinterpret_cast<char*>(buf->getBuffer()), 1840 std::string(reinterpret_cast<char*>(buf->getBuffer()),
1841 buf->getSize())).unparse(true); 1841 buf->getSize())).unparse(true);
1842 - delete buf;  
1843 } 1842 }
1844 else 1843 else
1845 { 1844 {
1846 - char* tmp = QUtil::copy_string(val); 1845 + PointerHolder<char> tmp_ph =
  1846 + PointerHolder<char>(true, QUtil::copy_string(val));
  1847 + char* tmp = tmp_ph.getPointer();
1847 size_t vlen = val.length(); 1848 size_t vlen = val.length();
1848 RC4 rc4(QUtil::unsigned_char_pointer(this->m->cur_data_key), 1849 RC4 rc4(QUtil::unsigned_char_pointer(this->m->cur_data_key),
1849 QIntC::to_int(this->m->cur_data_key.length())); 1850 QIntC::to_int(this->m->cur_data_key.length()));
1850 rc4.process(QUtil::unsigned_char_pointer(tmp), vlen); 1851 rc4.process(QUtil::unsigned_char_pointer(tmp), vlen);
1851 val = QPDF_String(std::string(tmp, vlen)).unparse(); 1852 val = QPDF_String(std::string(tmp, vlen)).unparse();
1852 - delete [] tmp;  
1853 } 1853 }
1854 } 1854 }
1855 else 1855 else
libqpdf/QPDF_encryption.cc
@@ -204,7 +204,9 @@ iterate_rc4(unsigned char* data, size_t data_len, @@ -204,7 +204,9 @@ iterate_rc4(unsigned char* data, size_t data_len,
204 unsigned char* okey, int key_len, 204 unsigned char* okey, int key_len,
205 int iterations, bool reverse) 205 int iterations, bool reverse)
206 { 206 {
207 - unsigned char* key = new unsigned char[QIntC::to_size(key_len)]; 207 + PointerHolder<unsigned char> key_ph = PointerHolder<unsigned char>(
  208 + true, new unsigned char[QIntC::to_size(key_len)]);
  209 + unsigned char* key = key_ph.getPointer();
208 for (int i = 0; i < iterations; ++i) 210 for (int i = 0; i < iterations; ++i)
209 { 211 {
210 int const xor_value = (reverse ? iterations - 1 - i : i); 212 int const xor_value = (reverse ? iterations - 1 - i : i);
@@ -215,7 +217,6 @@ iterate_rc4(unsigned char* data, size_t data_len, @@ -215,7 +217,6 @@ iterate_rc4(unsigned char* data, size_t data_len,
215 RC4 rc4(key, QIntC::to_int(key_len)); 217 RC4 rc4(key, QIntC::to_int(key_len));
216 rc4.process(data, data_len); 218 rc4.process(data, data_len);
217 } 219 }
218 - delete [] key;  
219 } 220 }
220 221
221 static std::string 222 static std::string
libqpdf/QUtil.cc
@@ -670,10 +670,9 @@ QUtil::get_env(std::string const&amp; var, std::string* value) @@ -670,10 +670,9 @@ QUtil::get_env(std::string const&amp; var, std::string* value)
670 670
671 if (value) 671 if (value)
672 { 672 {
673 - char* t = new char[len + 1];  
674 - ::GetEnvironmentVariable(var.c_str(), t, len);  
675 - *value = t;  
676 - delete [] t; 673 + PointerHolder<char> t = PointerHolder<char>(true, new char[len + 1]);
  674 + ::GetEnvironmentVariable(var.c_str(), t.getPointer(), len);
  675 + *value = t.getPointer();
677 } 676 }
678 677
679 return true; 678 return true;
libqpdf/qpdf-c.cc
@@ -22,8 +22,8 @@ struct _qpdf_data @@ -22,8 +22,8 @@ struct _qpdf_data
22 _qpdf_data(); 22 _qpdf_data();
23 ~_qpdf_data(); 23 ~_qpdf_data();
24 24
25 - QPDF* qpdf;  
26 - QPDFWriter* qpdf_writer; 25 + PointerHolder<QPDF> qpdf;
  26 + PointerHolder<QPDFWriter> qpdf_writer;
27 27
28 PointerHolder<QPDFExc> error; 28 PointerHolder<QPDFExc> error;
29 _qpdf_error tmp_error; 29 _qpdf_error tmp_error;
@@ -36,22 +36,16 @@ struct _qpdf_data @@ -36,22 +36,16 @@ struct _qpdf_data
36 unsigned long long size; 36 unsigned long long size;
37 char const* password; 37 char const* password;
38 bool write_memory; 38 bool write_memory;
39 - Buffer* output_buffer; 39 + PointerHolder<Buffer> output_buffer;
40 }; 40 };
41 41
42 _qpdf_data::_qpdf_data() : 42 _qpdf_data::_qpdf_data() :
43 - qpdf(0),  
44 - qpdf_writer(0),  
45 - write_memory(false),  
46 - output_buffer(0) 43 + write_memory(false)
47 { 44 {
48 } 45 }
49 46
50 _qpdf_data::~_qpdf_data() 47 _qpdf_data::~_qpdf_data()
51 { 48 {
52 - delete qpdf_writer;  
53 - delete qpdf;  
54 - delete output_buffer;  
55 } 49 }
56 50
57 // must set qpdf->filename and qpdf->password 51 // must set qpdf->filename and qpdf->password
@@ -451,14 +445,12 @@ QPDF_BOOL qpdf_allow_modify_all(qpdf_data qpdf) @@ -451,14 +445,12 @@ QPDF_BOOL qpdf_allow_modify_all(qpdf_data qpdf)
451 445
452 static void qpdf_init_write_internal(qpdf_data qpdf) 446 static void qpdf_init_write_internal(qpdf_data qpdf)
453 { 447 {
454 - if (qpdf->qpdf_writer) 448 + if (qpdf->qpdf_writer.getPointer())
455 { 449 {
456 QTC::TC("qpdf", "qpdf-c called qpdf_init_write multiple times"); 450 QTC::TC("qpdf", "qpdf-c called qpdf_init_write multiple times");
457 - delete qpdf->qpdf_writer;  
458 qpdf->qpdf_writer = 0; 451 qpdf->qpdf_writer = 0;
459 - if (qpdf->output_buffer) 452 + if (qpdf->output_buffer.getPointer())
460 { 453 {
461 - delete qpdf->output_buffer;  
462 qpdf->output_buffer = 0; 454 qpdf->output_buffer = 0;
463 qpdf->write_memory = false; 455 qpdf->write_memory = false;
464 qpdf->filename = 0; 456 qpdf->filename = 0;
@@ -496,7 +488,7 @@ size_t qpdf_get_buffer_length(qpdf_data qpdf) @@ -496,7 +488,7 @@ size_t qpdf_get_buffer_length(qpdf_data qpdf)
496 { 488 {
497 qpdf_get_buffer_internal(qpdf); 489 qpdf_get_buffer_internal(qpdf);
498 size_t result = 0; 490 size_t result = 0;
499 - if (qpdf->output_buffer) 491 + if (qpdf->output_buffer.getPointer())
500 { 492 {
501 result = qpdf->output_buffer->getSize(); 493 result = qpdf->output_buffer->getSize();
502 } 494 }
@@ -507,7 +499,7 @@ unsigned char const* qpdf_get_buffer(qpdf_data qpdf) @@ -507,7 +499,7 @@ unsigned char const* qpdf_get_buffer(qpdf_data qpdf)
507 { 499 {
508 unsigned char const* result = 0; 500 unsigned char const* result = 0;
509 qpdf_get_buffer_internal(qpdf); 501 qpdf_get_buffer_internal(qpdf);
510 - if (qpdf->output_buffer) 502 + if (qpdf->output_buffer.getPointer())
511 { 503 {
512 result = qpdf->output_buffer->getBuffer(); 504 result = qpdf->output_buffer->getBuffer();
513 } 505 }
libqpdf/qpdf/Pl_AES_PDF.hh
@@ -55,8 +55,8 @@ class Pl_AES_PDF: public Pipeline @@ -55,8 +55,8 @@ class Pl_AES_PDF: public Pipeline
55 bool cbc_mode; 55 bool cbc_mode;
56 bool first; 56 bool first;
57 size_t offset; // offset into memory buffer 57 size_t offset; // offset into memory buffer
58 - unsigned char* key;  
59 - uint32_t* rk; 58 + PointerHolder<unsigned char> key;
  59 + PointerHolder<uint32_t> rk;
60 unsigned char inbuf[buf_size]; 60 unsigned char inbuf[buf_size];
61 unsigned char outbuf[buf_size]; 61 unsigned char outbuf[buf_size];
62 unsigned char cbc_block[buf_size]; 62 unsigned char cbc_block[buf_size];
libqpdf/qpdf/Pl_PNGFilter.hh
@@ -41,10 +41,10 @@ class Pl_PNGFilter: public Pipeline @@ -41,10 +41,10 @@ class Pl_PNGFilter: public Pipeline
41 action_e action; 41 action_e action;
42 unsigned int bytes_per_row; 42 unsigned int bytes_per_row;
43 unsigned int bytes_per_pixel; 43 unsigned int bytes_per_pixel;
44 - unsigned char* cur_row;  
45 - unsigned char* prev_row;  
46 - unsigned char* buf1;  
47 - unsigned char* buf2; 44 + unsigned char* cur_row; // points to buf1 or buf2
  45 + unsigned char* prev_row; // points to buf1 or buf2
  46 + PointerHolder<unsigned char> buf1;
  47 + PointerHolder<unsigned char> buf2;
48 size_t pos; 48 size_t pos;
49 size_t incoming; 49 size_t incoming;
50 }; 50 };
libqpdf/qpdf/Pl_RC4.hh
@@ -24,7 +24,7 @@ class Pl_RC4: public Pipeline @@ -24,7 +24,7 @@ class Pl_RC4: public Pipeline
24 virtual void finish(); 24 virtual void finish();
25 25
26 private: 26 private:
27 - unsigned char* outbuf; 27 + PointerHolder<unsigned char> outbuf;
28 size_t out_bufsize; 28 size_t out_bufsize;
29 RC4 rc4; 29 RC4 rc4;
30 }; 30 };
libqpdf/qpdf/Pl_TIFFPredictor.hh
@@ -32,7 +32,7 @@ class Pl_TIFFPredictor: public Pipeline @@ -32,7 +32,7 @@ class Pl_TIFFPredictor: public Pipeline
32 unsigned int bytes_per_row; 32 unsigned int bytes_per_row;
33 unsigned int samples_per_pixel; 33 unsigned int samples_per_pixel;
34 unsigned int bits_per_sample; 34 unsigned int bits_per_sample;
35 - unsigned char* cur_row; 35 + PointerHolder<unsigned char> cur_row;
36 size_t pos; 36 size_t pos;
37 }; 37 };
38 38
zlib-flate/zlib-flate.cc
@@ -61,8 +61,9 @@ int main(int argc, char* argv[]) @@ -61,8 +61,9 @@ int main(int argc, char* argv[])
61 61
62 QUtil::binary_stdout(); 62 QUtil::binary_stdout();
63 QUtil::binary_stdin(); 63 QUtil::binary_stdin();
64 - Pl_StdioFile* out = new Pl_StdioFile("stdout", stdout);  
65 - Pl_Flate* flate = new Pl_Flate("flate", out, action); 64 + PointerHolder<Pl_StdioFile> out = new Pl_StdioFile("stdout", stdout);
  65 + PointerHolder<Pl_Flate> flate =
  66 + new Pl_Flate("flate", out.getPointer(), action);
66 67
67 try 68 try
68 { 69 {
@@ -81,8 +82,6 @@ int main(int argc, char* argv[]) @@ -81,8 +82,6 @@ int main(int argc, char* argv[])
81 } 82 }
82 } 83 }
83 flate->finish(); 84 flate->finish();
84 - delete flate;  
85 - delete out;  
86 } 85 }
87 catch (std::exception& e) 86 catch (std::exception& e)
88 { 87 {