Reorganize CLZWDecoder. - Add a ctor and initialize more variables there, or initialize them in the class declaration instead of in Decode(). - Take in the source data as a span instead of a raw pointer. - Change |m_Early| to |m_nEarly| and avoid adding ints with bools. - Fix nits and lint errors. Change-Id: I1b95619c2e094796f9e7a9dfea07ad55cacbc1da Reviewed-on: https://pdfium-review.googlesource.com/c/pdfium/+/56412 Reviewed-by: Tom Sepez <tsepez@chromium.org> Commit-Queue: Lei Zhang <thestig@chromium.org>
diff --git a/core/fxcodec/flate/flatemodule.cpp b/core/fxcodec/flate/flatemodule.cpp index 3604efb..0809c5b 100644 --- a/core/fxcodec/flate/flatemodule.cpp +++ b/core/fxcodec/flate/flatemodule.cpp
@@ -108,73 +108,66 @@ class CLZWDecoder { public: - bool Decode(uint8_t* dest_buf, - uint32_t* dest_size, - const uint8_t* src_buf, - uint32_t* src_size, - bool early_change); + CLZWDecoder(pdfium::span<const uint8_t> src_span, bool early_change); + + bool Decode(uint8_t* dest_buf, uint32_t* dest_size, uint32_t* src_size); private: void AddCode(uint32_t prefix_code, uint8_t append_char); void DecodeString(uint32_t code); - uint32_t m_InPos; - uint32_t m_OutPos; + pdfium::span<const uint8_t> const m_spSrc; + uint32_t m_InPos = 0; + uint32_t m_OutPos = 0; uint8_t* m_pOutput; - const uint8_t* m_pInput; - bool m_Early; - uint32_t m_nCodes; + const uint8_t m_nEarly; + uint32_t m_nCodes = 0; uint32_t m_StackLen; - int m_CodeLen; + uint8_t m_CodeLen = 9; uint32_t m_CodeArray[5021]; uint8_t m_DecodeStack[4000]; }; +CLZWDecoder::CLZWDecoder(pdfium::span<const uint8_t> src_span, + bool early_change) + : m_spSrc(src_span), m_nEarly(early_change ? 1 : 0) {} + void CLZWDecoder::AddCode(uint32_t prefix_code, uint8_t append_char) { - if (m_nCodes + m_Early == 4094) { + if (m_nCodes + m_nEarly == 4094) return; - } + m_CodeArray[m_nCodes++] = (prefix_code << 16) | append_char; - if (m_nCodes + m_Early == 512 - 258) { + if (m_nCodes + m_nEarly == 512 - 258) m_CodeLen = 10; - } else if (m_nCodes + m_Early == 1024 - 258) { + else if (m_nCodes + m_nEarly == 1024 - 258) m_CodeLen = 11; - } else if (m_nCodes + m_Early == 2048 - 258) { + else if (m_nCodes + m_nEarly == 2048 - 258) m_CodeLen = 12; - } } void CLZWDecoder::DecodeString(uint32_t code) { while (1) { int index = code - 258; - if (index < 0 || index >= (int)m_nCodes) { + if (index < 0 || static_cast<uint32_t>(index) >= m_nCodes) break; - } + uint32_t data = m_CodeArray[index]; - if (m_StackLen >= sizeof(m_DecodeStack)) { + if (m_StackLen >= sizeof(m_DecodeStack)) return; - } - m_DecodeStack[m_StackLen++] = (uint8_t)data; + + m_DecodeStack[m_StackLen++] = static_cast<uint8_t>(data); code = data >> 16; } - if (m_StackLen >= sizeof(m_DecodeStack)) { + if (m_StackLen >= sizeof(m_DecodeStack)) return; - } - m_DecodeStack[m_StackLen++] = (uint8_t)code; + + m_DecodeStack[m_StackLen++] = static_cast<uint8_t>(code); } bool CLZWDecoder::Decode(uint8_t* dest_buf, uint32_t* dest_size, - const uint8_t* src_buf, - uint32_t* src_size, - bool early_change) { - m_CodeLen = 9; - m_InPos = 0; - m_OutPos = 0; - m_pInput = src_buf; + uint32_t* src_size) { m_pOutput = dest_buf; - m_Early = early_change; - m_nCodes = 0; uint32_t old_code = 0xFFFFFFFF; uint8_t last_char = 0; while (1) { @@ -182,19 +175,20 @@ break; int byte_pos = m_InPos / 8; - int bit_pos = m_InPos % 8, bit_left = m_CodeLen; + int bit_pos = m_InPos % 8; + uint8_t bit_left = m_CodeLen; uint32_t code = 0; if (bit_pos) { bit_left -= 8 - bit_pos; - code = (m_pInput[byte_pos++] & ((1 << (8 - bit_pos)) - 1)) << bit_left; + code = (m_spSrc[byte_pos++] & ((1 << (8 - bit_pos)) - 1)) << bit_left; } if (bit_left < 8) { - code |= m_pInput[byte_pos] >> (8 - bit_left); + code |= m_spSrc[byte_pos] >> (8 - bit_left); } else { bit_left -= 8; - code |= m_pInput[byte_pos++] << bit_left; + code |= m_spSrc[byte_pos++] << bit_left; if (bit_left) - code |= m_pInput[byte_pos] >> (8 - bit_left); + code |= m_spSrc[byte_pos] >> (8 - bit_left); } m_InPos += m_CodeLen; @@ -795,20 +789,18 @@ PredictorType predictor_type = GetPredictor(predictor); if (bLZW) { - auto decoder = pdfium::MakeUnique<CLZWDecoder>(); + auto decoder = pdfium::MakeUnique<CLZWDecoder>(src_span, bEarlyChange); *dest_size = 0xFFFFFFFF; offset = src_span.size(); - bool success = decoder->Decode(nullptr, dest_size, src_span.data(), &offset, - bEarlyChange); + bool success = decoder->Decode(nullptr, dest_size, &offset); if (!success || *dest_size == 0 || *dest_size + 1 < *dest_size) return FX_INVALID_OFFSET; - decoder = pdfium::MakeUnique<CLZWDecoder>(); + decoder = pdfium::MakeUnique<CLZWDecoder>(src_span, bEarlyChange); dest_buf->reset(FX_Alloc(uint8_t, *dest_size + 1)); uint8_t* dest_buf_ptr = dest_buf->get(); dest_buf_ptr[*dest_size] = '\0'; - decoder->Decode(dest_buf_ptr, dest_size, src_span.data(), &offset, - bEarlyChange); + decoder->Decode(dest_buf_ptr, dest_size, &offset); } else { FlateUncompress(src_span, estimated_size, dest_buf, dest_size, &offset); }