Better validate Prev entries in trailers.
Prev entries are defined as "The byte offset from the beginning of the
file" so they should not be negative.
Simplify another FX_SAFE_FILESIZE usage along the way.
Change-Id: I596d708ff5a08abcaf9688edbc9e5715b6a30119
Reviewed-on: https://pdfium-review.googlesource.com/c/pdfium/+/60970
Reviewed-by: Henrique Nakashima <hnakashima@chromium.org>
Commit-Queue: Lei Zhang <thestig@chromium.org>
diff --git a/core/fpdfapi/parser/cpdf_data_avail.cpp b/core/fpdfapi/parser/cpdf_data_avail.cpp
index df759a7..457ae61 100644
--- a/core/fpdfapi/parser/cpdf_data_avail.cpp
+++ b/core/fpdfapi/parser/cpdf_data_avail.cpp
@@ -748,21 +748,22 @@
}
if (!m_bMainXRefLoadTried) {
- const FX_SAFE_FILESIZE main_xref_offset =
+ const FX_SAFE_FILESIZE prev =
m_pDocument->GetParser()->GetTrailer()->GetIntegerFor("Prev");
- if (!main_xref_offset.IsValid())
+ const FX_FILESIZE main_xref_offset = prev.ValueOrDefault(-1);
+ if (main_xref_offset < 0)
return DataError;
- if (main_xref_offset.ValueOrDie() == 0)
+ if (main_xref_offset == 0)
return DataAvailable;
FX_SAFE_SIZE_T data_size = m_dwFileLen;
- data_size -= main_xref_offset.ValueOrDie();
+ data_size -= main_xref_offset;
if (!data_size.IsValid())
return DataError;
if (!GetValidator()->CheckDataRangeAndRequestIfUnavailable(
- main_xref_offset.ValueOrDie(), data_size.ValueOrDie()))
+ main_xref_offset, data_size.ValueOrDie()))
return DataNotAvailable;
CPDF_Parser::Error eRet =
diff --git a/core/fpdfapi/parser/cpdf_parser.cpp b/core/fpdfapi/parser/cpdf_parser.cpp
index 01c2a67..f8e244e 100644
--- a/core/fpdfapi/parser/cpdf_parser.cpp
+++ b/core/fpdfapi/parser/cpdf_parser.cpp
@@ -1051,19 +1051,20 @@
}
CPDF_Parser::Error CPDF_Parser::LoadLinearizedMainXRefTable() {
- const FX_SAFE_FILESIZE main_xref_offset = GetTrailer()->GetIntegerFor("Prev");
- if (!main_xref_offset.IsValid())
+ const FX_SAFE_FILESIZE prev = GetTrailer()->GetIntegerFor("Prev");
+ const FX_FILESIZE main_xref_offset = prev.ValueOrDefault(-1);
+ if (main_xref_offset < 0)
return FORMAT_ERROR;
- if (main_xref_offset.ValueOrDie() == 0)
+ if (main_xref_offset == 0)
return SUCCESS;
const AutoRestorer<uint32_t> save_metadata_objnum(&m_MetadataObjnum);
m_MetadataObjnum = 0;
m_ObjectStreamMap.clear();
- if (!LoadLinearizedAllCrossRefV4(main_xref_offset.ValueOrDie()) &&
- !LoadLinearizedAllCrossRefV5(main_xref_offset.ValueOrDie())) {
+ if (!LoadLinearizedAllCrossRefV4(main_xref_offset) &&
+ !LoadLinearizedAllCrossRefV5(main_xref_offset)) {
m_LastXRefOffset = 0;
return FORMAT_ERROR;
}
diff --git a/core/fpdfapi/parser/cpdf_read_validator.cpp b/core/fpdfapi/parser/cpdf_read_validator.cpp
index 61d7d19..80e6517 100644
--- a/core/fpdfapi/parser/cpdf_read_validator.cpp
+++ b/core/fpdfapi/parser/cpdf_read_validator.cpp
@@ -21,9 +21,7 @@
FX_FILESIZE AlignUp(FX_FILESIZE offset) {
FX_SAFE_FILESIZE safe_result = AlignDown(offset);
safe_result += kAlignBlockValue;
- if (safe_result.IsValid())
- return safe_result.ValueOrDie();
- return offset;
+ return safe_result.ValueOrDefault(offset);
}
} // namespace