1 // Copyright (c) 2016 The WebM project authors. All Rights Reserved.
2 //
3 // Use of this source code is governed by a BSD-style license
4 // that can be found in the LICENSE file in the root of the source
5 // tree. An additional intellectual property rights grant can be found
6 // in the file PATENTS.  All contributing project authors may
7 // be found in the AUTHORS file in the root of the source tree.
8 #include "src/chapter_atom_parser.h"
9 
10 #include "gtest/gtest.h"
11 
12 #include "test_utils/element_parser_test.h"
13 #include "webm/id.h"
14 #include "webm/status.h"
15 
16 using webm::ChapterAtom;
17 using webm::ChapterAtomParser;
18 using webm::ChapterDisplay;
19 using webm::ElementParserTest;
20 using webm::Id;
21 using webm::Status;
22 
23 namespace {
24 
25 class ChapterAtomParserTest
26     : public ElementParserTest<ChapterAtomParser, Id::kChapterAtom> {};
27 
TEST_F(ChapterAtomParserTest,DefaultParse)28 TEST_F(ChapterAtomParserTest, DefaultParse) {
29   ParseAndVerify();
30 
31   const ChapterAtom chapter_atom = parser_.value();
32 
33   EXPECT_FALSE(chapter_atom.uid.is_present());
34   EXPECT_EQ(static_cast<std::uint64_t>(0), chapter_atom.uid.value());
35 
36   EXPECT_FALSE(chapter_atom.string_uid.is_present());
37   EXPECT_EQ("", chapter_atom.string_uid.value());
38 
39   EXPECT_FALSE(chapter_atom.time_start.is_present());
40   EXPECT_EQ(static_cast<std::uint64_t>(0), chapter_atom.time_start.value());
41 
42   EXPECT_FALSE(chapter_atom.time_end.is_present());
43   EXPECT_EQ(static_cast<std::uint64_t>(0), chapter_atom.time_end.value());
44 
45   EXPECT_EQ(static_cast<std::size_t>(0), chapter_atom.displays.size());
46 
47   EXPECT_EQ(static_cast<std::uint64_t>(0), chapter_atom.atoms.size());
48 }
49 
TEST_F(ChapterAtomParserTest,DefaultValues)50 TEST_F(ChapterAtomParserTest, DefaultValues) {
51   SetReaderData({
52       0x73, 0xC4,  // ID = 0x73C4 (ChapterUID).
53       0x80,  // Size = 0.
54 
55       0x56, 0x54,  // ID = 0x73C4 (ChapterStringUID).
56       0x80,  // Size = 0.
57 
58       0x91,  // ID = 0x91 (ChapterTimeStart).
59       0x40, 0x00,  // Size = 0.
60 
61       0x92,  // ID = 0x91 (ChapterTimeEnd).
62       0x40, 0x00,  // Size = 0.
63 
64       0x80,  // ID = 0x80 (ChapterDisplay).
65       0x40, 0x00,  // Size = 0.
66 
67       0xB6,  // ID = 0xB6 (ChapterAtom).
68       0x40, 0x00,  // Size = 0.
69   });
70 
71   ParseAndVerify();
72 
73   const ChapterAtom chapter_atom = parser_.value();
74 
75   EXPECT_TRUE(chapter_atom.uid.is_present());
76   EXPECT_EQ(static_cast<std::uint64_t>(0), chapter_atom.uid.value());
77 
78   EXPECT_TRUE(chapter_atom.string_uid.is_present());
79   EXPECT_EQ("", chapter_atom.string_uid.value());
80 
81   EXPECT_TRUE(chapter_atom.time_start.is_present());
82   EXPECT_EQ(static_cast<std::uint64_t>(0), chapter_atom.time_start.value());
83 
84   EXPECT_TRUE(chapter_atom.time_end.is_present());
85   EXPECT_EQ(static_cast<std::uint64_t>(0), chapter_atom.time_end.value());
86 
87   ASSERT_EQ(static_cast<std::uint64_t>(1), chapter_atom.displays.size());
88   EXPECT_TRUE(chapter_atom.displays[0].is_present());
89   EXPECT_EQ(ChapterDisplay{}, chapter_atom.displays[0].value());
90 
91   ASSERT_EQ(static_cast<std::uint64_t>(1), chapter_atom.atoms.size());
92   EXPECT_TRUE(chapter_atom.atoms[0].is_present());
93   EXPECT_EQ(ChapterAtom{}, chapter_atom.atoms[0].value());
94 }
95 
TEST_F(ChapterAtomParserTest,CustomValues)96 TEST_F(ChapterAtomParserTest, CustomValues) {
97   SetReaderData({
98       0x73, 0xC4,  // ID = 0x73C4 (ChapterUID).
99       0x81,  // Size = 1.
100       0x01,  // Body (value = 1).
101 
102       0x56, 0x54,  // ID = 0x73C4 (ChapterStringUID).
103       0x81,  // Size = 1.
104       0x41,  // Body (value = "A").
105 
106       0x91,  // ID = 0x91 (ChapterTimeStart).
107       0x40, 0x01,  // Size = 1.
108       0x02,  // Body (value = 2).
109 
110       0x92,  // ID = 0x91 (ChapterTimeEnd).
111       0x40, 0x01,  // Size = 1.
112       0x03,  // Body (value = 3).
113 
114       0x80,  // ID = 0x80 (ChapterDisplay).
115       0x40, 0x04,  // Size = 4.
116 
117       0x85,  //   ID = 0x85 (ChapString).
118       0x40, 0x01,  //   Size = 1.
119       0x42,  //   Body (value = "B").
120 
121       0x80,  // ID = 0x80 (ChapterDisplay).
122       0x40, 0x04,  // Size = 4.
123 
124       0x85,  //   ID = 0x85 (ChapString).
125       0x40, 0x01,  //   Size = 1.
126       0x43,  //   Body (value = "C").
127 
128       0xB6,  // ID = 0xB6 (ChapterAtom).
129       0x40, 0x12,  // Size = 18.
130 
131       0x73, 0xC4,  //   ID = 0x73C4 (ChapterUID).
132       0x81,  //   Size = 1.
133       0x04,  //   Body (value = 4).
134 
135       0xB6,  //   ID = 0xB6 (ChapterAtom).
136       0x40, 0x04,  //   Size = 4.
137 
138       0x73, 0xC4,  //     ID = 0x73C4 (ChapterUID).
139       0x81,  //     Size = 1.
140       0x05,  //     Body (value = 5).
141 
142       0xB6,  //   ID = 0xB6 (ChapterAtom).
143       0x40, 0x04,  //   Size = 4.
144 
145       0x73, 0xC4,  //     ID = 0x73C4 (ChapterUID).
146       0x81,  //     Size = 1.
147       0x06,  //     Body (value = 6).
148   });
149 
150   ParseAndVerify();
151 
152   const ChapterAtom chapter_atom = parser_.value();
153 
154   EXPECT_TRUE(chapter_atom.uid.is_present());
155   EXPECT_EQ(static_cast<std::uint64_t>(1), chapter_atom.uid.value());
156 
157   EXPECT_TRUE(chapter_atom.string_uid.is_present());
158   EXPECT_EQ("A", chapter_atom.string_uid.value());
159 
160   EXPECT_TRUE(chapter_atom.time_start.is_present());
161   EXPECT_EQ(static_cast<std::uint64_t>(2), chapter_atom.time_start.value());
162 
163   EXPECT_TRUE(chapter_atom.time_end.is_present());
164   EXPECT_EQ(static_cast<std::uint64_t>(3), chapter_atom.time_end.value());
165 
166   ChapterDisplay expected_chapter_display;
167 
168   ASSERT_EQ(static_cast<std::size_t>(2), chapter_atom.displays.size());
169   expected_chapter_display.string.Set("B", true);
170   EXPECT_TRUE(chapter_atom.displays[0].is_present());
171   EXPECT_EQ(expected_chapter_display, chapter_atom.displays[0].value());
172   expected_chapter_display.string.Set("C", true);
173   EXPECT_TRUE(chapter_atom.displays[1].is_present());
174   EXPECT_EQ(expected_chapter_display, chapter_atom.displays[1].value());
175 
176   ChapterAtom expected_chapter_atom;
177   expected_chapter_atom.uid.Set(4, true);
178 
179   ChapterAtom tmp_atom{};
180   tmp_atom.uid.Set(5, true);
181   expected_chapter_atom.atoms.emplace_back(tmp_atom, true);
182   tmp_atom.uid.Set(6, true);
183   expected_chapter_atom.atoms.emplace_back(tmp_atom, true);
184 
185   ASSERT_EQ(static_cast<std::size_t>(1), chapter_atom.atoms.size());
186   EXPECT_TRUE(chapter_atom.atoms[0].is_present());
187   EXPECT_EQ(expected_chapter_atom, chapter_atom.atoms[0].value());
188 }
189 
TEST_F(ChapterAtomParserTest,ExceedMaxRecursionDepth)190 TEST_F(ChapterAtomParserTest, ExceedMaxRecursionDepth) {
191   ResetParser(1);
192 
193   SetReaderData({
194       0xB6,  // ID = 0xB6 (ChapterAtom).
195       0x80,  // Size = 0.
196   });
197   ParseAndVerify();
198 
199   SetReaderData({
200       0xB6,  // ID = 0xB6 (ChapterAtom).
201       0x82,  // Size = 2.
202 
203       0xB6,  //   ID = 0xB6 (ChapterAtom).
204       0x80,  //   Size = 0.
205   });
206   ParseAndExpectResult(Status::kExceededRecursionDepthLimit);
207 }
208 
209 }  // namespace
210