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