• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 <stdexcept>
17 
18 #include "signature_tools_log.h"
19 #include "zip_entry.h"
20 
21 namespace OHOS {
22 namespace SignatureTools {
Alignment(int alignNum)23 int ZipEntry::Alignment(int alignNum)
24 {
25     /* if cd extra len bigger than entry extra len, make cd and entry extra length equals */
26     if (alignNum == 0) {
27         return -1;
28     }
29     uint16_t padding = 0;
30     if (!CalZeroPaddingLengthForEntryExtra(padding)) {
31         return -1;
32     }
33     uint32_t remainder = (m_zipEntryData->GetZipEntryHeader()->GetLength() +
34         m_fileEntryInCentralDirectory->GetOffset()) % alignNum;
35     if (remainder == 0) {
36         return padding;
37     }
38     int add = alignNum - remainder;
39     uint16_t newExtraLength = m_zipEntryData->GetZipEntryHeader()->GetExtraLength() + add;
40     static constexpr int MAX_UNSIGNED_SHORT_VALUE = 0xFFFF;
41     if (newExtraLength > MAX_UNSIGNED_SHORT_VALUE) {
42         SIGNATURE_TOOLS_LOGE("can not align %s", m_zipEntryData->GetZipEntryHeader()->GetFileName().c_str());
43         return -1;
44     }
45     SetEntryHeaderNewExtraLength(newExtraLength);
46     SetCenterDirectoryNewExtraLength(newExtraLength);
47 
48     return add;
49 }
50 
CalZeroPaddingLengthForEntryExtra(uint16_t & padding)51 bool ZipEntry::CalZeroPaddingLengthForEntryExtra(uint16_t& padding)
52 {
53     uint16_t entryExtraLen = m_zipEntryData->GetZipEntryHeader()->GetExtraLength();
54     uint16_t cdExtraLen = m_fileEntryInCentralDirectory->GetExtraLength();
55     if (cdExtraLen > entryExtraLen) {
56         if (!SetEntryHeaderNewExtraLength(cdExtraLen)) {
57             return false;
58         }
59         padding =  cdExtraLen - entryExtraLen;
60     }
61     if (cdExtraLen < entryExtraLen) {
62         if (!SetCenterDirectoryNewExtraLength(entryExtraLen)) {
63             return false;
64         }
65         padding =  entryExtraLen - cdExtraLen;
66     }
67     return true;
68 }
69 
SetCenterDirectoryNewExtraLength(uint16_t newLength)70 bool ZipEntry::SetCenterDirectoryNewExtraLength(uint16_t newLength)
71 {
72     const std::string oldExtraData = m_fileEntryInCentralDirectory->GetExtraData();
73     std::string newCDExtra;
74     if (!GetAlignmentNewExtra(newLength, oldExtraData, newCDExtra)) {
75         return false;
76     }
77     m_fileEntryInCentralDirectory->SetExtraData(newCDExtra);
78     m_fileEntryInCentralDirectory->SetExtraLength(newLength);
79     m_fileEntryInCentralDirectory->SetLength(CentralDirectory::CD_LENGTH +
80         m_fileEntryInCentralDirectory->GetFileNameLength() +
81         m_fileEntryInCentralDirectory->GetExtraLength() +
82         m_fileEntryInCentralDirectory->GetCommentLength());
83     return true;
84 }
85 
SetEntryHeaderNewExtraLength(uint16_t newLength)86 bool ZipEntry::SetEntryHeaderNewExtraLength(uint16_t newLength)
87 {
88     ZipEntryHeader* zipEntryHeader = m_zipEntryData->GetZipEntryHeader();
89     const std::string oldExtraData = zipEntryHeader->GetExtraData();
90     std::string alignmentNewExtra;
91     if (!GetAlignmentNewExtra(newLength, oldExtraData, alignmentNewExtra)) {
92         return false;
93     }
94     zipEntryHeader->SetExtraData(alignmentNewExtra);
95     zipEntryHeader->SetExtraLength(newLength);
96     zipEntryHeader->SetLength(ZipEntryHeader::HEADER_LENGTH +
97         zipEntryHeader->GetExtraLength() + zipEntryHeader->GetFileNameLength());
98     m_zipEntryData->SetLength(zipEntryHeader->GetLength() +
99         m_zipEntryData->GetFileSize() +
100         (m_zipEntryData->GetDataDescriptor() == nullptr ? 0 : DataDescriptor::DES_LENGTH));
101     return true;
102 }
103 
GetAlignmentNewExtra(uint16_t newLength,const std::string & old,std::string & res)104 bool ZipEntry::GetAlignmentNewExtra(uint16_t newLength, const std::string& old, std::string& res)
105 {
106     if (old.empty()) {
107         res = std::string(newLength, 0);
108         return true;
109     }
110     if (newLength < old.size()) {
111         SIGNATURE_TOOLS_LOGE("can not align %s", m_zipEntryData->GetZipEntryHeader()->GetFileName().c_str());
112         return false;
113     }
114 
115     res = old;
116     res.resize(newLength);
117     return true;
118 }
119 
GetZipEntryData()120 ZipEntryData* ZipEntry::GetZipEntryData()
121 {
122     return m_zipEntryData;
123 }
124 
SetZipEntryData(ZipEntryData * zipEntryData)125 void ZipEntry::SetZipEntryData(ZipEntryData* zipEntryData)
126 {
127     m_zipEntryData = zipEntryData;
128 }
129 
GetCentralDirectory()130 CentralDirectory* ZipEntry::GetCentralDirectory()
131 {
132     return m_fileEntryInCentralDirectory;
133 }
134 
SetCentralDirectory(CentralDirectory * centralDirectory)135 void ZipEntry::SetCentralDirectory(CentralDirectory* centralDirectory)
136 {
137     m_fileEntryInCentralDirectory = centralDirectory;
138 }
139 } // namespace SignatureTools
140 } // namespace OHOS
141