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 namespace android { 21 namespace hardware { 22 namespace confirmationui { 23 namespace support { 24 namespace { 25 26 inline uint8_t getByte(const uint64_t& v, const uint8_t index) { 27 return v >> (index * 8); 28 } 29 30 WriteState writeBytes(WriteState state, uint64_t value, uint8_t size) { 31 auto pos = state.data_; 32 if (!(state += size)) return state; 33 switch (size) { 34 case 8: 35 *pos++ = getByte(value, 7); 36 *pos++ = getByte(value, 6); 37 *pos++ = getByte(value, 5); 38 *pos++ = getByte(value, 4); 39 case 4: 40 *pos++ = getByte(value, 3); 41 *pos++ = getByte(value, 2); 42 case 2: 43 *pos++ = getByte(value, 1); 44 case 1: 45 *pos++ = value; 46 break; 47 default: 48 state.error_ = Error::MALFORMED; 49 } 50 return state; 51 } 52 53 } // anonymous namespace 54 55 WriteState writeHeader(WriteState wState, Type type, const uint64_t value) { 56 if (!wState) return wState; 57 uint8_t& header = *wState.data_; 58 if (!++wState) return wState; 59 header = static_cast<uint8_t>(type) << 5; 60 if (value < 24) { 61 header |= static_cast<uint8_t>(value); 62 } else if (value < 0x100) { 63 header |= 24; 64 wState = writeBytes(wState, value, 1); 65 } else if (value < 0x10000) { 66 header |= 25; 67 wState = writeBytes(wState, value, 2); 68 } else if (value < 0x100000000) { 69 header |= 26; 70 wState = writeBytes(wState, value, 4); 71 } else { 72 header |= 27; 73 wState = writeBytes(wState, value, 8); 74 } 75 return wState; 76 } 77 78 bool checkUTF8Copy(const char* begin, const char* const end, uint8_t* out) { 79 uint32_t multi_byte_length = 0; 80 while (begin != end) { 81 if (multi_byte_length) { 82 // parsing multi byte character - must start with 10xxxxxx 83 --multi_byte_length; 84 if ((*begin & 0xc0) != 0x80) return false; 85 } else if (!((*begin) & 0x80)) { 86 // 7bit character -> nothing to be done 87 } else { 88 // msb is set and we were not parsing a multi byte character 89 // so this must be a header byte 90 char c = *begin << 1; 91 while (c & 0x80) { 92 ++multi_byte_length; 93 c <<= 1; 94 } 95 // headers of the form 10xxxxxx are not allowed 96 if (multi_byte_length < 1) return false; 97 // chars longer than 4 bytes are not allowed (multi_byte_length does not count the 98 // header thus > 3 99 if (multi_byte_length > 3) return false; 100 } 101 if (out) *out++ = *reinterpret_cast<const uint8_t*>(begin++); 102 } 103 // if the string ends in the middle of a multi byte char it is invalid 104 if (multi_byte_length) return false; 105 return true; 106 } 107 108 } // namespace support 109 } // namespace confirmationui 110 } // namespace hardware 111 } // namespace android 112