!1490 fix: 文件夹安装解包内存申请失败问题修复

Merge pull request !1490 from liurantao/master
This commit is contained in:
openharmony_ci 2024-08-28 07:50:34 +00:00 committed by Gitee
commit cc8b7be89f
No known key found for this signature in database
GPG Key ID: 173E9B9CA92EEF8F
6 changed files with 118 additions and 61 deletions

View File

@ -20,8 +20,37 @@
#include <iostream>
namespace Hdc {
bool Decompress::DecompressToLocal(std::string decPath)
{
if (!CheckPath(decPath)) {
return false;
}
uint8_t buff[HEADER_LEN];
std::ifstream inFile(tarPath);
std::optional<Entry> entry = std::nullopt;
while (true) {
inFile.read(reinterpret_cast<char*>(buff), HEADER_LEN);
auto readcnt = inFile.gcount();
if (readcnt == 0) {
break;
}
if (inFile.fail() || readcnt != HEADER_LEN) {
WRITE_LOG(LOG_FATAL, "read file error");
break;
}
entry = Entry(buff, HEADER_LEN);
if (!entry.value().CopyPayload(decPath, inFile)) {
entry = std::nullopt;
break;
}
entry = std::nullopt;
continue;
}
inFile.close();
return true;
}
bool Decompress::CheckPath(std::string decPath)
{
uv_fs_t req;
int rc = uv_fs_lstat(nullptr, &req, tarPath.c_str(), nullptr);
@ -50,35 +79,6 @@ bool Decompress::DecompressToLocal(std::string decPath)
return false;
}
}
uint8_t buff[HEADER_LEN];
std::ifstream inFile(tarPath);
std::optional<Entry> entry = std::nullopt;
while (1) {
inFile.read(reinterpret_cast<char*>(buff), HEADER_LEN);
auto readcnt = inFile.gcount();
if (readcnt == 0) {
break;
}
if (inFile.fail() || readcnt != HEADER_LEN) {
WRITE_LOG(LOG_FATAL, "read file error");
break;
}
if (!entry.has_value()) {
entry = Entry(buff, HEADER_LEN);
if (entry.value().IsFinish()) {
entry.value().SaveToFile(decPath);
entry = std::nullopt;
}
continue;
}
entry.value().AddData(buff, HEADER_LEN);
if (entry.value().IsFinish()) {
entry.value().SaveToFile(decPath);
entry = std::nullopt;
}
}
inFile.close();
return true;
}
}
}

View File

@ -27,6 +27,7 @@ public:
~Decompress() {}
bool DecompressToLocal(std::string decPath);
bool CheckPath(std::string decPath);
private:
std::vector<Entry> entrys;

View File

@ -20,6 +20,7 @@
namespace Hdc {
constexpr size_t ENTRY_FILE_BUFSIZE = 4 * 1024; // 4KB
constexpr uint64_t ENTRY_MAX_FILE_SIZE = static_cast<uint64_t>(4) * 1024 * 1024 * 1024; // 4GB
std::optional<std::string> StripPrefix(const std::string& str, const std::string& prefix)
{
@ -103,35 +104,17 @@ bool Entry::UpdataName(std::string name)
return this->header.UpdataName(name);
}
bool Entry::SaveToFile(std::string prefixPath)
bool Entry::CopyPayload(std::string prefixPath, std::ifstream &inFile)
{
if (!IsFinish()) {
return false;
}
switch (this->header.FileType()) {
case TypeFlage::ORDINARYFILE: {
auto saveFile = prefixPath.append(GetName());
std::ofstream file(saveFile, std::ios::out | std::ios::binary);
if (!file.is_open()) {
WRITE_LOG(LOG_FATAL, "open %s fail", saveFile.c_str());
return false;
}
WRITE_LOG(LOG_INFO, "saveFile %s, size %ld", saveFile.c_str(), this->data.size());
const char *pData = reinterpret_cast<const char *>(this->data.data());
file.write(pData, this->data.size());
file.close();
if (file.fail()) {
if (!PayloadToFile(prefixPath, inFile)) {
return false;
}
break;
}
case TypeFlage::DIRECTORY: {
auto dirPath = prefixPath.append(GetName());
std::string estr;
bool b = Base::TryCreateDirectory(dirPath, estr);
if (!b) {
WRITE_LOG(LOG_FATAL, "mkdir failed dirPath:%s estr:%s", dirPath.c_str(), estr.c_str());
if (!PayloadToDir(prefixPath, inFile)) {
return false;
}
break;
@ -142,6 +125,71 @@ bool Entry::SaveToFile(std::string prefixPath)
return true;
}
bool Entry::PayloadToFile(std::string prefixPath, std::ifstream &inFile)
{
std::string saveFile = "";
saveFile = prefixPath + GetName();
std::ofstream outFile(saveFile, std::ios::app | std::ios::binary);
if (!outFile.is_open()) {
WRITE_LOG(LOG_FATAL, "PayloadToFile open %s fail", saveFile.c_str());
return false;
}
bool ret = true;
uint8_t *buffAppend = new uint8_t[ENTRY_FILE_BUFSIZE];
while (this->needSize >= ENTRY_FILE_BUFSIZE) {
ret = ReadAndWriteData(inFile, outFile, buffAppend, ENTRY_FILE_BUFSIZE, ENTRY_FILE_BUFSIZE);
if (!ret) {
break;
}
this->needSize -= ENTRY_FILE_BUFSIZE;
}
if (ret && this->needSize > 0) {
long int paddingSize = HEADER_LEN - (this->needSize % HEADER_LEN);
long int lastBufSize = (paddingSize == HEADER_LEN) ? this->needSize :
this->needSize + paddingSize;
ret = ReadAndWriteData(inFile, outFile, buffAppend, lastBufSize, this->needSize);
}
delete[] buffAppend;
buffAppend = nullptr;
outFile.close();
this->needSize = 0;
return ret;
}
bool Entry::ReadAndWriteData(std::ifstream &inFile, std::ofstream &outFile, uint8_t *buffAppend,
int readSize, int writeSize)
{
if (buffAppend == nullptr) {
WRITE_LOG(LOG_FATAL, "ReadAndWriteData buffAppend is null");
return false;
}
inFile.read(reinterpret_cast<char*>(buffAppend), readSize);
auto readcnt = inFile.gcount();
if (inFile.fail() || readcnt != readSize) {
WRITE_LOG(LOG_FATAL, "ReadAndWriteData read file error");
return false;
}
outFile.write(reinterpret_cast<const char*>(buffAppend), writeSize);
if (outFile.fail()) {
WRITE_LOG(LOG_FATAL, "ReadAndWriteData write file error");
return false;
}
return true;
}
bool Entry::PayloadToDir(std::string prefixPath, std::ifstream &inFile)
{
std::string saveFile = "";
auto dirPath = prefixPath.append(GetName());
std::string estr;
bool b = Base::TryCreateDirectory(dirPath, estr);
if (!b) {
WRITE_LOG(LOG_FATAL, "PayloadToDir mkdir failed dirPath:%s estr:%s", dirPath.c_str(), estr.c_str());
return false;
}
return true;
}
bool Entry::WriteToTar(std::ofstream &file)
{
switch (header.FileType()) {
@ -149,6 +197,9 @@ bool Entry::WriteToTar(std::ofstream &file)
char buff[HEADER_LEN] = {0};
header.GetBytes(reinterpret_cast<uint8_t *>(buff), HEADER_LEN);
file.write(buff, HEADER_LEN);
if (header.Size() == 0) {
break;
}
std::string name = Base::UnicodeToUtf8(GetName().c_str(), true);
std::ifstream inFile(name, std::ios::binary);
if (!inFile) {

View File

@ -37,12 +37,16 @@ public:
}
void AddData(uint8_t *data, size_t len);
size_t Size()
uint64_t Size()
{
return header.Size();
}
bool SaveToFile(std::string prefixPath);
bool CopyPayload(std::string prefixPath, std::ifstream &inFile);
bool PayloadToFile(std::string prefixPath, std::ifstream &inFile);
bool PayloadToDir(std::string prefixPath, std::ifstream &inFile);
bool ReadAndWriteData(std::ifstream &inFile, std::ofstream &outFile, uint8_t *buffAppend,
int readSize, int writeSize);
bool WriteToTar(std::ofstream &file);
std::string GetName();
@ -50,7 +54,7 @@ public:
private:
Header header;
size_t needSize;
uint64_t needSize;
std::string prefix;
std::vector<uint8_t> data;
};

View File

@ -83,15 +83,16 @@ bool Header::UpdataName(std::string fileName)
return true;
}
size_t Header::Size()
uint64_t Header::Size()
{
std::string octalStr(reinterpret_cast<char*>(this->size));
long num = 0;
std::string octalStr(reinterpret_cast<char*>(this->size), (HEADER_SIZE_LEN - 1));
uint64_t num = 0;
WRITE_LOG(LOG_DEBUG, "header size octalStr %s", octalStr.c_str());
if (!octalStr.empty()) {
const int octal = 8;
num = std::stol(octalStr, nullptr, octal);
num = stoull(octalStr, nullptr, octal);
}
WRITE_LOG(LOG_DEBUG, "header size num %ld", num);
WRITE_LOG(LOG_DEBUG, "header size num %llu", num);
return num;
}

View File

@ -102,7 +102,7 @@ struct Header {
explicit Header(uint8_t data[512], int dataLen);
std::string Name();
bool UpdataName(std::string fileName);
size_t Size();
uint64_t Size();
void UpdataSize(size_t fileLen);
TypeFlage FileType();
void UpdataFileType(TypeFlage fileType);