Qt
Internal/Contributor docs for the Qt SDK. Note: These are NOT official API docs; those are found at https://doc.qt.io/
Loading...
Searching...
No Matches
cpdf_object_stream.cpp
Go to the documentation of this file.
1// Copyright 2018 The PDFium Authors
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#include "core/fpdfapi/parser/cpdf_object_stream.h"
6
7#include <utility>
8
9#include "core/fpdfapi/parser/cpdf_dictionary.h"
10#include "core/fpdfapi/parser/cpdf_number.h"
11#include "core/fpdfapi/parser/cpdf_parser.h"
12#include "core/fpdfapi/parser/cpdf_reference.h"
13#include "core/fpdfapi/parser/cpdf_stream.h"
14#include "core/fpdfapi/parser/cpdf_stream_acc.h"
15#include "core/fpdfapi/parser/cpdf_syntax_parser.h"
16#include "core/fpdfapi/parser/fpdf_parser_utility.h"
17#include "core/fxcrt/cfx_read_only_span_stream.h"
18#include "core/fxcrt/fx_safe_types.h"
19#include "third_party/base/check.h"
20#include "third_party/base/memory/ptr_util.h"
21
22namespace {
23
24bool IsObjectStream(const CPDF_Stream* stream) {
25 if (!stream)
26 return false;
27
28 // See ISO 32000-1:2008 spec, table 16.
29 RetainPtr<const CPDF_Dictionary> stream_dict = stream->GetDict();
30 if (!ValidateDictType(stream_dict.Get(), "ObjStm"))
31 return false;
32
33 RetainPtr<const CPDF_Number> number_of_objects =
34 stream_dict->GetNumberFor("N");
35 if (!number_of_objects || !number_of_objects->IsInteger() ||
36 number_of_objects->GetInteger() < 0 ||
37 number_of_objects->GetInteger() >=
38 static_cast<int>(CPDF_Parser::kMaxObjectNumber)) {
39 return false;
40 }
41
42 RetainPtr<const CPDF_Number> first_object_offset =
43 stream_dict->GetNumberFor("First");
44 if (!first_object_offset || !first_object_offset->IsInteger() ||
45 first_object_offset->GetInteger() < 0) {
46 return false;
47 }
48
49 return true;
50}
51
52} // namespace
53
54// static
55std::unique_ptr<CPDF_ObjectStream> CPDF_ObjectStream::Create(
56 RetainPtr<const CPDF_Stream> stream) {
57 if (!IsObjectStream(stream.Get()))
58 return nullptr;
59
60 // Protected constructor.
61 return pdfium::WrapUnique(new CPDF_ObjectStream(std::move(stream)));
62}
63
64CPDF_ObjectStream::CPDF_ObjectStream(RetainPtr<const CPDF_Stream> obj_stream)
65 : stream_acc_(pdfium::MakeRetain<CPDF_StreamAcc>(obj_stream)),
66 first_object_offset_(obj_stream->GetDict()->GetIntegerFor("First")) {
67 DCHECK(IsObjectStream(obj_stream.Get()));
68 Init(obj_stream.Get());
69}
70
72
75 uint32_t obj_number,
76 uint32_t archive_obj_index) const {
77 if (archive_obj_index >= object_info_.size())
78 return nullptr;
79
80 const auto& info = object_info_[archive_obj_index];
81 if (info.obj_num != obj_number)
82 return nullptr;
83
84 RetainPtr<CPDF_Object> result =
85 ParseObjectAtOffset(pObjList, info.obj_offset);
86 if (result)
87 result->SetObjNum(obj_number);
88 return result;
89}
90
91void CPDF_ObjectStream::Init(const CPDF_Stream* stream) {
92 stream_acc_->LoadAllDataFiltered();
93 data_stream_ =
94 pdfium::MakeRetain<CFX_ReadOnlySpanStream>(stream_acc_->GetSpan());
95
96 CPDF_SyntaxParser syntax(data_stream_);
97 const int object_count = stream->GetDict()->GetIntegerFor("N");
98 for (int32_t i = object_count; i > 0; --i) {
99 if (syntax.GetPos() >= data_stream_->GetSize())
100 break;
101
102 const uint32_t obj_num = syntax.GetDirectNum();
103 const uint32_t obj_offset = syntax.GetDirectNum();
104 if (!obj_num)
105 continue;
106
107 object_info_.emplace_back(obj_num, obj_offset);
108 }
109}
110
111RetainPtr<CPDF_Object> CPDF_ObjectStream::ParseObjectAtOffset(
113 uint32_t object_offset) const {
114 FX_SAFE_FILESIZE offset_in_stream = first_object_offset_;
115 offset_in_stream += object_offset;
116
117 if (!offset_in_stream.IsValid())
118 return nullptr;
119
120 if (offset_in_stream.ValueOrDie() >= data_stream_->GetSize())
121 return nullptr;
122
123 CPDF_SyntaxParser syntax(data_stream_);
124 syntax.SetPos(offset_in_stream.ValueOrDie());
125 return syntax.GetObjectBody(pObjList);
126}
RetainPtr< CPDF_Object > ParseObject(CPDF_IndirectObjectHolder *pObjList, uint32_t obj_number, uint32_t archive_obj_index) const
RetainPtr< const CPDF_Dictionary > GetDict() const
static constexpr uint32_t kMaxObjectNumber
Definition cpdf_parser.h:57
void SetPos(FX_FILESIZE pos)
RetainPtr< CPDF_Object > GetObjectBody(CPDF_IndirectObjectHolder *pObjList)