Commit e999bbae43fc4fd0bdf24c3117574eb75216f0d9
1 parent
c6872d2c
Fix memory leak with bad jpeg data
Showing
2 changed files
with
9 additions
and
5 deletions
include/qpdf/Pl_DCT.hh
| @@ -49,8 +49,8 @@ class Pl_DCT: public Pipeline | @@ -49,8 +49,8 @@ class Pl_DCT: public Pipeline | ||
| 49 | virtual void finish(); | 49 | virtual void finish(); |
| 50 | 50 | ||
| 51 | private: | 51 | private: |
| 52 | - void compress(void* cinfo, PointerHolder<Buffer>); | ||
| 53 | - void decompress(void* cinfo, PointerHolder<Buffer>); | 52 | + void compress(void* cinfo, Buffer*); |
| 53 | + void decompress(void* cinfo, Buffer*); | ||
| 54 | 54 | ||
| 55 | enum action_e { a_compress, a_decompress }; | 55 | enum action_e { a_compress, a_decompress }; |
| 56 | 56 |
libqpdf/Pl_DCT.cc
| @@ -66,7 +66,6 @@ void | @@ -66,7 +66,6 @@ void | ||
| 66 | Pl_DCT::finish() | 66 | Pl_DCT::finish() |
| 67 | { | 67 | { |
| 68 | this->buf.finish(); | 68 | this->buf.finish(); |
| 69 | - PointerHolder<Buffer> b = this->buf.getBuffer(); | ||
| 70 | 69 | ||
| 71 | struct jpeg_compress_struct cinfo_compress; | 70 | struct jpeg_compress_struct cinfo_compress; |
| 72 | struct jpeg_decompress_struct cinfo_decompress; | 71 | struct jpeg_decompress_struct cinfo_decompress; |
| @@ -77,6 +76,10 @@ Pl_DCT::finish() | @@ -77,6 +76,10 @@ Pl_DCT::finish() | ||
| 77 | jerr.pub.error_exit = error_handler; | 76 | jerr.pub.error_exit = error_handler; |
| 78 | 77 | ||
| 79 | bool error = false; | 78 | bool error = false; |
| 79 | + // Using a PointerHolder<Buffer> here and passing it into compress | ||
| 80 | + // and decompress causes a memory leak with setjmp/longjmp. Just | ||
| 81 | + // use a pointer and delete it. | ||
| 82 | + Buffer* b = this->buf.getBuffer(); | ||
| 80 | if (setjmp(jerr.jmpbuf) == 0) | 83 | if (setjmp(jerr.jmpbuf) == 0) |
| 81 | { | 84 | { |
| 82 | if (this->action == a_compress) | 85 | if (this->action == a_compress) |
| @@ -92,6 +95,7 @@ Pl_DCT::finish() | @@ -92,6 +95,7 @@ Pl_DCT::finish() | ||
| 92 | { | 95 | { |
| 93 | error = true; | 96 | error = true; |
| 94 | } | 97 | } |
| 98 | + delete b; | ||
| 95 | 99 | ||
| 96 | if (this->action == a_compress) | 100 | if (this->action == a_compress) |
| 97 | { | 101 | { |
| @@ -127,7 +131,7 @@ class Freer | @@ -127,7 +131,7 @@ class Freer | ||
| 127 | }; | 131 | }; |
| 128 | 132 | ||
| 129 | void | 133 | void |
| 130 | -Pl_DCT::compress(void* cinfo_p, PointerHolder<Buffer> b) | 134 | +Pl_DCT::compress(void* cinfo_p, Buffer* b) |
| 131 | { | 135 | { |
| 132 | struct jpeg_compress_struct* cinfo = | 136 | struct jpeg_compress_struct* cinfo = |
| 133 | reinterpret_cast<jpeg_compress_struct*>(cinfo_p); | 137 | reinterpret_cast<jpeg_compress_struct*>(cinfo_p); |
| @@ -183,7 +187,7 @@ Pl_DCT::compress(void* cinfo_p, PointerHolder<Buffer> b) | @@ -183,7 +187,7 @@ Pl_DCT::compress(void* cinfo_p, PointerHolder<Buffer> b) | ||
| 183 | } | 187 | } |
| 184 | 188 | ||
| 185 | void | 189 | void |
| 186 | -Pl_DCT::decompress(void* cinfo_p, PointerHolder<Buffer> b) | 190 | +Pl_DCT::decompress(void* cinfo_p, Buffer* b) |
| 187 | { | 191 | { |
| 188 | struct jpeg_decompress_struct* cinfo = | 192 | struct jpeg_decompress_struct* cinfo = |
| 189 | reinterpret_cast<jpeg_decompress_struct*>(cinfo_p); | 193 | reinterpret_cast<jpeg_decompress_struct*>(cinfo_p); |