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 "content_reader.h"
17 
18 #include "base/raw_data_base_def.h"
19 #include "base/raw_data.h"
20 #include "encoded/encoded_param.h"
21 #include "hiview_logger.h"
22 #include "securec.h"
23 #include "sys_event.h"
24 
25 namespace OHOS {
26 namespace HiviewDFX {
27 DEFINE_LOG_TAG("HiView-ContentReader");
28 using namespace EventStore;
29 namespace {
30 constexpr uint32_t DATA_FORMAT_VERSION_OFFSET =
31     sizeof(uint64_t) + sizeof(uint32_t) + sizeof(uint8_t); // magicNumber + blockSize + pageSize
32 
UpdateParamCnt(std::shared_ptr<RawData> rawData,int32_t addParamCnt)33 bool UpdateParamCnt(std::shared_ptr<RawData> rawData, int32_t addParamCnt)
34 {
35     uint32_t pos = BLOCK_SIZE + sizeof(struct EventRaw::HiSysEventHeader);
36     auto header = *(reinterpret_cast<struct EventRaw::HiSysEventHeader*>(rawData->GetData() + BLOCK_SIZE));
37     if (header.isTraceOpened == 1) { // 1: include trace info, 0: exclude trace info
38         pos += sizeof(struct EventRaw::TraceInfo);
39     }
40     int32_t paramCnt = *(reinterpret_cast<int32_t*>(rawData->GetData() + pos)) + addParamCnt;
41     return rawData->Update(reinterpret_cast<uint8_t*>(&paramCnt), sizeof(int32_t), pos);
42 }
43 
UpdateRealSize(std::shared_ptr<RawData> rawData)44 bool UpdateRealSize(std::shared_ptr<RawData> rawData)
45 {
46     uint32_t realSize = rawData->GetDataLength();
47     return rawData->Update(reinterpret_cast<uint8_t*>(&realSize), BLOCK_SIZE, 0);
48 }
49 }
50 
ReadFmtVersion(std::ifstream & docStream)51 uint8_t ContentReader::ReadFmtVersion(std::ifstream& docStream)
52 {
53     if (!docStream.is_open()) {
54         return EventStore::EVENT_DATA_FORMATE_VERSION::INVALID;
55     }
56     auto curPos = docStream.tellg();
57     docStream.seekg(DATA_FORMAT_VERSION_OFFSET, std::ios::beg);
58     uint8_t dataFmtVersion = EventStore::EVENT_DATA_FORMATE_VERSION::INVALID;
59     docStream.read(reinterpret_cast<char*>(&dataFmtVersion), sizeof(uint8_t));
60     docStream.seekg(curPos, std::ios::beg);
61     return dataFmtVersion;
62 }
63 
ReadRawData(const EventInfo & eventInfo,uint8_t * content,uint32_t contentSize)64 std::shared_ptr<RawData> ContentReader::ReadRawData(const EventInfo& eventInfo, uint8_t* content, uint32_t contentSize)
65 {
66     constexpr uint32_t expandSize = 128; // for seq, tag, level
67     // the different size of event header between old and newer version.
68     uint32_t eventSize = contentSize - GetContentHeaderSize() + sizeof(EventStore::ContentHeader) -
69         SEQ_SIZE + MAX_DOMAIN_LEN + MAX_EVENT_NAME_LEN + expandSize;
70     if (eventSize > MAX_NEW_SIZE) {
71         HIVIEW_LOGE("invalid new event size=%{public}u", eventSize);
72         return nullptr;
73     }
74     auto rawData = std::make_shared<RawData>(eventSize);
75     if (!rawData->Append(reinterpret_cast<uint8_t*>(&eventSize), BLOCK_SIZE)) {
76         HIVIEW_LOGE("failed to copy event size to raw event");
77         return nullptr;
78     }
79     if (AppendDomainAndName(rawData, eventInfo) != DOC_STORE_SUCCESS) {
80         return nullptr;
81     }
82     if (AppendContentData(rawData, content, contentSize) != DOC_STORE_SUCCESS) {
83         return nullptr;
84     }
85     if (AppendExtraInfo(rawData, eventInfo)) {
86         return nullptr;
87     }
88     return rawData;
89 }
90 
AppendDomainAndName(std::shared_ptr<RawData> rawData,const EventInfo & eventInfo)91 int ContentReader::AppendDomainAndName(std::shared_ptr<RawData> rawData, const EventInfo& eventInfo)
92 {
93     if (!rawData->Append(reinterpret_cast<uint8_t*>(const_cast<char*>(eventInfo.domain)), MAX_DOMAIN_LEN)) {
94         HIVIEW_LOGE("failed to copy domain to raw event");
95         return DOC_STORE_ERROR_MEMORY;
96     }
97     if (!rawData->Append(reinterpret_cast<uint8_t*>(const_cast<char*>(eventInfo.name)), MAX_EVENT_NAME_LEN)) {
98         HIVIEW_LOGE("failed to copy name to raw event");
99         return DOC_STORE_ERROR_MEMORY;
100     }
101     return DOC_STORE_SUCCESS;
102 }
103 
AppendContentData(std::shared_ptr<RawData> rawData,uint8_t * content,uint32_t contentSize)104 int ContentReader::AppendContentData(std::shared_ptr<RawData> rawData, uint8_t* content, uint32_t contentSize)
105 {
106     EventStore::ContentHeader contentHeader;
107     if (GetContentHeader(content, contentHeader) != DOC_STORE_SUCCESS) {
108         HIVIEW_LOGE("failed to get header of content");
109         return DOC_STORE_ERROR_MEMORY;
110     }
111     if (!rawData->Append(reinterpret_cast<uint8_t*>(&contentHeader) + SEQ_SIZE,
112         sizeof(EventStore::ContentHeader) - SEQ_SIZE)) {
113         HIVIEW_LOGE("failed to copy content header to raw event");
114         return DOC_STORE_ERROR_MEMORY;
115     }
116     size_t contentPos = BLOCK_SIZE + GetContentHeaderSize();
117     if (!rawData->Append(content + contentPos, contentSize - contentPos - CRC_SIZE)) {
118         HIVIEW_LOGE("failed to copy content data to raw event");
119         return DOC_STORE_ERROR_MEMORY;
120     }
121     return DOC_STORE_SUCCESS;
122 }
123 
AppendExtraInfo(std::shared_ptr<RawData> rawData,const EventInfo & eventInfo)124 int ContentReader::AppendExtraInfo(std::shared_ptr<RawData> rawData, const EventInfo& eventInfo)
125 {
126     uint32_t addParamCnt = 2; // for seq, level
127     if (AppendTag(rawData, eventInfo.tag) == DOC_STORE_SUCCESS) {
128         addParamCnt++;
129     }
130     if (auto ret = AppendLevel(rawData, eventInfo.level); ret != DOC_STORE_SUCCESS) {
131         return ret;
132     }
133     if (auto ret = AppendSeq(rawData, eventInfo.seq); ret != DOC_STORE_SUCCESS) {
134         return ret;
135     }
136     if (!UpdateParamCnt(rawData, addParamCnt)) {
137         HIVIEW_LOGE("failed to update paramCnt to raw event");
138         return DOC_STORE_ERROR_MEMORY;
139     }
140     if (!UpdateRealSize(rawData)) {
141         HIVIEW_LOGE("failed to update realSize of raw event");
142         return DOC_STORE_ERROR_MEMORY;
143     }
144     return DOC_STORE_SUCCESS;
145 }
146 
AppendTag(std::shared_ptr<RawData> rawData,const std::string & tag)147 int ContentReader::AppendTag(std::shared_ptr<RawData> rawData, const std::string& tag)
148 {
149     if (tag.empty()) {
150         return DOC_STORE_ERROR_INVALID;
151     }
152     auto tagParam = std::make_shared<EventRaw::StringEncodedParam>(EventCol::TAG, tag);
153     auto& tagRawData = tagParam->GetRawData();
154     if (!rawData->Append(tagRawData.GetData(), tagRawData.GetDataLength())) {
155         HIVIEW_LOGE("failed to copy tag to raw event");
156         return DOC_STORE_ERROR_MEMORY;
157     }
158     return DOC_STORE_SUCCESS;
159 }
160 
AppendLevel(std::shared_ptr<RawData> rawData,const std::string & level)161 int ContentReader::AppendLevel(std::shared_ptr<RawData> rawData, const std::string& level)
162 {
163     auto levelParam = std::make_shared<EventRaw::StringEncodedParam>(EventCol::LEVEL, level);
164     auto& levelRawData = levelParam->GetRawData();
165     if (!rawData->Append(levelRawData.GetData(), levelRawData.GetDataLength())) {
166         HIVIEW_LOGE("failed to copy level to raw event");
167         return DOC_STORE_ERROR_MEMORY;
168     }
169     return DOC_STORE_SUCCESS;
170 }
171 
AppendSeq(std::shared_ptr<RawData> rawData,int64_t seq)172 int ContentReader::AppendSeq(std::shared_ptr<RawData> rawData, int64_t seq)
173 {
174     auto seqParam = std::make_shared<EventRaw::SignedVarintEncodedParam<int64_t>>(EventCol::SEQ, seq);
175     auto& seqRawData = seqParam->GetRawData();
176     if (!rawData->Append(seqRawData.GetData(), seqRawData.GetDataLength())) {
177         HIVIEW_LOGE("failed to copy seq to raw event");
178         return DOC_STORE_ERROR_MEMORY;
179     }
180     return DOC_STORE_SUCCESS;
181 }
182 
GetDataString(std::ifstream & docStream,std::string & value)183 bool ContentReader::GetDataString(std::ifstream& docStream, std::string& value)
184 {
185     uint32_t valueSize = 0;
186     docStream.read(reinterpret_cast<char*>(&valueSize), sizeof(uint32_t));
187     if (valueSize > (MAX_VERSION_LENG + 1) || valueSize == 0) { // end with '\0'
188         HIVIEW_LOGE("version size is invalid, size=%{public}" PRIu32 "", valueSize);
189         return false;
190     }
191 
192     char valueStr[valueSize];
193     docStream.read(valueStr, valueSize);
194     value = std::string(valueStr);
195     return true;
196 }
197 } // HiviewDFX
198 } // OHOS