1 /*
2 **
3 ** Copyright 2017, The Android Open Source Project
4 **
5 ** Licensed under the Apache License, Version 2.0 (the "License");
6 ** you may not use this file except in compliance with the License.
7 ** You may obtain a copy of the License at
8 **
9 ** http://www.apache.org/licenses/LICENSE-2.0
10 **
11 ** Unless required by applicable law or agreed to in writing, software
12 ** distributed under the License is distributed on an "AS IS" BASIS,
13 ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 ** See the License for the specific language governing permissions and
15 ** limitations under the License.
16 */
17
18 #include <android/hardware/confirmationui/support/cbor.h>
19
20 #include <cstddef>
21 #include <cstdint>
22 #include <iomanip>
23 #include <iostream>
24
25 #include <gtest/gtest.h>
26
27 using namespace android::hardware::confirmationui::support;
28
29 uint8_t testVector[] = {
30 0xA4, 0x63, 0x6B, 0x65, 0x79, 0x65, 0x76, 0x61, 0x6C, 0x75, 0x65, 0x63, 0x6B, 0x65, 0x79, 0x4D,
31 0x31, 0x30, 0x30, 0x31, 0x30, 0x31, 0x30, 0x31, 0x30, 0x30, 0x31, 0x30, 0x00, 0x04, 0x07, 0x1B,
32 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3B, 0x00, 0x07, 0x1A, 0xFD, 0x49, 0x8C, 0xFF,
33 0xFF, 0x82, 0x69, 0xE2, 0x99, 0xA8, 0xE2, 0x9A, 0x96, 0xE2, 0xB6, 0x96, 0x59, 0x01, 0x91, 0x61,
34 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61,
35 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61,
36 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61,
37 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61,
38 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61,
39 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61,
40 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61,
41 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61,
42 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61,
43 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61,
44 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61,
45 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61,
46 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61,
47 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61,
48 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61,
49 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61,
50 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61,
51 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61,
52 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61,
53 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61,
54 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61,
55 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61,
56 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61,
57 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61,
58 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x00,
59 };
60
61 // 400 'a's and a '\0'
62 constexpr char fourHundredAs[] =
63 "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
64 "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
65 "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
66 "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
67 "aaaaaaaaaaaaaaaaaaaaaaaa";
68
writeTest(WriteState state)69 WriteState writeTest(WriteState state) {
70 return write(state, //
71 map( //
72 pair(text("key"), text("value")), //
73 pair(text("key"), bytes("100101010010")), //
74 pair(4, 7), //
75 pair((UINT64_C(1) << 62), INT64_C(-2000000000000000)) //
76 ), //
77 arr(text("♨⚖ⶖ"), bytes(fourHundredAs)));
78 }
79
TEST(Cbor,FeatureTest)80 TEST(Cbor, FeatureTest) {
81 uint8_t buffer[0x1000];
82 WriteState state(buffer);
83 state = writeTest(state);
84 ASSERT_EQ(sizeof(testVector), size_t(state.data_ - buffer));
85 ASSERT_EQ(Error::OK, state.error_);
86 ASSERT_EQ(0, memcmp(buffer, testVector, sizeof(testVector)));
87 }
88
89 // Test if in all write cases an out of data error is correctly propagated and we don't
90 // write beyond the end of the buffer.
TEST(Cbor,BufferTooShort)91 TEST(Cbor, BufferTooShort) {
92 uint8_t buffer[0x1000];
93 for (size_t s = 1; s < sizeof(testVector); ++s) {
94 memset(buffer, 0x22, 0x1000); // 0x22 is not in the testVector
95 WriteState state(buffer, s);
96 state = writeTest(state);
97 for (size_t t = s; t < 0x1000; ++t) {
98 ASSERT_EQ(0x22, buffer[t]); // check if a canary has been killed
99 }
100 ASSERT_EQ(Error::OUT_OF_DATA, state.error_);
101 }
102 }
103
TEST(Cbor,MalformedUTF8Test_Stray)104 TEST(Cbor, MalformedUTF8Test_Stray) {
105 uint8_t buffer[20];
106 WriteState state(buffer);
107 char malformed[] = {char(0x80), 0};
108 state = write(state, text(malformed));
109 ASSERT_EQ(Error::MALFORMED_UTF8, state.error_);
110 }
111
TEST(Cbor,MalformendUTF8Test_StringEndsMidMultiByte)112 TEST(Cbor, MalformendUTF8Test_StringEndsMidMultiByte) {
113 uint8_t buffer[20];
114 WriteState state(buffer);
115 char malformed[] = {char(0xc0), 0};
116 state = write(state, text(malformed));
117 ASSERT_EQ(Error::MALFORMED_UTF8, state.error_);
118 }
119
TEST(Cbor,UTF8Test_TwoBytes)120 TEST(Cbor, UTF8Test_TwoBytes) {
121 uint8_t buffer[20];
122 WriteState state(buffer);
123 char neat[] = {char(0xc3), char(0x82), 0};
124 state = write(state, text(neat));
125 ASSERT_EQ(Error::OK, state.error_);
126 }
127
TEST(Cbor,UTF8Test_ThreeBytes)128 TEST(Cbor, UTF8Test_ThreeBytes) {
129 uint8_t buffer[20];
130 WriteState state(buffer);
131 char neat[] = {char(0xe3), char(0x82), char(0x82), 0};
132 state = write(state, text(neat));
133 ASSERT_EQ(Error::OK, state.error_);
134 }
135
TEST(Cbor,UTF8Test_FourBytes)136 TEST(Cbor, UTF8Test_FourBytes) {
137 uint8_t buffer[20];
138 WriteState state(buffer);
139 char neat[] = {char(0xf3), char(0x82), char(0x82), char(0x82), 0};
140 state = write(state, text(neat));
141 ASSERT_EQ(Error::OK, state.error_);
142 }
143
TEST(Cbor,MalformendUTF8Test_CharacterTooLong)144 TEST(Cbor, MalformendUTF8Test_CharacterTooLong) {
145 uint8_t buffer[20];
146 WriteState state(buffer);
147 char malformed[] = {char(0xf8), char(0x82), char(0x82), char(0x82), char(0x82), 0};
148 state = write(state, text(malformed));
149 ASSERT_EQ(Error::MALFORMED_UTF8, state.error_);
150 }
151
TEST(Cbor,MalformendUTF8Test_StringEndsMidMultiByte2)152 TEST(Cbor, MalformendUTF8Test_StringEndsMidMultiByte2) {
153 uint8_t buffer[20];
154 WriteState state(buffer);
155 char malformed[] = {char(0xc0), char(0x82), char(0x83), 0};
156 state = write(state, text(malformed));
157 ASSERT_EQ(Error::MALFORMED_UTF8, state.error_);
158 }
159
TEST(Cbor,MinimalViableHeaderSizeTest)160 TEST(Cbor, MinimalViableHeaderSizeTest) {
161 uint8_t buffer[20];
162 WriteState state(buffer);
163 state = writeHeader(state, Type::NUMBER, 23);
164 ASSERT_EQ(state.data_ - buffer, 1);
165
166 state = WriteState(buffer);
167 state = writeHeader(state, Type::NUMBER, 24);
168 ASSERT_EQ(state.data_ - buffer, 2);
169
170 state = WriteState(buffer);
171 state = writeHeader(state, Type::NUMBER, 0xff);
172 ASSERT_EQ(state.data_ - buffer, 2);
173
174 state = WriteState(buffer);
175 state = writeHeader(state, Type::NUMBER, 0x100);
176 ASSERT_EQ(state.data_ - buffer, 3);
177
178 state = WriteState(buffer);
179 state = writeHeader(state, Type::NUMBER, 0xffff);
180 ASSERT_EQ(state.data_ - buffer, 3);
181
182 state = WriteState(buffer);
183 state = writeHeader(state, Type::NUMBER, 0x10000);
184 ASSERT_EQ(state.data_ - buffer, 5);
185
186 state = WriteState(buffer);
187 state = writeHeader(state, Type::NUMBER, 0xffffffff);
188 ASSERT_EQ(state.data_ - buffer, 5);
189
190 state = WriteState(buffer);
191 state = writeHeader(state, Type::NUMBER, 0x100000000);
192 ASSERT_EQ(state.data_ - buffer, 9);
193
194 state = WriteState(buffer);
195 state = writeHeader(state, Type::NUMBER, 0xffffffffffffffff);
196 ASSERT_EQ(state.data_ - buffer, 9);
197 }
198