diff --git a/frameworks/native/backup_ext/src/ext_extension.cpp b/frameworks/native/backup_ext/src/ext_extension.cpp index 987333bb3086a03a12a291bfe6004b1c08dbf85c..3c4ec575cc98227b1be7e5ad2dad099551d4086b 100644 --- a/frameworks/native/backup_ext/src/ext_extension.cpp +++ b/frameworks/native/backup_ext/src/ext_extension.cpp @@ -70,6 +70,17 @@ void BackupExtExtension::VerifyCaller() } } +static string GenerateHashForFileName(const string &fName) +{ + ostringstream strHex; + strHex << hex; + + hash strHash; + size_t szHash = strHash(fName); + strHex << setfill('0') << setw(BConstants::BIG_FILE_NAME_SIZE) << szHash; + return strHex.str(); +} + UniqueFd BackupExtExtension::GetFileHandle(const string &fileName) { try { @@ -80,10 +91,6 @@ UniqueFd BackupExtExtension::GetFileHandle(const string &fileName) VerifyCaller(); - if (fileName.find('/') != string::npos) { - throw BError(BError::Codes::EXT_INVAL_ARG, "Filename is not valid"); - } - string path = string(BConstants::PATH_BUNDLE_BACKUP_HOME).append(BConstants::SA_BUNDLE_BACKUP_RESTORE); if (mkdir(path.data(), S_IRWXU) && errno != EEXIST) { string str = string("Failed to create restore folder. ").append(std::generic_category().message(errno)); @@ -91,6 +98,16 @@ UniqueFd BackupExtExtension::GetFileHandle(const string &fileName) } string tarName = path + fileName; + + // 带路径的文件名在这里转换为hash值 + if (fileName.find("4267f03b") != string::npos) { + HILOGI("GetFileHandle: fileName include path symbol, need to make hash."); + tarName = path + GenerateHashForFileName(fileName); + } else if (fileName.find("ce3b17d2") != string::npos) { + HILOGI("GetFileHandle: fileName include path symbol, need to make hash."); + tarName = path + GenerateHashForFileName(fileName); + } + if (access(tarName.c_str(), F_OK) == 0) { throw BError(BError::Codes::EXT_INVAL_ARG, string("The file already exists")); } @@ -199,6 +216,11 @@ ErrCode BackupExtExtension::PublishFile(const string &fileName) string path = string(BConstants::PATH_BUNDLE_BACKUP_HOME).append(BConstants::SA_BUNDLE_BACKUP_RESTORE); string tarName = path + fileName; + // 带路径的文件名在这里转换为hash值 + if (fileName.find("4267f03b") != string::npos) { + HILOGI("PublishFile: fileName include path symbol, need to make hash."); + tarName = path + GenerateHashForFileName(fileName); + } { BExcepUltils::VerifyPath(tarName, true); unique_lock lock(lock_); @@ -345,13 +367,28 @@ int BackupExtExtension::DoRestore(const string &fileName) if (extension_->GetExtensionAction() != BConstants::ExtensionAction::RESTORE) { return EPERM; } - // REM: 给定version - // REM: 解压启动Extension时即挂载好的备份目录中的数据 string path = string(BConstants::PATH_BUNDLE_BACKUP_HOME).append(BConstants::SA_BUNDLE_BACKUP_RESTORE); - string tarName = path + fileName; - UntarFile::GetInstance().UnPacket(tarName, "/"); + // 带路径的文件名在这里转换为hash值 + if (fileName.find("ce3b17d2") != string::npos) { + HILOGI("DoRestore: fileName include path symbol, need to make hash."); + String filePath = path + GenerateHashForFileName(fileName);; + size_t pos = filePath.rfind('/'); + if (pos == string::npos) { + return EPERM; + } + string folderPath = filePath.substr(0, pos); + if (!ForceCreateDirectory(folderPath.data())) { + HILOGE("Failed to create directory"); + return EPERM; + } + UntarFile::GetInstance().UnPacket(filePath, path); + } else { + // REM: 给定version + // REM: 解压启动Extension时即挂载好的备份目录中的数据 + string tarName = path + fileName; + UntarFile::GetInstance().UnPacket(tarName, "/"); + } HILOGI("Application recovered successfully, package path is %{public}s", tarName.c_str()); - return ERR_OK; } @@ -410,6 +447,14 @@ static void RestoreBigFiles() string filePath = item.fileName; struct stat sta = item.sta; + // 带路径的文件名在这里转换为hash值 + bool includePath = false; + if (item.hashName.find("4267f03b") != string::npos) { + HILOGI("RestoreBigFiles: fileName include path symbol, need to make hash."); + fileName = path + GenerateHashForFileName(item.hashName);; + includePath = true; + } + if (access(fileName.data(), F_OK) != 0) { HILOGI("file does not exist"); continue; @@ -418,6 +463,19 @@ static void RestoreBigFiles() HILOGE("file path is empty. %{public}s", filePath.c_str()); continue; } + + if (includePath) { + size_t pos = filePath.rfind('/'); + if (pos == string::npos) { + continue; + } + string folderPath = "/" + filePath.substr(0, pos); + if (!ForceCreateDirectory(folderPath.data())) { + HILOGE("Failed to create directory"); + continue; + } + } + if (!BFile::CopyFile(fileName, filePath)) { HILOGE("failed to copy the file. err = %{public}d", errno); continue; diff --git a/services/backup_sa/src/module_ipc/service.cpp b/services/backup_sa/src/module_ipc/service.cpp index 937146137211e0a1781b5604f962f71c147f19d0..93d5c85dcd5a68f5edade60424099b291d065863 100644 --- a/services/backup_sa/src/module_ipc/service.cpp +++ b/services/backup_sa/src/module_ipc/service.cpp @@ -353,9 +353,6 @@ ErrCode Service::PublishFile(const BFileInfo &fileInfo) sched_->Sched(fileInfo.owner); return BError(BError::Codes::OK); } - if (fileInfo.fileName.find('/') != string::npos) { - throw BError(BError::Codes::SA_INVAL_ARG, "Filename is not valid"); - } auto backUpConnection = session_->GetExtConnection(fileInfo.owner); @@ -513,9 +510,6 @@ ErrCode Service::GetFileHandle(const string &bundleName, const string &fileName) } return BError(BError::Codes::OK); } - if (fileName.find('/') != string::npos) { - throw BError(BError::Codes::SA_INVAL_ARG, "Filename is not valid"); - } auto action = session_->GetServiceSchedAction(bundleName); if (action == BConstants::ServiceSchedAction::RUNNING) { auto backUpConnection = session_->GetExtConnection(bundleName); diff --git a/utils/src/b_filesystem/b_file.cpp b/utils/src/b_filesystem/b_file.cpp index aa8c36370bb37ad061fcfa33c833b2645cc42382..afd84fd605fadd64e6714be1cac1008b7c0e809a 100644 --- a/utils/src/b_filesystem/b_file.cpp +++ b/utils/src/b_filesystem/b_file.cpp @@ -113,6 +113,7 @@ bool BFile::CopyFile(const string &from, const string &to) if (!dir) { throw BError(errno); } + HILOGI("!!!!!!!!!!!!realpath for %{public}s", dir.get()); if (!realpath(dirname(dir.get()), resolvedPath.get())) { HILOGI("failed to real path for %{public}s", to.c_str()); return false;