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 20namespace android { 21namespace hardware { 22namespace confirmationui { 23namespace support { 24namespace { 25 26inline uint8_t getByte(const uint64_t& v, const uint8_t index) { 27 return v >> (index * 8); 28} 29 30WriteState 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 55WriteState 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 78bool 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