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