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 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 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. 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 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 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 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 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 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 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 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 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