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#include "filetransfermanager_fuzzer.h"
16
17#include <cstddef>
18#include <cstdint>
19#include <memory>
20#include <string>
21
22#include "cloud_fuzzer_helper.h"
23#include "file_transfer_manager.h"
24#include "task_state_manager.h"
25
26namespace OHOS {
27constexpr size_t U16_AT_SIZE = 2;
28constexpr size_t U32_AT_SIZE = 4;
29constexpr size_t U64_AT_SIZE = 8;
30
31using namespace std;
32using namespace OHOS::FileManagement::CloudSync;
33
34bool DownloadFileFromRemoteDeviceFuzzTest(shared_ptr<FileTransferManager> fileTransferMgrPtr,
35                                          FuzzData &fuzzData,
36                                          size_t size)
37{
38    fuzzData.ResetData(size);
39    int32_t userId = fuzzData.GetData<int32_t>();
40    uint64_t taskId = fuzzData.GetData<uint64_t>();
41    std::string networkId = fuzzData.GetStringFromData(NETWORK_ID_SIZE_MAX);
42    int len = fuzzData.GetRemainSize();
43    std::string uri = fuzzData.GetStringFromData(len);
44    fileTransferMgrPtr->DownloadFileFromRemoteDevice(networkId, userId, taskId, uri);
45    return true;
46}
47
48bool HandleDownloadFileRequestFuzzTest(shared_ptr<FileTransferManager> fileTransferMgrPtr,
49                                       FuzzData &fuzzData,
50                                       size_t size)
51{
52    fuzzData.ResetData(size);
53    int32_t userId = fuzzData.GetData<int32_t>();
54    uint64_t taskId = fuzzData.GetData<uint64_t>();
55    int receiverSessionId = fuzzData.GetData<int>();
56    std::string senderNetworkId = fuzzData.GetStringFromData(NETWORK_ID_SIZE_MAX);
57    int len = fuzzData.GetRemainSize();
58    std::string uri = fuzzData.GetStringFromData(len);
59    MessageInputInfo msgInputInfo;
60    msgInputInfo.userId = userId;
61    msgInputInfo.taskId = taskId;
62    msgInputInfo.uri = uri;
63    MessageHandler msgHandle(msgInputInfo);
64    fileTransferMgrPtr->HandleDownloadFileRequest(msgHandle, senderNetworkId, receiverSessionId);
65    return true;
66}
67
68bool HandleDownloadFileResponseFuzzTest(shared_ptr<FileTransferManager> fileTransferMgrPtr,
69                                        FuzzData &fuzzData,
70                                        size_t size)
71{
72    fuzzData.ResetData(size);
73    int32_t errorCode = fuzzData.GetData<int32_t>();
74    uint64_t taskId = fuzzData.GetData<uint64_t>();
75    int len = fuzzData.GetRemainSize();
76    std::string uri = fuzzData.GetStringFromData(len);
77    MessageInputInfo msgInputInfo;
78    msgInputInfo.errorCode = errorCode;
79    msgInputInfo.taskId = taskId;
80    msgInputInfo.uri = uri;
81    MessageHandler msgHandle(msgInputInfo);
82    fileTransferMgrPtr->HandleDownloadFileResponse(msgHandle);
83    return true;
84}
85
86bool OnMessageHandleFuzzTest(shared_ptr<FileTransferManager> fileTransferMgrPtr, FuzzData &fuzzData, size_t size)
87{
88    fuzzData.ResetData(size);
89    std::string senderNetworkId = fuzzData.GetStringFromData(NETWORK_ID_SIZE_MAX);
90    int receiverSessionId = fuzzData.GetData<int>();
91    int32_t errorCode = fuzzData.GetData<int32_t>();
92    int32_t userId = fuzzData.GetData<int32_t>();
93    uint64_t taskId = fuzzData.GetData<uint64_t>();
94    uint16_t msgType =
95        fuzzData.GetData<uint16_t>() % (MsgType::MSG_FINISH_FILE_RECV + static_cast<int16_t>(U16_AT_SIZE));
96    int len = static_cast<int>(fuzzData.GetRemainSize());
97    std::string uri = fuzzData.GetStringFromData(len);
98    MessageInputInfo msgInputInfo;
99    msgInputInfo.errorCode = errorCode;
100    msgInputInfo.taskId = taskId;
101    msgInputInfo.uri = uri;
102    msgInputInfo.userId = userId;
103    msgInputInfo.msgType = msgType;
104    MessageHandler msgHandle(msgInputInfo);
105    auto dataSubPtr = std::make_unique<uint8_t[]>(size);
106    msgHandle.PackData(dataSubPtr.get(), static_cast<uint32_t>(size));
107    fileTransferMgrPtr->OnMessageHandle(senderNetworkId, receiverSessionId, dataSubPtr.get(), msgHandle.GetDataSize());
108    return true;
109}
110
111bool OnFileRecvHandleFuzzTest(shared_ptr<FileTransferManager> fileTransferMgrPtr, FuzzData &fuzzData, size_t size)
112{
113    fuzzData.ResetData(size);
114    std::string senderNetworkId = fuzzData.GetStringFromData(NETWORK_ID_SIZE_MAX);
115    int result = fuzzData.GetData<int>();
116    int len = static_cast<int>(fuzzData.GetRemainSize());
117    std::string filePath = fuzzData.GetStringFromData(len);
118    fileTransferMgrPtr->OnFileRecvHandle(senderNetworkId, filePath.c_str(), result);
119    fileTransferMgrPtr->HandleRecvFileFinished();
120    fileTransferMgrPtr->OnSessionClosed();
121    return true;
122}
123} // namespace OHOS
124
125/* Fuzzer entry point */
126extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size)
127{
128    /* Run your code on data */
129    if (data == nullptr || size <= (OHOS::U16_AT_SIZE + OHOS::U64_AT_SIZE + (OHOS::U32_AT_SIZE << 1) +
130                                    (OHOS::FileManagement::CloudSync::NETWORK_ID_SIZE_MAX << 1))) {
131        return 0;
132    }
133
134    OHOS::FuzzData fuzzData(data, size);
135    auto sessionMgrPtr = std::make_shared<OHOS::FileManagement::CloudSync::SessionManager>();
136    std::shared_ptr<OHOS::FileManagement::CloudSync::FileTransferManager> fileTransferMgrPtr =
137        std::make_shared<OHOS::FileManagement::CloudSync::FileTransferManager>(sessionMgrPtr);
138    fileTransferMgrPtr->Init();
139
140    OHOS::DownloadFileFromRemoteDeviceFuzzTest(fileTransferMgrPtr, fuzzData, size);
141    OHOS::HandleDownloadFileRequestFuzzTest(fileTransferMgrPtr, fuzzData, size);
142    OHOS::HandleDownloadFileResponseFuzzTest(fileTransferMgrPtr, fuzzData, size);
143    OHOS::OnMessageHandleFuzzTest(fileTransferMgrPtr, fuzzData, size);
144    OHOS::OnFileRecvHandleFuzzTest(fileTransferMgrPtr, fuzzData, size);
145
146    if (OHOS::FileManagement::CloudSync::TaskStateManager::GetInstance().unloadTaskHandle_ != nullptr) {
147        OHOS::FileManagement::CloudSync::TaskStateManager::GetInstance().queue_.wait(
148            OHOS::FileManagement::CloudSync::TaskStateManager::GetInstance().unloadTaskHandle_);
149    }
150    return 0;
151}
152