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