1/*
2 * Copyright (c) 2021-2023 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_device_fuzzer.h"
17#include "camera.h"
18#include "v1_1/icamera_device.h"
19
20namespace OHOS::Camera {
21const size_t RAW_DATA_SIZE_MAX = 256;
22const size_t THRESHOLD = 10;
23
24enum DeviceCmdId {
25    CAMERA_DEVICE_GET_DEFAULT_SETTINGS,
26    CAMERA_DEVICE_GET_STREAM_V1_1,
27    CAMERA_DEVICE_UPDATE_SETTINGS,
28    CAMERA_DEVICE_SET_RESULT_MODE,
29    CAMERA_DEVICE_GET_ENABLED_RESULTS,
30    CAMERA_DEVICE_ENABLE_RESULT,
31    CAMERA_DEVICE_DISABLE_RESULT,
32    CAMERA_DEVICE_GET_STATUS,
33    CAMERA_DEVICE_GET_SECURECAMERASEQ,
34    CAMERA_DEVICE_END, // Enumerated statistical value. The new enumerated value is added before
35};
36
37void FuncGetDefaultSettings(const uint8_t *rawData, size_t size)
38{
39    if (size >= RAW_DATA_SIZE_MAX) {
40        return;
41    }
42    std::vector<uint8_t> abilityVec = {};
43    uint8_t *data = const_cast<uint8_t *>(rawData);
44    abilityVec.push_back(*data);
45    cameraTest->cameraDeviceV1_3->GetDefaultSettings(abilityVec);
46}
47
48void FuncGetStreamOperator_V1_1(const uint8_t *rawData, size_t size)
49{
50    (void)size;
51    sptr<HDI::Camera::V1_0::IStreamOperatorCallback> g_callback =
52        new OHOS::Camera::HdiCommon::TestStreamOperatorCallback();
53    sptr<HDI::Camera::V1_1::IStreamOperator> g_StreamOperator = nullptr;
54    cameraTest->cameraDeviceV1_3->GetStreamOperator_V1_1(g_callback, g_StreamOperator);
55}
56
57void FuncUpdateSettings(const uint8_t *rawData, size_t size)
58{
59    if (size >= RAW_DATA_SIZE_MAX) {
60        return;
61    }
62    float *data = const_cast<float *>(reinterpret_cast<const float *>(rawData));
63    std::shared_ptr<CameraMetadata> meta = std::make_shared<CameraMetadata>(
64        cameraTest->itemCapacity, cameraTest->dataCapacity);
65    meta->addEntry(OHOS_CONTROL_ZOOM_RATIO, &data[0], cameraTest->dataCount);
66    std::vector<uint8_t> metaVec;
67    MetadataUtils::ConvertMetadataToVec(meta, metaVec);
68    cameraTest->cameraDeviceV1_3->UpdateSettings(metaVec);
69}
70
71void FuncSetResultMode(const uint8_t *rawData, size_t size)
72{
73    (void)size;
74    cameraTest->cameraDeviceV1_3->SetResultMode(
75        *reinterpret_cast<const HDI::Camera::V1_0::ResultCallbackMode *>(rawData));
76}
77
78void FuncGetEnabledResults(const uint8_t *rawData, size_t size)
79{
80    (void)size;
81    std::vector<int32_t> result = {};
82    int32_t *data = const_cast<int32_t *>(reinterpret_cast<const int32_t *>(rawData));
83    result.push_back(*data);
84    cameraTest->cameraDeviceV1_3->GetEnabledResults(result);
85}
86
87void FuncEnableResult(const uint8_t *rawData, size_t size)
88{
89    (void)size;
90    std::vector<int32_t> result = {};
91    int32_t *data = const_cast<int32_t *>(reinterpret_cast<const int32_t *>(rawData));
92    result.push_back(*data);
93    cameraTest->cameraDeviceV1_3->EnableResult(result);
94}
95
96void FuncDisableResult(const uint8_t *rawData, size_t size)
97{
98    (void)size;
99    std::vector<int32_t> result = {};
100    int32_t *data = const_cast<int32_t *>(reinterpret_cast<const int32_t *>(rawData));
101    result.push_back(*data);
102    cameraTest->cameraDeviceV1_3->DisableResult(result);
103}
104
105void FuncGetStatus(const uint8_t *rawData, size_t size)
106{
107    (void)size;
108    std::vector<uint8_t> resultOut = {};
109    float *data = const_cast<float *>(reinterpret_cast<const float *>(rawData));
110    std::shared_ptr<CameraMetadata> meta = std::make_shared<CameraMetadata>(
111        cameraTest->itemCapacity, cameraTest->dataCapacity);
112    meta->addEntry(OHOS_CONTROL_ZOOM_RATIO, &data[0], cameraTest->dataCount);
113    std::vector<uint8_t> metaVec;
114    MetadataUtils::ConvertMetadataToVec(meta, metaVec);
115    if (nullptr == cameraTest->cameraDeviceV1_3) {
116        return;
117    }
118    cameraTest->cameraDeviceV1_3->GetStatus(metaVec, resultOut);
119}
120
121void FuncGetSecureCameraSeq(const uint8_t *rawData, size_t size)
122{
123    (void)size;
124    if (nullptr == cameraTest->cameraDeviceV1_3) {
125        return;
126    }
127    uint64_t SeqId;
128    // Output do not need fuzz
129    cameraTest->cameraDeviceV1_3->GetSecureCameraSeq(SeqId);
130}
131
132static void DeviceFuncSwitch(uint32_t cmd, const uint8_t *rawData, size_t size)
133{
134    CAMERA_LOGI("DeviceFuncSwitch start, the cmd is:%{public}u", cmd);
135    switch (cmd) {
136        case CAMERA_DEVICE_GET_DEFAULT_SETTINGS: {
137            FuncGetDefaultSettings(rawData, size);
138            break;
139        }
140        case CAMERA_DEVICE_GET_STREAM_V1_1: {
141            FuncGetStreamOperator_V1_1(rawData, size);
142            break;
143        }
144
145        case CAMERA_DEVICE_UPDATE_SETTINGS: {
146            FuncUpdateSettings(rawData, size);
147            break;
148        }
149        case CAMERA_DEVICE_SET_RESULT_MODE: {
150            FuncSetResultMode(rawData, size);
151            break;
152        }
153        case CAMERA_DEVICE_GET_ENABLED_RESULTS: {
154            FuncGetEnabledResults(rawData, size);
155            break;
156        }
157        case CAMERA_DEVICE_ENABLE_RESULT: {
158            FuncEnableResult(rawData, size);
159            break;
160        }
161        case CAMERA_DEVICE_DISABLE_RESULT: {
162            FuncDisableResult(rawData, size);
163            break;
164        }
165        case CAMERA_DEVICE_GET_STATUS: {
166            FuncGetStatus(rawData, size);
167            break;
168        }
169        case CAMERA_DEVICE_GET_SECURECAMERASEQ: {
170            FuncGetSecureCameraSeq(rawData, size);
171            break;
172        }
173        default: {
174            CAMERA_LOGW("The interfaces is not tested, the cmd is:%{public}u", cmd);
175            return;
176        }
177    }
178}
179
180bool DoSomethingInterestingWithMyApi(const uint8_t *rawData, size_t size)
181{
182    if (rawData == nullptr) {
183        return false;
184    }
185
186    uint32_t cmd = 0;
187    rawData += sizeof(cmd);
188
189    cameraTest = std::make_shared<OHOS::Camera::HdiCommonV1_3>();
190    cameraTest->Init();
191    if (cameraTest->serviceV1_3 == nullptr) {
192        return false;
193    }
194    cameraTest->Open(DEVICE_0);
195    if (cameraTest->cameraDeviceV1_3 == nullptr) {
196        return false;
197    }
198
199    for (cmd = 0; cmd < CAMERA_DEVICE_END; cmd++) {
200        DeviceFuncSwitch(cmd, rawData, size);
201    }
202    cameraTest->Close();
203    return true;
204}
205
206extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size)
207{
208    if (size < THRESHOLD) {
209        CAMERA_LOGW("Fuzz test input is invalid. The size is smaller than %{public}zu", THRESHOLD);
210        return 0;
211    }
212
213    DoSomethingInterestingWithMyApi(data, size);
214    return 0;
215}
216} // namespace OHOS
217