Remove out-parameters from FlateUncompress() Return a struct instead. Add struct DataAndBytesConsumed in its own file for reuse by other codec decoders in the future. Change-Id: Id66d1e253270b22b138de7dddc401d82eda6c97e Reviewed-on: https://pdfium-review.googlesource.com/c/pdfium/+/119133 Reviewed-by: Thomas Sepez <tsepez@google.com> Reviewed-by: Tom Sepez <tsepez@chromium.org> Commit-Queue: Lei Zhang <thestig@chromium.org>
diff --git a/core/fxcodec/BUILD.gn b/core/fxcodec/BUILD.gn index 588cd2d..46bdb06 100644 --- a/core/fxcodec/BUILD.gn +++ b/core/fxcodec/BUILD.gn
@@ -11,6 +11,8 @@ "basic/basicmodule.h", "cfx_codec_memory.cpp", "cfx_codec_memory.h", + "data_and_bytes_consumed.cpp", + "data_and_bytes_consumed.h", "fax/faxmodule.cpp", "fax/faxmodule.h", "flate/flatemodule.cpp",
diff --git a/core/fxcodec/data_and_bytes_consumed.cpp b/core/fxcodec/data_and_bytes_consumed.cpp new file mode 100644 index 0000000..6e83f34 --- /dev/null +++ b/core/fxcodec/data_and_bytes_consumed.cpp
@@ -0,0 +1,25 @@ +// Copyright 2024 The PDFium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "core/fxcodec/data_and_bytes_consumed.h" + +#include <utility> + +namespace fxcodec { + +DataAndBytesConsumed::DataAndBytesConsumed( + std::unique_ptr<uint8_t, FxFreeDeleter> data, + uint32_t size, + uint32_t bytes_consumed) + : data(std::move(data)), size(size), bytes_consumed(bytes_consumed) {} + +DataAndBytesConsumed::DataAndBytesConsumed(DataAndBytesConsumed&&) noexcept = + default; + +DataAndBytesConsumed& DataAndBytesConsumed::operator=( + DataAndBytesConsumed&&) noexcept = default; + +DataAndBytesConsumed::~DataAndBytesConsumed() = default; + +} // namespace fxcodec
diff --git a/core/fxcodec/data_and_bytes_consumed.h b/core/fxcodec/data_and_bytes_consumed.h new file mode 100644 index 0000000..1aef085 --- /dev/null +++ b/core/fxcodec/data_and_bytes_consumed.h
@@ -0,0 +1,37 @@ +// Copyright 2024 The PDFium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CORE_FXCODEC_DATA_AND_BYTES_CONSUMED_H_ +#define CORE_FXCODEC_DATA_AND_BYTES_CONSUMED_H_ + +#include <stdint.h> + +#include <memory> + +#include "core/fxcrt/fx_memory_wrappers.h" + +namespace fxcodec { + +struct DataAndBytesConsumed { + DataAndBytesConsumed(std::unique_ptr<uint8_t, FxFreeDeleter> data, + uint32_t size, + uint32_t bytes_consumed); + DataAndBytesConsumed(DataAndBytesConsumed&) = delete; + DataAndBytesConsumed& operator=(DataAndBytesConsumed&) = delete; + DataAndBytesConsumed(DataAndBytesConsumed&&) noexcept; + DataAndBytesConsumed& operator=(DataAndBytesConsumed&&) noexcept; + ~DataAndBytesConsumed(); + + // TODO(crbug.com/pdfium/1872): Replace with DataVector. + std::unique_ptr<uint8_t, FxFreeDeleter> data; + uint32_t size; + // TODO(thestig): Consider replacing with std::optional<size_t>. + uint32_t bytes_consumed; +}; + +} // namespace fxcodec + +using DataAndBytesConsumed = fxcodec::DataAndBytesConsumed; + +#endif // CORE_FXCODEC_DATA_AND_BYTES_CONSUMED_H_
diff --git a/core/fxcodec/flate/flatemodule.cpp b/core/fxcodec/flate/flatemodule.cpp index 88a93c8..4933219 100644 --- a/core/fxcodec/flate/flatemodule.cpp +++ b/core/fxcodec/flate/flatemodule.cpp
@@ -19,6 +19,7 @@ #include <utility> #include <vector> +#include "core/fxcodec/data_and_bytes_consumed.h" #include "core/fxcodec/scanlinedecoder.h" #include "core/fxcrt/check.h" #include "core/fxcrt/data_vector.h" @@ -549,17 +550,12 @@ return true; } -void FlateUncompress(pdfium::span<const uint8_t> src_buf, - uint32_t orig_size, - std::unique_ptr<uint8_t, FxFreeDeleter>* dest_buf, - uint32_t* dest_size, - uint32_t* offset) { - dest_buf->reset(); - *dest_size = 0; - +DataAndBytesConsumed FlateUncompress(pdfium::span<const uint8_t> src_buf, + uint32_t orig_size) { std::unique_ptr<z_stream, FlateDeleter> context(FlateInit()); - if (!context) - return; + if (!context) { + return {nullptr, 0u, 0u}; + } FlateInput(context.get(), src_buf); @@ -574,7 +570,6 @@ std::unique_ptr<uint8_t, FxFreeDeleter> guess_buf( FX_Alloc(uint8_t, guess_size + 1)); guess_buf.get()[guess_size] = '\0'; - std::vector<std::unique_ptr<uint8_t, FxFreeDeleter>> result_tmp_bufs; { std::unique_ptr<uint8_t, FxFreeDeleter> cur_buf = std::move(guess_buf); @@ -595,17 +590,16 @@ // The TotalOut size returned from the library may not be big enough to // handle the content the library returns. We can only handle items // up to 4GB in size. - *dest_size = FlateGetPossiblyTruncatedTotalOut(context.get()); - *offset = FlateGetPossiblyTruncatedTotalIn(context.get()); + const uint32_t dest_size = FlateGetPossiblyTruncatedTotalOut(context.get()); + const uint32_t offset = FlateGetPossiblyTruncatedTotalIn(context.get()); if (result_tmp_bufs.size() == 1) { - *dest_buf = std::move(result_tmp_bufs[0]); - return; + return {std::move(result_tmp_bufs.front()), dest_size, offset}; } std::unique_ptr<uint8_t, FxFreeDeleter> result_buf( - FX_Alloc(uint8_t, *dest_size)); + FX_Alloc(uint8_t, dest_size)); uint32_t result_pos = 0; - uint32_t remaining = *dest_size; + uint32_t remaining = dest_size; for (size_t i = 0; i < result_tmp_bufs.size(); i++) { std::unique_ptr<uint8_t, FxFreeDeleter> tmp_buf = std::move(result_tmp_bufs[i]); @@ -618,7 +612,7 @@ result_pos += cp_size; remaining -= cp_size; } - *dest_buf = std::move(result_buf); + return {std::move(result_buf), dest_size, offset}; } enum class PredictorType : uint8_t { kNone, kFlate, kPng }; @@ -857,25 +851,29 @@ std::unique_ptr<uint8_t, FxFreeDeleter>* dest_buf, uint32_t* dest_size) { dest_buf->reset(); - uint32_t offset = 0; + uint32_t bytes_consumed = 0; PredictorType predictor_type = GetPredictor(predictor); if (bLZW) { auto decoder = std::make_unique<CLZWDecoder>(src_span, bEarlyChange); - if (!decoder->Decode()) + if (!decoder->Decode()) { return FX_INVALID_OFFSET; + } - offset = decoder->GetSrcSize(); + bytes_consumed = decoder->GetSrcSize(); *dest_size = decoder->GetDestSize(); *dest_buf = decoder->TakeDestBuf(); } else { - FlateUncompress(src_span, estimated_size, dest_buf, dest_size, &offset); + DataAndBytesConsumed result = FlateUncompress(src_span, estimated_size); + *dest_buf = std::move(result.data); + *dest_size = result.size; + bytes_consumed = result.bytes_consumed; } bool ret = false; switch (predictor_type) { case PredictorType::kNone: - return offset; + return bytes_consumed; case PredictorType::kPng: ret = PNG_Predictor(Colors, BitsPerComponent, Columns, dest_buf, dest_size); @@ -885,7 +883,7 @@ dest_size); break; } - return ret ? offset : FX_INVALID_OFFSET; + return ret ? bytes_consumed : FX_INVALID_OFFSET; } // static