1 // Copyright 2016 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 <limits>
6
7 #include "core/fpdfapi/parser/cpdf_object.h"
8 #include "core/fpdfapi/parser/cpdf_parser.h"
9 #include "core/fpdfapi/parser/cpdf_syntax_parser.h"
10 #include "core/fxcrt/cfx_read_only_span_stream.h"
11 #include "core/fxcrt/fx_extension.h"
12 #include "testing/gtest/include/gtest/gtest.h"
13 #include "testing/utils/path_service.h"
14
TEST(SyntaxParserTest,ReadHexString)15 TEST(SyntaxParserTest, ReadHexString) {
16 {
17 // Empty string.
18 static const uint8_t data[] = "";
19 CPDF_SyntaxParser parser(
20 pdfium::MakeRetain<CFX_ReadOnlySpanStream>(pdfium::make_span(data, 0)));
21 EXPECT_EQ("", parser.ReadHexString());
22 EXPECT_EQ(0, parser.GetPos());
23 }
24
25 {
26 // Blank string.
27 static const uint8_t data[] = " ";
28 CPDF_SyntaxParser parser(
29 pdfium::MakeRetain<CFX_ReadOnlySpanStream>(pdfium::make_span(data, 2)));
30 EXPECT_EQ("", parser.ReadHexString());
31 EXPECT_EQ(2, parser.GetPos());
32 }
33
34 {
35 // Skips unknown characters.
36 static const uint8_t data[] = "z12b";
37 CPDF_SyntaxParser parser(
38 pdfium::MakeRetain<CFX_ReadOnlySpanStream>(pdfium::make_span(data, 4)));
39 EXPECT_EQ("\x12\xb0", parser.ReadHexString());
40 EXPECT_EQ(4, parser.GetPos());
41 }
42
43 {
44 // Skips unknown characters.
45 static const uint8_t data[] = "*<&*#$^&@1";
46 CPDF_SyntaxParser parser(pdfium::MakeRetain<CFX_ReadOnlySpanStream>(
47 pdfium::make_span(data, 10)));
48 EXPECT_EQ("\x10", parser.ReadHexString());
49 EXPECT_EQ(10, parser.GetPos());
50 }
51
52 {
53 // Skips unknown characters.
54 static const uint8_t data[] = "\x80zab";
55 CPDF_SyntaxParser parser(
56 pdfium::MakeRetain<CFX_ReadOnlySpanStream>(pdfium::make_span(data, 4)));
57 EXPECT_EQ("\xab", parser.ReadHexString());
58 EXPECT_EQ(4, parser.GetPos());
59 }
60
61 {
62 // Skips unknown characters.
63 static const uint8_t data[] = "\xffzab";
64 CPDF_SyntaxParser parser(
65 pdfium::MakeRetain<CFX_ReadOnlySpanStream>(pdfium::make_span(data, 4)));
66 EXPECT_EQ("\xab", parser.ReadHexString());
67 EXPECT_EQ(4, parser.GetPos());
68 }
69
70 {
71 // Regular conversion.
72 static const uint8_t data[] = "1A2b>abcd";
73 CPDF_SyntaxParser parser(
74 pdfium::MakeRetain<CFX_ReadOnlySpanStream>(pdfium::make_span(data, 9)));
75 EXPECT_EQ("\x1a\x2b", parser.ReadHexString());
76 EXPECT_EQ(5, parser.GetPos());
77 }
78
79 {
80 // Position out of bounds.
81 static const uint8_t data[] = "12ab>";
82 CPDF_SyntaxParser parser(
83 pdfium::MakeRetain<CFX_ReadOnlySpanStream>(pdfium::make_span(data, 5)));
84 parser.SetPos(5);
85 EXPECT_EQ("", parser.ReadHexString());
86
87 parser.SetPos(6);
88 EXPECT_EQ("", parser.ReadHexString());
89
90 parser.SetPos(std::numeric_limits<FX_FILESIZE>::max());
91 EXPECT_EQ("", parser.ReadHexString());
92
93 // Check string still parses when set to 0.
94 parser.SetPos(0);
95 EXPECT_EQ("\x12\xab", parser.ReadHexString());
96 }
97
98 {
99 // Missing ending >.
100 static const uint8_t data[] = "1A2b";
101 CPDF_SyntaxParser parser(
102 pdfium::MakeRetain<CFX_ReadOnlySpanStream>(pdfium::make_span(data, 4)));
103 EXPECT_EQ("\x1a\x2b", parser.ReadHexString());
104 EXPECT_EQ(4, parser.GetPos());
105 }
106
107 {
108 // Missing ending >.
109 static const uint8_t data[] = "12abz";
110 CPDF_SyntaxParser parser(
111 pdfium::MakeRetain<CFX_ReadOnlySpanStream>(pdfium::make_span(data, 5)));
112 EXPECT_EQ("\x12\xab", parser.ReadHexString());
113 EXPECT_EQ(5, parser.GetPos());
114 }
115
116 {
117 // Uneven number of bytes.
118 static const uint8_t data[] = "1A2>asdf";
119 CPDF_SyntaxParser parser(
120 pdfium::MakeRetain<CFX_ReadOnlySpanStream>(pdfium::make_span(data, 8)));
121 EXPECT_EQ("\x1a\x20", parser.ReadHexString());
122 EXPECT_EQ(4, parser.GetPos());
123 }
124
125 {
126 // Uneven number of bytes.
127 static const uint8_t data[] = "1A2zasdf";
128 CPDF_SyntaxParser parser(
129 pdfium::MakeRetain<CFX_ReadOnlySpanStream>(pdfium::make_span(data, 8)));
130 EXPECT_EQ("\x1a\x2a\xdf", parser.ReadHexString());
131 EXPECT_EQ(8, parser.GetPos());
132 }
133
134 {
135 // Just ending character.
136 static const uint8_t data[] = ">";
137 CPDF_SyntaxParser parser(
138 pdfium::MakeRetain<CFX_ReadOnlySpanStream>(pdfium::make_span(data, 1)));
139 EXPECT_EQ("", parser.ReadHexString());
140 EXPECT_EQ(1, parser.GetPos());
141 }
142 }
143
TEST(SyntaxParserTest,GetInvalidReference)144 TEST(SyntaxParserTest, GetInvalidReference) {
145 // Data with a reference with number CPDF_Object::kInvalidObjNum
146 static const uint8_t data[] = "4294967295 0 R";
147 CPDF_SyntaxParser parser(
148 pdfium::MakeRetain<CFX_ReadOnlySpanStream>(pdfium::make_span(data, 14)));
149 RetainPtr<CPDF_Object> ref = parser.GetObjectBody(nullptr);
150 EXPECT_FALSE(ref);
151 }
152
TEST(SyntaxParserTest,PeekNextWord)153 TEST(SyntaxParserTest, PeekNextWord) {
154 static const uint8_t data[] = " WORD ";
155 CPDF_SyntaxParser parser(pdfium::MakeRetain<CFX_ReadOnlySpanStream>(data));
156 EXPECT_EQ("WORD", parser.PeekNextWord());
157 EXPECT_EQ("WORD", parser.GetNextWord().word);
158 }
159