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
20 using namespace OHOS::Camera;
21 namespace OHOS {
22 const size_t THRESHOLD = 12;
23
24 enum 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 };
ConvertUint32(const uint8_t * bitOperat)36 static 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
GetMinInputSize(const uint8_t * rawData)46 uint32_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
FuncEncodeCameraMetadata(const uint8_t * rawData,size_t size)84 void 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
FuncDecodeCameraMetadata(const uint8_t * rawData,size_t size)95 void 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
FuncEncodeToString(const uint8_t * rawData,size_t size)106 void 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
FuncDecodeFromString(const uint8_t * rawData,size_t size)116 void FuncDecodeFromString(const uint8_t *rawData, size_t size)
117 {
118 std::string str(rawData, rawData + size);
119 MetadataUtils::DecodeFromString(str);
120 }
121
FuncConvertMetadataToVec(const uint8_t * rawData,size_t size)122 void 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
FuncConvertVecToMetadata(const uint8_t * rawData,size_t size)133 void 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
141 typedef void (*TestFuncDef)(const uint8_t *rawData, size_t size);
142 static TestFuncDef g_allTestFunc[] = {
143 FuncEncodeCameraMetadata,
144 FuncDecodeCameraMetadata,
145 FuncEncodeToString,
146 FuncDecodeFromString,
147 FuncConvertMetadataToVec,
148 FuncConvertVecToMetadata,
149 };
150
151
TestFuncSwitch(uint32_t cmd,const uint8_t * rawData,size_t size)152 static 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
DoSomethingInterestingWithMyApi(const uint8_t * rawData,size_t size)159 bool 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
LLVMFuzzerTestOneInput(const uint8_t * data,size_t size)177 extern "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