Commit 3bab4cf394f0606998e3e000f510c1e49787a3f7
1 parent
5edb5481
Refactor Pl_RunLength::decode
Buffer output locally. Add qpdf_fuzzer test case.
Showing
5 changed files
with
12 additions
and
8 deletions
fuzz/CMakeLists.txt
fuzz/qpdf_extra/69977e.fuzz
0 → 100644
No preview for this file type
fuzz/qtest/fuzz.test
include/qpdf/Pl_RunLength.hh
libqpdf/Pl_RunLength.cc
| ... | ... | @@ -66,8 +66,9 @@ Pl_RunLength::encode(unsigned char const* data, size_t len) |
| 66 | 66 | void |
| 67 | 67 | Pl_RunLength::decode(unsigned char const* data, size_t len) |
| 68 | 68 | { |
| 69 | + m->out.reserve(len); | |
| 69 | 70 | for (size_t i = 0; i < len; ++i) { |
| 70 | - unsigned char ch = data[i]; | |
| 71 | + unsigned char const& ch = data[i]; | |
| 71 | 72 | switch (m->state) { |
| 72 | 73 | case st_top: |
| 73 | 74 | if (ch < 128) { |
| ... | ... | @@ -85,16 +86,14 @@ Pl_RunLength::decode(unsigned char const* data, size_t len) |
| 85 | 86 | break; |
| 86 | 87 | |
| 87 | 88 | case st_copying: |
| 88 | - this->getNext()->write(&ch, 1); | |
| 89 | + m->out.append(1, static_cast<char>(ch)); | |
| 89 | 90 | if (--m->length == 0) { |
| 90 | 91 | m->state = st_top; |
| 91 | 92 | } |
| 92 | 93 | break; |
| 93 | 94 | |
| 94 | 95 | case st_run: |
| 95 | - for (unsigned int j = 0; j < m->length; ++j) { | |
| 96 | - this->getNext()->write(&ch, 1); | |
| 97 | - } | |
| 96 | + m->out.append(m->length, static_cast<char>(ch)); | |
| 98 | 97 | m->state = st_top; |
| 99 | 98 | break; |
| 100 | 99 | } |
| ... | ... | @@ -137,10 +136,13 @@ Pl_RunLength::finish() |
| 137 | 136 | // When decoding, we might have read a length byte not followed by data, which means the stream |
| 138 | 137 | // was terminated early, but we will just ignore this case since this is the only sensible thing |
| 139 | 138 | // to do. |
| 139 | + auto next = getNext(); | |
| 140 | 140 | if (m->action == a_encode) { |
| 141 | 141 | flush_encode(); |
| 142 | 142 | unsigned char ch = 128; |
| 143 | - this->getNext()->write(&ch, 1); | |
| 143 | + next->write(&ch, 1); | |
| 144 | + } else { | |
| 145 | + next->writeString(m->out); | |
| 144 | 146 | } |
| 145 | - this->getNext()->finish(); | |
| 147 | + next->finish(); | |
| 146 | 148 | } | ... | ... |