1/* 2 * Copyright (c) 2024 Huawei Device Co., Ltd. 3 * Licensed under the Apache License, Version 2.0 (the "License"); 4 * you may not use this file except in compliance with the License. 5 * You may obtain a copy of the License at 6 * 7 * http://www.apache.org/licenses/LICENSE-2.0 8 * 9 * Unless required by applicable law or agreed to in writing, software 10 * distributed under the License is distributed on an "AS IS" BASIS, 11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 * See the License for the specific language governing permissions and 13 * limitations under the License. 14 */ 15 16#include "camera.h" 17#include "camera_metadata_operator.h" 18#include "metadata_utils.h" 19 20using namespace OHOS::Camera; 21namespace OHOS { 22const size_t THRESHOLD = 12; 23 24enum BitOperat { 25 INDEX_0 = 0, 26 INDEX_1, 27 INDEX_2, 28 INDEX_3, 29 OFFSET, 30 MOVE_EIGHT_BITS = 8, 31 MOVE_SIXTEEN_BITS = 16, 32 DATA_TYPE_OFFSET = 20, 33 MOVE_TWENTY_FOUR_BITS = 24, 34 META_HEADER_SIZE = 28, 35}; 36static uint32_t ConvertUint32(const uint8_t *bitOperat) 37{ 38 if (bitOperat == nullptr) { 39 return 0; 40 } 41 42 return (bitOperat[INDEX_0] << MOVE_TWENTY_FOUR_BITS) | (bitOperat[INDEX_1] << MOVE_SIXTEEN_BITS) | 43 (bitOperat[INDEX_2] << MOVE_EIGHT_BITS) | (bitOperat[INDEX_3]); 44} 45 46uint32_t GetMinInputSize(const uint8_t *rawData) 47{ 48 uint32_t dataType = ConvertUint32(rawData + DATA_TYPE_OFFSET); 49 uint32_t dataSize; 50 switch (dataType) { 51 case META_TYPE_BYTE: 52 dataSize = sizeof(uint8_t); 53 break; 54 case META_TYPE_INT32: 55 dataSize = sizeof(int32_t); 56 break; 57 case META_TYPE_UINT32: 58 dataSize = sizeof(uint32_t); 59 break; 60 case META_TYPE_FLOAT: 61 dataSize = sizeof(float); 62 break; 63 case META_TYPE_INT64: 64 dataSize = sizeof(int64_t); 65 break; 66 case META_TYPE_DOUBLE: 67 dataSize = sizeof(double); 68 break; 69 case META_TYPE_RATIONAL: 70 dataSize = sizeof(camera_rational_t); 71 break; 72 default: 73 dataSize = 0; 74 break; 75 } 76 uint32_t dataCount = ConvertUint32(rawData + MOVE_TWENTY_FOUR_BITS); 77 uint32_t maxValue = std::numeric_limits<uint32_t>::max(); 78 if (dataSize == 0 || dataCount == 0 || dataCount > (maxValue - META_HEADER_SIZE)/dataSize) { 79 return 0; 80 } 81 return (META_HEADER_SIZE + dataSize * dataCount); 82} 83 84void FuncEncodeCameraMetadata(const uint8_t *rawData, size_t size) 85{ 86 MessageParcel data; 87 std::shared_ptr<CameraMetadata> metadata 88 = std::make_shared<CameraMetadata>(MAX_ITEM_CAPACITY, MAX_ITEM_CAPACITY); 89 std::vector<uint8_t> cameraAbility(rawData, rawData + size); 90 MetadataUtils::ConvertVecToMetadata(cameraAbility, metadata); 91 92 MetadataUtils::EncodeCameraMetadata(metadata, data); 93} 94 95void FuncDecodeCameraMetadata(const uint8_t *rawData, size_t size) 96{ 97 MessageParcel data; 98 std::vector<uint32_t> dataVec(rawData, rawData + size); 99 data.WriteUInt32Vector(dataVec); 100 std::shared_ptr<CameraMetadata> metadata 101 = std::make_shared<CameraMetadata>(MAX_ITEM_CAPACITY, MAX_ITEM_CAPACITY); 102 103 MetadataUtils::DecodeCameraMetadata(data, metadata); 104} 105 106void FuncEncodeToString(const uint8_t *rawData, size_t size) 107{ 108 std::shared_ptr<CameraMetadata> metadata 109 = std::make_shared<CameraMetadata>(MAX_ITEM_CAPACITY, MAX_ITEM_CAPACITY); 110 std::vector<uint8_t> cameraAbility(rawData, rawData + size); 111 MetadataUtils::ConvertVecToMetadata(cameraAbility, metadata); 112 113 MetadataUtils::EncodeToString(metadata); 114} 115 116void FuncDecodeFromString(const uint8_t *rawData, size_t size) 117{ 118 std::string str(rawData, rawData + size); 119 MetadataUtils::DecodeFromString(str); 120} 121 122void FuncConvertMetadataToVec(const uint8_t *rawData, size_t size) 123{ 124 std::shared_ptr<CameraMetadata> metadata 125 = std::make_shared<CameraMetadata>(MAX_ITEM_CAPACITY, MAX_ITEM_CAPACITY); 126 std::vector<uint8_t> cameraAbility(rawData, rawData + size); 127 MetadataUtils::ConvertVecToMetadata(cameraAbility, metadata); 128 129 std::vector<uint8_t> metaVec; 130 MetadataUtils::ConvertMetadataToVec(metadata, metaVec); 131} 132 133void FuncConvertVecToMetadata(const uint8_t *rawData, size_t size) 134{ 135 std::shared_ptr<CameraMetadata> metadata 136 = std::make_shared<CameraMetadata>(MAX_ITEM_CAPACITY, MAX_ITEM_CAPACITY); 137 std::vector<uint8_t> cameraAbility(rawData, rawData + size); 138 MetadataUtils::ConvertVecToMetadata(cameraAbility, metadata); 139} 140 141typedef void (*TestFuncDef)(const uint8_t *rawData, size_t size); 142static TestFuncDef g_allTestFunc[] = { 143 FuncEncodeCameraMetadata, 144 FuncDecodeCameraMetadata, 145 FuncEncodeToString, 146 FuncDecodeFromString, 147 FuncConvertMetadataToVec, 148 FuncConvertVecToMetadata, 149}; 150 151 152static void TestFuncSwitch(uint32_t cmd, const uint8_t *rawData, size_t size) 153{ 154 int testCount = sizeof(g_allTestFunc) / sizeof(g_allTestFunc[0]); 155 TestFuncDef curFunc = g_allTestFunc[cmd % testCount]; 156 curFunc(rawData, size); 157} 158 159bool DoSomethingInterestingWithMyApi(const uint8_t *rawData, size_t size) 160{ 161 if (rawData == nullptr) { 162 return false; 163 } 164 165 uint32_t cmd = 0; 166 rawData += sizeof(cmd); 167 168 uint32_t minInputSize = GetMinInputSize(rawData); 169 if (size < minInputSize || minInputSize == 0) { 170 return false; 171 } 172 173 TestFuncSwitch(cmd, rawData, size); 174 return true; 175} 176 177extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) 178{ 179 if (size < OHOS::THRESHOLD) { 180 CAMERA_LOGW("Fuzz test input is invalid. The size is smaller than %{public}zu", OHOS::THRESHOLD); 181 return 0; 182 } 183 184 OHOS::DoSomethingInterestingWithMyApi(data, size); 185 return 0; 186} 187} // namespace OHOS