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 <fstream>
17#include <iostream>
18
19#include "file_utils.h"
20#include "signature_tools_log.h"
21#include "zip_entry_data.h"
22
23namespace OHOS {
24namespace SignatureTools {
25ZipEntryHeader* ZipEntryData::GetZipEntryHeader()
26{
27    return m_zipEntryHeader;
28}
29
30ZipEntryData* ZipEntryData::GetZipEntry(std::ifstream& input, uint32_t entryOffset, uint32_t fileSize)
31{
32    uint32_t offset = entryOffset;
33    /* read entry header by file and offset. */
34    std::string retStr;
35    if (FileUtils::ReadInputByOffsetAndLength(input, entryOffset, ZipEntryHeader::HEADER_LENGTH, retStr) != 0) {
36        SIGNATURE_TOOLS_LOGE("read zip entry head failed in file");
37        return nullptr;
38    }
39    ZipEntryHeader* entryHeader = ZipEntryHeader::GetZipEntryHeader(retStr);
40    if (!entryHeader) {
41        return nullptr;
42    }
43    offset += ZipEntryHeader::HEADER_LENGTH;
44
45    /* read entry file name and extra by offset. */
46    if (!ReadEntryFileNameAndExtraByOffset(input, entryHeader, offset)) {
47        return nullptr;
48    }
49    /* skip file data , save file offset and size. */
50    ZipEntryData* entry = new ZipEntryData();
51    entry->SetFileOffset(offset);
52    entry->SetFileSize(fileSize);
53    input.seekg(fileSize, std::ios::cur);
54    int64_t entryLength = entryHeader->GetLength() + fileSize;
55
56    /* set desc null flag */
57    if ((entryHeader->GetFlag() & HAS_DATA_DESCRIPTOR_MASK) != NOT_HAS_DATA_DESCRIPTOR_FLAG) {
58        /* if entry has data descriptor, read entry data descriptor. */
59        std::string retStr;
60        if (FileUtils::ReadInputByLength(input, DataDescriptor::DES_LENGTH, retStr) != 0) {
61            SIGNATURE_TOOLS_LOGE("read entry data descriptor failed in file");
62            return nullptr;
63        }
64        DataDescriptor* dataDesc = DataDescriptor::GetDataDescriptor(retStr);
65        if (!dataDesc) {
66            return nullptr;
67        }
68        entryLength += DataDescriptor::DES_LENGTH;
69        entry->SetDataDescriptor(dataDesc);
70    }
71    entry->SetZipEntryHeader(entryHeader);
72    entry->SetLength(entryLength);
73    return entry;
74}
75
76bool ZipEntryData::ReadEntryFileNameAndExtraByOffset(std::ifstream& input, ZipEntryHeader* entryHeader,
77    uint32_t& offset)
78{
79    if (entryHeader->GetFileNameLength() > 0) {
80        std::string fileNameStr;
81        if (FileUtils::ReadInputByLength(input, entryHeader->GetFileNameLength(), fileNameStr) != 0) {
82            SIGNATURE_TOOLS_LOGE("read entry file name failed in file");
83            return false;
84        }
85        entryHeader->ReadFileName(fileNameStr);
86        offset += entryHeader->GetFileNameLength();
87    }
88    if (entryHeader->GetExtraLength() > 0) {
89        std::string extraStr;
90        if (FileUtils::ReadInputByLength(input, entryHeader->GetExtraLength(), extraStr) != 0) {
91            SIGNATURE_TOOLS_LOGE("read entry file extra failed in file");
92            return false;
93        }
94        entryHeader->ReadExtra(extraStr);
95        offset += entryHeader->GetExtraLength();
96    }
97    return true;
98}
99
100void ZipEntryData::SetZipEntryHeader(ZipEntryHeader* zipEntryHeader)
101{
102    m_zipEntryHeader = zipEntryHeader;
103}
104
105DataDescriptor* ZipEntryData::GetDataDescriptor()
106{
107    return m_dataDescriptor;
108}
109
110void ZipEntryData::SetDataDescriptor(DataDescriptor* dataDescriptor)
111{
112    m_dataDescriptor = dataDescriptor;
113}
114
115uint32_t ZipEntryData::GetFileOffset()
116{
117    return m_fileOffset;
118}
119
120void ZipEntryData::SetFileOffset(uint32_t fileOffset)
121{
122    m_fileOffset = fileOffset;
123}
124
125uint32_t ZipEntryData::GetFileSize()
126{
127    return m_fileSize;
128}
129
130void ZipEntryData::SetFileSize(uint32_t fileSize)
131{
132    m_fileSize = fileSize;
133}
134
135uint32_t ZipEntryData::GetLength()
136{
137    return m_length;
138}
139
140void ZipEntryData::SetLength(uint32_t length)
141{
142    m_length = length;
143}
144} // namespace SignatureTools
145} // namespace OHOS