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