1/*
2 * Copyright (c) 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 "gsmsmsmessage_fuzzer.h"
17
18#define private public
19#include "addsmstoken_fuzzer.h"
20#include "core_manager_inner.h"
21#include "i_sms_service_interface.h"
22#include "sms_service.h"
23
24using namespace OHOS::Telephony;
25namespace OHOS {
26static bool g_isInited = false;
27static constexpr int32_t SLOT_NUM = 2;
28static constexpr int32_t UINT8_COUNT = 256;
29static constexpr int32_t UINT16_COUNT = 65536;
30static constexpr int32_t DATA_LEN = 160 * 15;
31static constexpr int32_t CODE_SCHEME_SIZE = 6;
32constexpr int32_t SLEEP_TIME_SECONDS = 1;
33
34bool IsServiceInited()
35{
36    if (!g_isInited) {
37        CoreManagerInner::GetInstance().isInitAllObj_ = true;
38        DelayedSingleton<SmsService>::GetInstance()->registerToService_ = true;
39        DelayedSingleton<SmsService>::GetInstance()->WaitCoreServiceToInit();
40        DelayedSingleton<SmsService>::GetInstance()->OnStart();
41        if (DelayedSingleton<SmsService>::GetInstance()->GetServiceRunningState() ==
42            static_cast<int32_t>(Telephony::ServiceRunningState::STATE_RUNNING)) {
43            g_isInited = true;
44        }
45    }
46    return g_isInited;
47}
48
49void CreateMessageTest(const uint8_t *data, size_t size)
50{
51    if (!IsServiceInited()) {
52        return;
53    }
54    std::string pdu(reinterpret_cast<const char *>(data), size);
55    GsmSmsMessage msg;
56    msg.CreateMessage(pdu);
57    msg.PduAnalysis(pdu);
58    SmsDeliver deliver;
59    msg.AnalysisMsgDeliver(deliver);
60    SmsStatusReport status;
61    msg.AnalysisMsgStatusReport(status);
62    SmsSubmit submit;
63    msg.AnalysisMsgSubmit(submit);
64}
65
66void CalcReplyEncodeAddress(const uint8_t *data, size_t size)
67{
68    if (!IsServiceInited()) {
69        return;
70    }
71    GsmSmsMessage msg;
72    std::string replyAddr(reinterpret_cast<const char *>(data), size);
73    msg.CalcReplyEncodeAddress(replyAddr);
74    std::string replyAddress(reinterpret_cast<const char *>(data), 0);
75    msg.CalcReplyEncodeAddress(replyAddress);
76
77    SmsTimeStamp times;
78    times.format = static_cast<SmsTimeFormat>(size);
79    times.time.absolute.day = static_cast<uint8_t>(size);
80    times.time.absolute.hour = static_cast<uint8_t>(size);
81    times.time.absolute.minute = static_cast<uint8_t>(size);
82    times.time.absolute.month = static_cast<uint8_t>(size);
83    times.time.absolute.second = static_cast<uint8_t>(size);
84    times.time.absolute.timeZone = static_cast<uint8_t>(size);
85    times.time.absolute.year = static_cast<uint8_t>(size);
86    msg.ConvertMsgTimeStamp(times);
87
88    SmsTimeStamp stamp;
89    stamp.format = static_cast<SmsTimeFormat>(size);
90    stamp.time.relative.time = static_cast<uint8_t>(size);
91    msg.ConvertMsgTimeStamp(stamp);
92
93    msg.GetIsSIMDataTypeDownload();
94    msg.GetIsTypeZeroInd();
95    msg.GetGsm();
96    msg.GetIsSmsText();
97    msg.GetDestPort();
98    msg.GetDestAddress();
99    msg.GetReplyAddress();
100    msg.GetFullText();
101
102    std::string text(reinterpret_cast<const char *>(data), size);
103    msg.SetFullText(text);
104    msg.ConvertUserData();
105    msg.ConvertUserPartData();
106    msg.GetFullText();
107    msg.CreateDeliverSmsTpdu();
108    msg.CreateDeliverReportSmsTpdu();
109    msg.CreateStatusReportSmsTpdu();
110    msg.ConvertMessageDcs();
111    std::string addr(reinterpret_cast<const char *>(data), size);
112    msg.SetDestAddress(addr);
113}
114
115void SplitMessageAndCreateSubmitTest(const uint8_t *data, size_t size)
116{
117    if (!IsServiceInited()) {
118        return;
119    }
120    GsmSmsMessage msg;
121    std::vector<struct SplitInfo> cellsInfos;
122    std::string text(reinterpret_cast<const char *>(data), size);
123    bool force7BitCode = (size % SLOT_NUM == 1);
124    DataCodingScheme codingType = static_cast<DataCodingScheme>(size % CODE_SCHEME_SIZE);
125    msg.SplitMessage(cellsInfos, text, force7BitCode, codingType, false, "");
126    bool isStatusReport = (size % SLOT_NUM == 0);
127    std::string desAddr(reinterpret_cast<const char *>(data), size);
128    std::string scAddr(reinterpret_cast<const char *>(data), size);
129    msg.CreateDefaultSubmitSmsTpdu(desAddr, scAddr, text, isStatusReport, codingType);
130    msg.SplitMessage(cellsInfos, text, force7BitCode, codingType, true, "");
131    uint8_t msgRef8bit = size % UINT8_COUNT;
132    msg.CreateDataSubmitSmsTpdu(desAddr, scAddr, size, data, size, msgRef8bit, codingType, isStatusReport);
133    bool bMore = (size % SLOT_NUM == 1);
134    msg.ConvertUserData();
135    msg.ConvertUserPartData();
136    msg.GetSubmitEncodeInfo(text, bMore);
137    uint8_t decodeData[DATA_LEN + 1];
138    uint16_t len = DATA_LEN < size ? DATA_LEN : size;
139    if (memcpy_s(decodeData, len, data, len) != EOK) {
140        return;
141    }
142    msg.GetSubmitEncodeInfoPartData(decodeData, size, bMore);
143    msg.SetHeaderReply(size);
144    SmsConcat contact;
145    contact.is8Bits = (size % SLOT_NUM == 1);
146    contact.msgRef = size % UINT16_COUNT;
147    contact.seqNum = size % UINT16_COUNT;
148    contact.totalSeg = size % UINT16_COUNT;
149    msg.IsSpecialMessage();
150}
151
152void DoSomethingInterestingWithMyAPI(const uint8_t *data, size_t size)
153{
154    if (data == nullptr || size == 0) {
155        return;
156    }
157    CalcReplyEncodeAddress(data, size);
158    SplitMessageAndCreateSubmitTest(data, size);
159    CreateMessageTest(data, size);
160    sleep(SLEEP_TIME_SECONDS);
161    DelayedSingleton<SmsService>::DestroyInstance();
162}
163} // namespace OHOS
164
165/* Fuzzer entry point */
166extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size)
167{
168    /* Run your code on data */
169    OHOS::AddSmsTokenFuzzer token;
170    OHOS::DoSomethingInterestingWithMyAPI(data, size);
171    return 0;
172}
173