1094332d3Sopenharmony_ci/*
2094332d3Sopenharmony_ci * Copyright (c) 2024 Huawei Device Co., Ltd.
3094332d3Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License");
4094332d3Sopenharmony_ci * you may not use this file except in compliance with the License.
5094332d3Sopenharmony_ci * You may obtain a copy of the License at
6094332d3Sopenharmony_ci *
7094332d3Sopenharmony_ci *     http://www.apache.org/licenses/LICENSE-2.0
8094332d3Sopenharmony_ci *
9094332d3Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software
10094332d3Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS,
11094332d3Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12094332d3Sopenharmony_ci * See the License for the specific language governing permissions and
13094332d3Sopenharmony_ci * limitations under the License.
14094332d3Sopenharmony_ci */
15094332d3Sopenharmony_ci
16094332d3Sopenharmony_ci#include "camera.h"
17094332d3Sopenharmony_ci#include "camera_metadata_operator.h"
18094332d3Sopenharmony_ci#include "metadata_utils.h"
19094332d3Sopenharmony_ci
20094332d3Sopenharmony_ciusing namespace OHOS::Camera;
21094332d3Sopenharmony_cinamespace OHOS {
22094332d3Sopenharmony_ciconst size_t THRESHOLD = 12;
23094332d3Sopenharmony_ci
24094332d3Sopenharmony_cienum BitOperat {
25094332d3Sopenharmony_ci    INDEX_0 = 0,
26094332d3Sopenharmony_ci    INDEX_1,
27094332d3Sopenharmony_ci    INDEX_2,
28094332d3Sopenharmony_ci    INDEX_3,
29094332d3Sopenharmony_ci    OFFSET,
30094332d3Sopenharmony_ci    MOVE_EIGHT_BITS = 8,
31094332d3Sopenharmony_ci    MOVE_SIXTEEN_BITS = 16,
32094332d3Sopenharmony_ci    DATA_TYPE_OFFSET = 20,
33094332d3Sopenharmony_ci    MOVE_TWENTY_FOUR_BITS = 24,
34094332d3Sopenharmony_ci    META_HEADER_SIZE = 28,
35094332d3Sopenharmony_ci};
36094332d3Sopenharmony_cistatic uint32_t ConvertUint32(const uint8_t *bitOperat)
37094332d3Sopenharmony_ci{
38094332d3Sopenharmony_ci    if (bitOperat == nullptr) {
39094332d3Sopenharmony_ci        return 0;
40094332d3Sopenharmony_ci    }
41094332d3Sopenharmony_ci
42094332d3Sopenharmony_ci    return (bitOperat[INDEX_0] << MOVE_TWENTY_FOUR_BITS) | (bitOperat[INDEX_1] << MOVE_SIXTEEN_BITS) |
43094332d3Sopenharmony_ci        (bitOperat[INDEX_2] << MOVE_EIGHT_BITS) | (bitOperat[INDEX_3]);
44094332d3Sopenharmony_ci}
45094332d3Sopenharmony_ci
46094332d3Sopenharmony_ciuint32_t GetMinInputSize(const uint8_t *rawData)
47094332d3Sopenharmony_ci{
48094332d3Sopenharmony_ci    uint32_t dataType = ConvertUint32(rawData + DATA_TYPE_OFFSET);
49094332d3Sopenharmony_ci    uint32_t dataSize;
50094332d3Sopenharmony_ci    switch (dataType) {
51094332d3Sopenharmony_ci        case META_TYPE_BYTE:
52094332d3Sopenharmony_ci            dataSize = sizeof(uint8_t);
53094332d3Sopenharmony_ci            break;
54094332d3Sopenharmony_ci        case META_TYPE_INT32:
55094332d3Sopenharmony_ci            dataSize = sizeof(int32_t);
56094332d3Sopenharmony_ci            break;
57094332d3Sopenharmony_ci        case META_TYPE_UINT32:
58094332d3Sopenharmony_ci            dataSize = sizeof(uint32_t);
59094332d3Sopenharmony_ci            break;
60094332d3Sopenharmony_ci        case META_TYPE_FLOAT:
61094332d3Sopenharmony_ci            dataSize = sizeof(float);
62094332d3Sopenharmony_ci            break;
63094332d3Sopenharmony_ci        case META_TYPE_INT64:
64094332d3Sopenharmony_ci            dataSize = sizeof(int64_t);
65094332d3Sopenharmony_ci            break;
66094332d3Sopenharmony_ci        case META_TYPE_DOUBLE:
67094332d3Sopenharmony_ci            dataSize = sizeof(double);
68094332d3Sopenharmony_ci            break;
69094332d3Sopenharmony_ci        case META_TYPE_RATIONAL:
70094332d3Sopenharmony_ci            dataSize = sizeof(camera_rational_t);
71094332d3Sopenharmony_ci            break;
72094332d3Sopenharmony_ci        default:
73094332d3Sopenharmony_ci            dataSize = 0;
74094332d3Sopenharmony_ci            break;
75094332d3Sopenharmony_ci    }
76094332d3Sopenharmony_ci    uint32_t dataCount = ConvertUint32(rawData + MOVE_TWENTY_FOUR_BITS);
77094332d3Sopenharmony_ci    uint32_t maxValue = std::numeric_limits<uint32_t>::max();
78094332d3Sopenharmony_ci    if (dataSize == 0 || dataCount == 0 || dataCount > (maxValue - META_HEADER_SIZE)/dataSize) {
79094332d3Sopenharmony_ci        return 0;
80094332d3Sopenharmony_ci    }
81094332d3Sopenharmony_ci    return (META_HEADER_SIZE + dataSize * dataCount);
82094332d3Sopenharmony_ci}
83094332d3Sopenharmony_ci
84094332d3Sopenharmony_civoid FuncEncodeCameraMetadata(const uint8_t *rawData, size_t size)
85094332d3Sopenharmony_ci{
86094332d3Sopenharmony_ci    MessageParcel data;
87094332d3Sopenharmony_ci    std::shared_ptr<CameraMetadata> metadata
88094332d3Sopenharmony_ci        = std::make_shared<CameraMetadata>(MAX_ITEM_CAPACITY, MAX_ITEM_CAPACITY);
89094332d3Sopenharmony_ci    std::vector<uint8_t> cameraAbility(rawData, rawData + size);
90094332d3Sopenharmony_ci    MetadataUtils::ConvertVecToMetadata(cameraAbility, metadata);
91094332d3Sopenharmony_ci
92094332d3Sopenharmony_ci    MetadataUtils::EncodeCameraMetadata(metadata, data);
93094332d3Sopenharmony_ci}
94094332d3Sopenharmony_ci
95094332d3Sopenharmony_civoid FuncDecodeCameraMetadata(const uint8_t *rawData, size_t size)
96094332d3Sopenharmony_ci{
97094332d3Sopenharmony_ci    MessageParcel data;
98094332d3Sopenharmony_ci    std::vector<uint32_t> dataVec(rawData, rawData + size);
99094332d3Sopenharmony_ci    data.WriteUInt32Vector(dataVec);
100094332d3Sopenharmony_ci    std::shared_ptr<CameraMetadata> metadata
101094332d3Sopenharmony_ci        = std::make_shared<CameraMetadata>(MAX_ITEM_CAPACITY, MAX_ITEM_CAPACITY);
102094332d3Sopenharmony_ci
103094332d3Sopenharmony_ci    MetadataUtils::DecodeCameraMetadata(data, metadata);
104094332d3Sopenharmony_ci}
105094332d3Sopenharmony_ci
106094332d3Sopenharmony_civoid FuncEncodeToString(const uint8_t *rawData, size_t size)
107094332d3Sopenharmony_ci{
108094332d3Sopenharmony_ci    std::shared_ptr<CameraMetadata> metadata
109094332d3Sopenharmony_ci        = std::make_shared<CameraMetadata>(MAX_ITEM_CAPACITY, MAX_ITEM_CAPACITY);
110094332d3Sopenharmony_ci    std::vector<uint8_t> cameraAbility(rawData, rawData + size);
111094332d3Sopenharmony_ci    MetadataUtils::ConvertVecToMetadata(cameraAbility, metadata);
112094332d3Sopenharmony_ci
113094332d3Sopenharmony_ci    MetadataUtils::EncodeToString(metadata);
114094332d3Sopenharmony_ci}
115094332d3Sopenharmony_ci
116094332d3Sopenharmony_civoid FuncDecodeFromString(const uint8_t *rawData, size_t size)
117094332d3Sopenharmony_ci{
118094332d3Sopenharmony_ci    std::string str(rawData, rawData + size);
119094332d3Sopenharmony_ci    MetadataUtils::DecodeFromString(str);
120094332d3Sopenharmony_ci}
121094332d3Sopenharmony_ci
122094332d3Sopenharmony_civoid FuncConvertMetadataToVec(const uint8_t *rawData, size_t size)
123094332d3Sopenharmony_ci{
124094332d3Sopenharmony_ci    std::shared_ptr<CameraMetadata> metadata
125094332d3Sopenharmony_ci        = std::make_shared<CameraMetadata>(MAX_ITEM_CAPACITY, MAX_ITEM_CAPACITY);
126094332d3Sopenharmony_ci    std::vector<uint8_t> cameraAbility(rawData, rawData + size);
127094332d3Sopenharmony_ci    MetadataUtils::ConvertVecToMetadata(cameraAbility, metadata);
128094332d3Sopenharmony_ci
129094332d3Sopenharmony_ci    std::vector<uint8_t> metaVec;
130094332d3Sopenharmony_ci    MetadataUtils::ConvertMetadataToVec(metadata, metaVec);
131094332d3Sopenharmony_ci}
132094332d3Sopenharmony_ci
133094332d3Sopenharmony_civoid FuncConvertVecToMetadata(const uint8_t *rawData, size_t size)
134094332d3Sopenharmony_ci{
135094332d3Sopenharmony_ci    std::shared_ptr<CameraMetadata> metadata
136094332d3Sopenharmony_ci        = std::make_shared<CameraMetadata>(MAX_ITEM_CAPACITY, MAX_ITEM_CAPACITY);
137094332d3Sopenharmony_ci    std::vector<uint8_t> cameraAbility(rawData, rawData + size);
138094332d3Sopenharmony_ci    MetadataUtils::ConvertVecToMetadata(cameraAbility, metadata);
139094332d3Sopenharmony_ci}
140094332d3Sopenharmony_ci
141094332d3Sopenharmony_citypedef void (*TestFuncDef)(const uint8_t *rawData, size_t size);
142094332d3Sopenharmony_cistatic TestFuncDef g_allTestFunc[] = {
143094332d3Sopenharmony_ci    FuncEncodeCameraMetadata,
144094332d3Sopenharmony_ci    FuncDecodeCameraMetadata,
145094332d3Sopenharmony_ci    FuncEncodeToString,
146094332d3Sopenharmony_ci    FuncDecodeFromString,
147094332d3Sopenharmony_ci    FuncConvertMetadataToVec,
148094332d3Sopenharmony_ci    FuncConvertVecToMetadata,
149094332d3Sopenharmony_ci};
150094332d3Sopenharmony_ci
151094332d3Sopenharmony_ci
152094332d3Sopenharmony_cistatic void TestFuncSwitch(uint32_t cmd, const uint8_t *rawData, size_t size)
153094332d3Sopenharmony_ci{
154094332d3Sopenharmony_ci    int testCount = sizeof(g_allTestFunc) / sizeof(g_allTestFunc[0]);
155094332d3Sopenharmony_ci    TestFuncDef curFunc = g_allTestFunc[cmd % testCount];
156094332d3Sopenharmony_ci    curFunc(rawData, size);
157094332d3Sopenharmony_ci}
158094332d3Sopenharmony_ci
159094332d3Sopenharmony_cibool DoSomethingInterestingWithMyApi(const uint8_t *rawData, size_t size)
160094332d3Sopenharmony_ci{
161094332d3Sopenharmony_ci    if (rawData == nullptr) {
162094332d3Sopenharmony_ci        return false;
163094332d3Sopenharmony_ci    }
164094332d3Sopenharmony_ci
165094332d3Sopenharmony_ci    uint32_t cmd = 0;
166094332d3Sopenharmony_ci    rawData += sizeof(cmd);
167094332d3Sopenharmony_ci
168094332d3Sopenharmony_ci    uint32_t minInputSize = GetMinInputSize(rawData);
169094332d3Sopenharmony_ci    if (size < minInputSize || minInputSize == 0) {
170094332d3Sopenharmony_ci        return false;
171094332d3Sopenharmony_ci    }
172094332d3Sopenharmony_ci
173094332d3Sopenharmony_ci    TestFuncSwitch(cmd, rawData, size);
174094332d3Sopenharmony_ci    return true;
175094332d3Sopenharmony_ci}
176094332d3Sopenharmony_ci
177094332d3Sopenharmony_ciextern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size)
178094332d3Sopenharmony_ci{
179094332d3Sopenharmony_ci    if (size < OHOS::THRESHOLD) {
180094332d3Sopenharmony_ci        CAMERA_LOGW("Fuzz test input is invalid. The size is smaller than %{public}zu", OHOS::THRESHOLD);
181094332d3Sopenharmony_ci        return 0;
182094332d3Sopenharmony_ci    }
183094332d3Sopenharmony_ci
184094332d3Sopenharmony_ci    OHOS::DoSomethingInterestingWithMyApi(data, size);
185094332d3Sopenharmony_ci    return 0;
186094332d3Sopenharmony_ci}
187094332d3Sopenharmony_ci} // namespace OHOS