1 /*
2  * Copyright (c) 2024-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 <cinttypes>
17 
18 #include "endof_central_directory.h"
19 #include "signature_tools_log.h"
20 
21 namespace OHOS {
22 namespace SignatureTools {
GetEOCDByBytes(const std::string& bytes)23 std::optional<EndOfCentralDirectory*> EndOfCentralDirectory::GetEOCDByBytes(const std::string& bytes)
24 {
25     return GetEOCDByBytes(bytes, 0);
26 }
27 
GetEOCDByBytes(const std::string& bytes, int offset)28 std::optional<EndOfCentralDirectory*> EndOfCentralDirectory::GetEOCDByBytes(const std::string& bytes, int offset)
29 {
30     EndOfCentralDirectory* eocd = new EndOfCentralDirectory();
31     int remainingDataLen = bytes.size() - offset;
32     if (remainingDataLen < EOCD_LENGTH) {
33         delete eocd;
34         SIGNATURE_TOOLS_LOGE("remainingDataLen is less than EOCD_LENGTH, remainingDataLen: %d, "
35                              "EOCD_LENGTH: %d", remainingDataLen, EOCD_LENGTH);
36         return std::nullopt;
37     }
38 
39     ByteBuffer bf(bytes.c_str(), bytes.size());
40 
41     int signValue;
42     bf.GetInt32(signValue);
43     if (signValue != SIGNATURE) {
44         delete eocd;
45         return std::nullopt;
46     }
47 
48     SetEndOfCentralDirectoryValues(bf, eocd);
49 
50     uint16_t commentLength = eocd->GetCommentLength();
51     if (bf.Remaining() != commentLength) {
52         delete eocd;
53         SIGNATURE_TOOLS_LOGE("bf.Remaining() is not equal to commentLength, bf.Remaining(): %d, "
54                              "commentLength: %" PRIu16, bf.Remaining(), commentLength);
55         return std::nullopt;
56     }
57     if (commentLength > 0) {
58         std::string readComment(commentLength, 0);
59         bf.GetData(&readComment[0], commentLength);
60         eocd->SetComment(readComment);
61     }
62     eocd->SetLength(EOCD_LENGTH + commentLength);
63     if (bf.Remaining() != 0) {
64         delete eocd;
65         SIGNATURE_TOOLS_LOGE("bf.Remaining() is not equal to 0, bf.Remaining(): %d", bf.Remaining());
66         return std::nullopt;
67     }
68     return std::make_optional(eocd);
69 }
70 
SetEndOfCentralDirectoryValues(ByteBuffer& bf, EndOfCentralDirectory* eocd)71 void EndOfCentralDirectory::SetEndOfCentralDirectoryValues(ByteBuffer& bf, EndOfCentralDirectory* eocd)
72 {
73     uint16_t eocdUInt16Value = 0;
74     bf.GetUInt16(eocdUInt16Value);
75     eocd->SetDiskNum(eocdUInt16Value);
76 
77     bf.GetUInt16(eocdUInt16Value);
78     eocd->SetcDStartDiskNum(eocdUInt16Value);
79 
80     bf.GetUInt16(eocdUInt16Value);
81     eocd->SetThisDiskCDNum(eocdUInt16Value);
82 
83     bf.GetUInt16(eocdUInt16Value);
84     eocd->SetcDTotal(eocdUInt16Value);
85 
86     uint32_t eocdUInt32Value;
87     bf.GetUInt32(eocdUInt32Value);
88     eocd->SetcDSize(eocdUInt32Value);
89 
90     bf.GetUInt32(eocdUInt32Value);
91     eocd->SetOffset(eocdUInt32Value);
92 
93     bf.GetUInt16(eocdUInt16Value);
94     eocd->SetCommentLength(eocdUInt16Value);
95 }
96 
ToBytes()97 std::string EndOfCentralDirectory::ToBytes()
98 {
99     ByteBuffer bf(m_length);
100 
101     bf.PutInt32(SIGNATURE);
102     bf.PutUInt16(m_diskNum);
103     bf.PutUInt16(m_cDStartDiskNum);
104     bf.PutUInt16(m_thisDiskCDNum);
105     bf.PutUInt16(m_cDTotal);
106     bf.PutUInt32(m_cDSize);
107     bf.PutUInt32(m_offset);
108     bf.PutUInt16(m_commentLength);
109 
110     if (m_commentLength > 0) {
111         bf.PutData(m_comment.data(), m_comment.size());
112     }
113 
114     return bf.ToString();
115 }
116 
GetEocdLength()117 int EndOfCentralDirectory::GetEocdLength()
118 {
119     return EOCD_LENGTH;
120 }
121 
GetSIGNATURE()122 int EndOfCentralDirectory::GetSIGNATURE()
123 {
124     return SIGNATURE;
125 }
126 
GetDiskNum()127 uint16_t EndOfCentralDirectory::GetDiskNum()
128 {
129     return m_diskNum;
130 }
131 
SetDiskNum(uint16_t diskNum)132 void EndOfCentralDirectory::SetDiskNum(uint16_t diskNum)
133 {
134     m_diskNum = diskNum;
135 }
136 
GetcDStartDiskNum()137 uint16_t EndOfCentralDirectory::GetcDStartDiskNum()
138 {
139     return m_cDStartDiskNum;
140 }
141 
SetcDStartDiskNum(uint16_t cDStartDiskNum)142 void EndOfCentralDirectory::SetcDStartDiskNum(uint16_t cDStartDiskNum)
143 {
144     m_cDStartDiskNum = cDStartDiskNum;
145 }
146 
GetThisDiskCDNum()147 uint16_t EndOfCentralDirectory::GetThisDiskCDNum()
148 {
149     return m_thisDiskCDNum;
150 }
151 
SetThisDiskCDNum(uint16_t thisDiskCDNum)152 void EndOfCentralDirectory::SetThisDiskCDNum(uint16_t thisDiskCDNum)
153 {
154     m_thisDiskCDNum = thisDiskCDNum;
155 }
156 
GetcDTotal()157 uint16_t EndOfCentralDirectory::GetcDTotal()
158 {
159     return m_cDTotal;
160 }
161 
SetcDTotal(uint16_t cDTotal)162 void EndOfCentralDirectory::SetcDTotal(uint16_t cDTotal)
163 {
164     m_cDTotal = cDTotal;
165 }
166 
GetcDSize()167 uint32_t EndOfCentralDirectory::GetcDSize()
168 {
169     return m_cDSize;
170 }
171 
SetcDSize(uint32_t cDSize)172 void EndOfCentralDirectory::SetcDSize(uint32_t cDSize)
173 {
174     m_cDSize = cDSize;
175 }
176 
GetOffset()177 uint32_t EndOfCentralDirectory::GetOffset()
178 {
179     return m_offset;
180 }
181 
SetOffset(uint32_t offset)182 void EndOfCentralDirectory::SetOffset(uint32_t offset)
183 {
184     m_offset = offset;
185 }
186 
GetCommentLength()187 uint16_t EndOfCentralDirectory::GetCommentLength()
188 {
189     return m_commentLength;
190 }
191 
SetCommentLength(uint16_t commentLength)192 void EndOfCentralDirectory::SetCommentLength(uint16_t commentLength)
193 {
194     m_commentLength = commentLength;
195 }
196 
GetComment()197 std::string EndOfCentralDirectory::GetComment()
198 {
199     return m_comment;
200 }
201 
SetComment(const std::string& comment)202 void EndOfCentralDirectory::SetComment(const std::string& comment)
203 {
204     m_comment = comment;
205 }
206 
GetLength()207 int EndOfCentralDirectory::GetLength()
208 {
209     return m_length;
210 }
211 
SetLength(uint32_t length)212 void EndOfCentralDirectory::SetLength(uint32_t length)
213 {
214     m_length = length;
215 }
216 } // namespace SignatureTools
217 } // namespace OHOS