blob: 665203ecd6db07186a0a98a34240deb6d6c11b30 [file] [log] [blame]
[email protected]d9806a972014-02-26 18:14:571// Copyright 2014 The Chromium Authors. All rights reserved.
[email protected]7556ea22011-12-08 19:29:152// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
[email protected]d9806a972014-02-26 18:14:575#include "base/big_endian.h"
6
avi9b6f42932015-12-26 22:15:147#include <stdint.h>
8
Daniel McArdle1714f572020-08-10 23:27:409#include <limits>
10
[email protected]d069c11a2013-04-13 00:01:5511#include "base/strings/string_piece.h"
[email protected]7556ea22011-12-08 19:29:1512#include "testing/gtest/include/gtest/gtest.h"
13
[email protected]d9806a972014-02-26 18:14:5714namespace base {
[email protected]7556ea22011-12-08 19:29:1515
Eugene Zemtsov9ade52b2020-09-09 08:01:0116TEST(ReadBigEndianTest, ReadSignedPositive) {
17 char data[] = {0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x1A, 0X2A};
18 int8_t s8 = 0;
19 int16_t s16 = 0;
20 int32_t s32 = 0;
21 int64_t s64 = 0;
22 ReadBigEndian(data, &s8);
23 ReadBigEndian(data, &s16);
24 ReadBigEndian(data, &s32);
25 ReadBigEndian(data, &s64);
26 EXPECT_EQ(0x0A, s8);
27 EXPECT_EQ(0x0A0B, s16);
28 EXPECT_EQ(int32_t{0x0A0B0C0D}, s32);
29 EXPECT_EQ(int64_t{0x0A0B0C0D0E0F1A2All}, s64);
30}
31
32TEST(ReadBigEndianTest, ReadSignedNegative) {
33 char data[] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0XFF};
34 int8_t s8 = 0;
35 int16_t s16 = 0;
36 int32_t s32 = 0;
37 int64_t s64 = 0;
38 ReadBigEndian(data, &s8);
39 ReadBigEndian(data, &s16);
40 ReadBigEndian(data, &s32);
41 ReadBigEndian(data, &s64);
42 EXPECT_EQ(-1, s8);
43 EXPECT_EQ(-1, s16);
44 EXPECT_EQ(-1, s32);
45 EXPECT_EQ(-1, s64);
46}
47
48TEST(ReadBigEndianTest, ReadUnsignedSigned) {
49 char data[] = {0xA0, 0xB0, 0xC0, 0xD0, 0xE0, 0xF0, 0xA1, 0XA2};
50 uint8_t u8 = 0;
51 uint16_t u16 = 0;
52 uint32_t u32 = 0;
53 uint64_t u64 = 0;
54 ReadBigEndian(data, &u8);
55 ReadBigEndian(data, &u16);
56 ReadBigEndian(data, &u32);
57 ReadBigEndian(data, &u64);
58 EXPECT_EQ(0xA0, u8);
59 EXPECT_EQ(0xA0B0, u16);
60 EXPECT_EQ(0xA0B0C0D0, u32);
61 EXPECT_EQ(0xA0B0C0D0E0F0A1A2ull, u64);
62}
63
64TEST(ReadBigEndianTest, TryAll16BitValues) {
65 using signed_type = int16_t;
66 char data[sizeof(signed_type)];
67 for (int i = std::numeric_limits<signed_type>::min();
68 i <= std::numeric_limits<signed_type>::max(); i++) {
69 signed_type expected = i;
70 signed_type actual = 0;
71 WriteBigEndian(data, expected);
72 ReadBigEndian(data, &actual);
73 EXPECT_EQ(expected, actual);
74 }
75}
76
[email protected]7556ea22011-12-08 19:29:1577TEST(BigEndianReaderTest, ReadsValues) {
[email protected]0d5590f2014-07-30 23:24:4878 char data[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0xA, 0xB, 0xC, 0xD, 0xE, 0xF,
79 0x1A, 0x2B, 0x3C, 0x4D, 0x5E };
[email protected]7556ea22011-12-08 19:29:1580 char buf[2];
avi9b6f42932015-12-26 22:15:1481 uint8_t u8;
82 uint16_t u16;
83 uint32_t u32;
84 uint64_t u64;
[email protected]7556ea22011-12-08 19:29:1585 base::StringPiece piece;
86 BigEndianReader reader(data, sizeof(data));
87
88 EXPECT_TRUE(reader.Skip(2));
89 EXPECT_EQ(data + 2, reader.ptr());
Raul Tambref191b592019-01-21 23:56:2990 EXPECT_EQ(reader.remaining(), sizeof(data) - 2);
[email protected]7556ea22011-12-08 19:29:1591 EXPECT_TRUE(reader.ReadBytes(buf, sizeof(buf)));
92 EXPECT_EQ(0x2, buf[0]);
93 EXPECT_EQ(0x3, buf[1]);
94 EXPECT_TRUE(reader.ReadU8(&u8));
95 EXPECT_EQ(0x4, u8);
96 EXPECT_TRUE(reader.ReadU16(&u16));
97 EXPECT_EQ(0x0506, u16);
98 EXPECT_TRUE(reader.ReadU32(&u32));
99 EXPECT_EQ(0x0708090Au, u32);
[email protected]0d5590f2014-07-30 23:24:48100 EXPECT_TRUE(reader.ReadU64(&u64));
101 EXPECT_EQ(0x0B0C0D0E0F1A2B3Cllu, u64);
[email protected]7556ea22011-12-08 19:29:15102 base::StringPiece expected(reader.ptr(), 2);
103 EXPECT_TRUE(reader.ReadPiece(&piece, 2));
104 EXPECT_EQ(2u, piece.size());
105 EXPECT_EQ(expected.data(), piece.data());
106}
107
David Van Clevedc398ef2019-10-15 19:39:11108TEST(BigEndianReaderTest, ReadsLengthPrefixedValues) {
109 {
110 char u8_prefixed_data[] = {8, 8, 9, 0xA, 0xB, 0xC, 0xD,
111 0xE, 0xF, 0x1A, 0x2B, 0x3C, 0x4D, 0x5E};
112 BigEndianReader reader(u8_prefixed_data, sizeof(u8_prefixed_data));
113
114 base::StringPiece piece;
115 ASSERT_TRUE(reader.ReadU8LengthPrefixed(&piece));
116 // |reader| should skip both a u8 and the length-8 length-prefixed field.
117 EXPECT_EQ(reader.ptr(), u8_prefixed_data + 9);
118 EXPECT_EQ(piece.size(), 8u);
119 EXPECT_EQ(piece.data(), u8_prefixed_data + 1);
120 }
121
122 {
123 char u16_prefixed_data[] = {0, 8, 0xD, 0xE, 0xF,
124 0x1A, 0x2B, 0x3C, 0x4D, 0x5E};
125 BigEndianReader reader(u16_prefixed_data, sizeof(u16_prefixed_data));
126 base::StringPiece piece;
127 ASSERT_TRUE(reader.ReadU16LengthPrefixed(&piece));
128 // |reader| should skip both a u16 and the length-8 length-prefixed field.
129 EXPECT_EQ(reader.ptr(), u16_prefixed_data + 10);
130 EXPECT_EQ(piece.size(), 8u);
131 EXPECT_EQ(piece.data(), u16_prefixed_data + 2);
132
133 // With no data left, we shouldn't be able to
134 // read another u8 length prefix (or a u16 length prefix,
135 // for that matter).
136 EXPECT_FALSE(reader.ReadU8LengthPrefixed(&piece));
137 EXPECT_FALSE(reader.ReadU16LengthPrefixed(&piece));
138 }
139
140 {
141 // Make sure there's no issue reading a zero-value length prefix.
142 char u16_prefixed_data[3] = {};
143 BigEndianReader reader(u16_prefixed_data, sizeof(u16_prefixed_data));
144 base::StringPiece piece;
145 ASSERT_TRUE(reader.ReadU16LengthPrefixed(&piece));
146 EXPECT_EQ(reader.ptr(), u16_prefixed_data + 2);
147 EXPECT_EQ(piece.data(), u16_prefixed_data + 2);
148 EXPECT_EQ(piece.size(), 0u);
149 }
150}
151
152TEST(BigEndianReaderTest, LengthPrefixedReadsFailGracefully) {
153 // We can't read 0xF (or, for that matter, 0xF8) bytes after the length
154 // prefix: there isn't enough data.
155 char data[] = {0xF, 8, 9, 0xA, 0xB, 0xC, 0xD,
156 0xE, 0xF, 0x1A, 0x2B, 0x3C, 0x4D, 0x5E};
157 BigEndianReader reader(data, sizeof(data));
158 base::StringPiece piece;
159 EXPECT_FALSE(reader.ReadU8LengthPrefixed(&piece));
160 EXPECT_EQ(data, reader.ptr());
161
162 EXPECT_FALSE(reader.ReadU16LengthPrefixed(&piece));
163 EXPECT_EQ(data, reader.ptr());
164}
165
[email protected]7556ea22011-12-08 19:29:15166TEST(BigEndianReaderTest, RespectsLength) {
[email protected]0d5590f2014-07-30 23:24:48167 char data[8];
[email protected]7556ea22011-12-08 19:29:15168 char buf[2];
avi9b6f42932015-12-26 22:15:14169 uint8_t u8;
170 uint16_t u16;
171 uint32_t u32;
172 uint64_t u64;
[email protected]7556ea22011-12-08 19:29:15173 base::StringPiece piece;
174 BigEndianReader reader(data, sizeof(data));
[email protected]0d5590f2014-07-30 23:24:48175 // 8 left
176 EXPECT_FALSE(reader.Skip(9));
[email protected]7556ea22011-12-08 19:29:15177 EXPECT_TRUE(reader.Skip(1));
[email protected]0d5590f2014-07-30 23:24:48178 // 7 left
179 EXPECT_FALSE(reader.ReadU64(&u64));
180 EXPECT_TRUE(reader.Skip(4));
[email protected]7556ea22011-12-08 19:29:15181 // 3 left
182 EXPECT_FALSE(reader.ReadU32(&u32));
183 EXPECT_FALSE(reader.ReadPiece(&piece, 4));
184 EXPECT_TRUE(reader.Skip(2));
185 // 1 left
186 EXPECT_FALSE(reader.ReadU16(&u16));
187 EXPECT_FALSE(reader.ReadBytes(buf, 2));
188 EXPECT_TRUE(reader.Skip(1));
189 // 0 left
190 EXPECT_FALSE(reader.ReadU8(&u8));
Raul Tambref191b592019-01-21 23:56:29191 EXPECT_EQ(0u, reader.remaining());
[email protected]7556ea22011-12-08 19:29:15192}
193
Daniel McArdle1714f572020-08-10 23:27:40194TEST(BigEndianReaderTest, SafePointerMath) {
195 char data[] = "foo";
196 BigEndianReader reader(data, sizeof(data));
197 // The test should fail without ever dereferencing the |dummy_buf| pointer.
198 char* dummy_buf = reinterpret_cast<char*>(0xdeadbeef);
199 // Craft an extreme length value that would cause |reader.data() + len| to
200 // overflow.
201 size_t extreme_length = std::numeric_limits<size_t>::max() - 1;
202 base::StringPiece piece;
203 EXPECT_FALSE(reader.Skip(extreme_length));
204 EXPECT_FALSE(reader.ReadBytes(dummy_buf, extreme_length));
205 EXPECT_FALSE(reader.ReadPiece(&piece, extreme_length));
206}
207
[email protected]7556ea22011-12-08 19:29:15208TEST(BigEndianWriterTest, WritesValues) {
[email protected]0d5590f2014-07-30 23:24:48209 char expected[] = { 0, 0, 2, 3, 4, 5, 6, 7, 8, 9, 0xA, 0xB, 0xC, 0xD, 0xE,
210 0xF, 0x1A, 0x2B, 0x3C };
[email protected]7556ea22011-12-08 19:29:15211 char data[sizeof(expected)];
212 char buf[] = { 0x2, 0x3 };
213 memset(data, 0, sizeof(data));
214 BigEndianWriter writer(data, sizeof(data));
215
216 EXPECT_TRUE(writer.Skip(2));
217 EXPECT_TRUE(writer.WriteBytes(buf, sizeof(buf)));
218 EXPECT_TRUE(writer.WriteU8(0x4));
219 EXPECT_TRUE(writer.WriteU16(0x0506));
220 EXPECT_TRUE(writer.WriteU32(0x0708090A));
[email protected]0d5590f2014-07-30 23:24:48221 EXPECT_TRUE(writer.WriteU64(0x0B0C0D0E0F1A2B3Cllu));
[email protected]7556ea22011-12-08 19:29:15222 EXPECT_EQ(0, memcmp(expected, data, sizeof(expected)));
223}
224
225TEST(BigEndianWriterTest, RespectsLength) {
[email protected]0d5590f2014-07-30 23:24:48226 char data[8];
[email protected]7556ea22011-12-08 19:29:15227 char buf[2];
avi9b6f42932015-12-26 22:15:14228 uint8_t u8 = 0;
229 uint16_t u16 = 0;
230 uint32_t u32 = 0;
231 uint64_t u64 = 0;
[email protected]7556ea22011-12-08 19:29:15232 BigEndianWriter writer(data, sizeof(data));
[email protected]0d5590f2014-07-30 23:24:48233 // 8 left
234 EXPECT_FALSE(writer.Skip(9));
[email protected]7556ea22011-12-08 19:29:15235 EXPECT_TRUE(writer.Skip(1));
[email protected]0d5590f2014-07-30 23:24:48236 // 7 left
237 EXPECT_FALSE(writer.WriteU64(u64));
238 EXPECT_TRUE(writer.Skip(4));
[email protected]7556ea22011-12-08 19:29:15239 // 3 left
240 EXPECT_FALSE(writer.WriteU32(u32));
241 EXPECT_TRUE(writer.Skip(2));
242 // 1 left
243 EXPECT_FALSE(writer.WriteU16(u16));
244 EXPECT_FALSE(writer.WriteBytes(buf, 2));
245 EXPECT_TRUE(writer.Skip(1));
246 // 0 left
247 EXPECT_FALSE(writer.WriteU8(u8));
Raul Tambref191b592019-01-21 23:56:29248 EXPECT_EQ(0u, writer.remaining());
[email protected]7556ea22011-12-08 19:29:15249}
250
Daniel McArdle1714f572020-08-10 23:27:40251TEST(BigEndianWriterTest, SafePointerMath) {
252 char data[3];
253 BigEndianWriter writer(data, sizeof(data));
254 // The test should fail without ever dereferencing the |dummy_buf| pointer.
255 const char* dummy_buf = reinterpret_cast<const char*>(0xdeadbeef);
256 // Craft an extreme length value that would cause |reader.data() + len| to
257 // overflow.
258 size_t extreme_length = std::numeric_limits<size_t>::max() - 1;
259 EXPECT_FALSE(writer.Skip(extreme_length));
260 EXPECT_FALSE(writer.WriteBytes(dummy_buf, extreme_length));
261}
262
[email protected]d9806a972014-02-26 18:14:57263} // namespace base