140f5d65dSopenharmony_ci/*
240f5d65dSopenharmony_ci * Copyright (c) 2023-2024 Huawei Device Co., Ltd.
340f5d65dSopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License");
440f5d65dSopenharmony_ci * you may not use this file except in compliance with the License.
540f5d65dSopenharmony_ci * You may obtain a copy of the License at
640f5d65dSopenharmony_ci *
740f5d65dSopenharmony_ci *     http://www.apache.org/licenses/LICENSE-2.0
840f5d65dSopenharmony_ci *
940f5d65dSopenharmony_ci * Unless required by applicable law or agreed to in writing, software
1040f5d65dSopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS,
1140f5d65dSopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1240f5d65dSopenharmony_ci * See the License for the specific language governing permissions and
1340f5d65dSopenharmony_ci * limitations under the License.
1440f5d65dSopenharmony_ci */
1540f5d65dSopenharmony_ci
1640f5d65dSopenharmony_ci#include "sandbox_helper.h"
1740f5d65dSopenharmony_ci
1840f5d65dSopenharmony_ci#include <iomanip>
1940f5d65dSopenharmony_ci#include <sstream>
2040f5d65dSopenharmony_ci#include <unordered_set>
2140f5d65dSopenharmony_ci#include <vector>
2240f5d65dSopenharmony_ci
2340f5d65dSopenharmony_ci#include "log.h"
2440f5d65dSopenharmony_ci#include "json_utils.h"
2540f5d65dSopenharmony_ci#include "uri.h"
2640f5d65dSopenharmony_ci
2740f5d65dSopenharmony_ciusing namespace std;
2840f5d65dSopenharmony_ci
2940f5d65dSopenharmony_cinamespace OHOS {
3040f5d65dSopenharmony_cinamespace AppFileService {
3140f5d65dSopenharmony_cinamespace {
3240f5d65dSopenharmony_ci    const string PACKAGE_NAME_FLAG = "<PackageName>";
3340f5d65dSopenharmony_ci    const string CURRENT_USER_ID_FLAG = "<currentUserId>";
3440f5d65dSopenharmony_ci    const string PHYSICAL_PATH_KEY = "src-path";
3540f5d65dSopenharmony_ci    const string SANDBOX_PATH_KEY = "sandbox-path";
3640f5d65dSopenharmony_ci    const string MOUNT_PATH_MAP_KEY = "mount-path-map";
3740f5d65dSopenharmony_ci    const string SANDBOX_JSON_FILE_PATH = "/etc/app_file_service/file_share_sandbox.json";
3840f5d65dSopenharmony_ci    const string BACKUP_SANDBOX_JSON_FILE_PATH = "/etc/app_file_service/backup_sandbox.json";
3940f5d65dSopenharmony_ci    const std::string SHAER_PATH_HEAD = "/mnt/hmdfs/";
4040f5d65dSopenharmony_ci    const std::string SHAER_PATH_MID = "/account/cloud_merge_view/files/";
4140f5d65dSopenharmony_ci    const string FILE_MANAGER_URI_HEAD = "/storage/";
4240f5d65dSopenharmony_ci    const string FILE_MANAGER_AUTHORITY = "docs";
4340f5d65dSopenharmony_ci    const string DLP_MANAGER_BUNDLE_NAME = "com.ohos.dlpmanager";
4440f5d65dSopenharmony_ci    const string FUSE_URI_HEAD = "/mnt/data/fuse";
4540f5d65dSopenharmony_ci    const string BACKFLASH = "/";
4640f5d65dSopenharmony_ci    const string MEDIA = "media";
4740f5d65dSopenharmony_ci    const string NETWORK_ID_FLAG = "<networkId>";
4840f5d65dSopenharmony_ci    const string LOCAL = "local";
4940f5d65dSopenharmony_ci    const int ASSET_IN_BUCKET_NUM_MAX = 1000;
5040f5d65dSopenharmony_ci    const int ASSET_DIR_START_NUM = 16;
5140f5d65dSopenharmony_ci    const int DECODE_FORMAT_NUM = 16;
5240f5d65dSopenharmony_ci}
5340f5d65dSopenharmony_ci
5440f5d65dSopenharmony_cistruct MediaUriInfo {
5540f5d65dSopenharmony_ci    string mediaType;
5640f5d65dSopenharmony_ci    string fileId;
5740f5d65dSopenharmony_ci    string realName;
5840f5d65dSopenharmony_ci    string displayName;
5940f5d65dSopenharmony_ci};
6040f5d65dSopenharmony_ci
6140f5d65dSopenharmony_cistd::unordered_map<std::string, std::string> SandboxHelper::sandboxPathMap_;
6240f5d65dSopenharmony_cistd::unordered_map<std::string, std::string> SandboxHelper::backupSandboxPathMap_;
6340f5d65dSopenharmony_cistd::mutex SandboxHelper::mapMutex_;
6440f5d65dSopenharmony_ci
6540f5d65dSopenharmony_cistring SandboxHelper::Encode(const string &uri)
6640f5d65dSopenharmony_ci{
6740f5d65dSopenharmony_ci    const unordered_set<char> uriCompentsSet = {
6840f5d65dSopenharmony_ci        '/', '-', '_', '.', '!',
6940f5d65dSopenharmony_ci        '~', '*', '(', ')', '\''
7040f5d65dSopenharmony_ci    };
7140f5d65dSopenharmony_ci    const int32_t encodeLen = 2;
7240f5d65dSopenharmony_ci    ostringstream outPutStream;
7340f5d65dSopenharmony_ci    outPutStream.fill('0');
7440f5d65dSopenharmony_ci    outPutStream << std::hex;
7540f5d65dSopenharmony_ci
7640f5d65dSopenharmony_ci    for (unsigned char tmpChar : uri) {
7740f5d65dSopenharmony_ci        if (std::isalnum(tmpChar) || uriCompentsSet.find(tmpChar) != uriCompentsSet.end()) {
7840f5d65dSopenharmony_ci            outPutStream << tmpChar;
7940f5d65dSopenharmony_ci        } else {
8040f5d65dSopenharmony_ci            outPutStream << std::uppercase;
8140f5d65dSopenharmony_ci            outPutStream << '%' << std::setw(encodeLen) << static_cast<unsigned int>(tmpChar);
8240f5d65dSopenharmony_ci            outPutStream << std::nouppercase;
8340f5d65dSopenharmony_ci        }
8440f5d65dSopenharmony_ci    }
8540f5d65dSopenharmony_ci
8640f5d65dSopenharmony_ci    return outPutStream.str();
8740f5d65dSopenharmony_ci}
8840f5d65dSopenharmony_ci
8940f5d65dSopenharmony_cistring SandboxHelper::Decode(const string &uri)
9040f5d65dSopenharmony_ci{
9140f5d65dSopenharmony_ci    std::string outPutStr;
9240f5d65dSopenharmony_ci    const int32_t encodeLen = 2;
9340f5d65dSopenharmony_ci    size_t index = 0;
9440f5d65dSopenharmony_ci    while (index < uri.length()) {
9540f5d65dSopenharmony_ci        if (uri[index] == '%') {
9640f5d65dSopenharmony_ci            std::string inputStr(uri.substr(index + 1, encodeLen));
9740f5d65dSopenharmony_ci            outPutStr += static_cast<char>(strtol(inputStr.c_str(), nullptr, DECODE_FORMAT_NUM));
9840f5d65dSopenharmony_ci            index += encodeLen + 1;
9940f5d65dSopenharmony_ci        } else {
10040f5d65dSopenharmony_ci            outPutStr += uri[index];
10140f5d65dSopenharmony_ci            index++;
10240f5d65dSopenharmony_ci        }
10340f5d65dSopenharmony_ci    }
10440f5d65dSopenharmony_ci
10540f5d65dSopenharmony_ci    return outPutStr;
10640f5d65dSopenharmony_ci}
10740f5d65dSopenharmony_ci
10840f5d65dSopenharmony_cistatic string GetLowerPath(string &lowerPathHead, const string &lowerPathTail,
10940f5d65dSopenharmony_ci                           const string &userId, const string &bundleName,
11040f5d65dSopenharmony_ci                           const string &networkId)
11140f5d65dSopenharmony_ci{
11240f5d65dSopenharmony_ci    if (lowerPathHead.find(CURRENT_USER_ID_FLAG) != string::npos) {
11340f5d65dSopenharmony_ci        lowerPathHead = lowerPathHead.replace(lowerPathHead.find(CURRENT_USER_ID_FLAG),
11440f5d65dSopenharmony_ci                                              CURRENT_USER_ID_FLAG.length(), userId);
11540f5d65dSopenharmony_ci    }
11640f5d65dSopenharmony_ci
11740f5d65dSopenharmony_ci    if (lowerPathHead.find(PACKAGE_NAME_FLAG) != string::npos) {
11840f5d65dSopenharmony_ci        lowerPathHead = lowerPathHead.replace(lowerPathHead.find(PACKAGE_NAME_FLAG),
11940f5d65dSopenharmony_ci                                              PACKAGE_NAME_FLAG.length(), bundleName);
12040f5d65dSopenharmony_ci    }
12140f5d65dSopenharmony_ci
12240f5d65dSopenharmony_ci    if (lowerPathHead.find(NETWORK_ID_FLAG) != string::npos) {
12340f5d65dSopenharmony_ci        lowerPathHead = lowerPathHead.replace(lowerPathHead.find(NETWORK_ID_FLAG),
12440f5d65dSopenharmony_ci                                              NETWORK_ID_FLAG.length(), networkId);
12540f5d65dSopenharmony_ci    }
12640f5d65dSopenharmony_ci
12740f5d65dSopenharmony_ci    return lowerPathHead + lowerPathTail;
12840f5d65dSopenharmony_ci}
12940f5d65dSopenharmony_ci
13040f5d65dSopenharmony_cibool SandboxHelper::GetSandboxPathMap()
13140f5d65dSopenharmony_ci{
13240f5d65dSopenharmony_ci    lock_guard<mutex> lock(mapMutex_);
13340f5d65dSopenharmony_ci    if (sandboxPathMap_.size() > 0) {
13440f5d65dSopenharmony_ci        return true;
13540f5d65dSopenharmony_ci    }
13640f5d65dSopenharmony_ci
13740f5d65dSopenharmony_ci    nlohmann::json jsonObj;
13840f5d65dSopenharmony_ci    int ret = JsonUtils::GetJsonObjFromPath(jsonObj, SANDBOX_JSON_FILE_PATH);
13940f5d65dSopenharmony_ci    if (ret != 0) {
14040f5d65dSopenharmony_ci        LOGE("Get json object failed with %{public}d", ret);
14140f5d65dSopenharmony_ci        return false;
14240f5d65dSopenharmony_ci    }
14340f5d65dSopenharmony_ci
14440f5d65dSopenharmony_ci    if (jsonObj.find(MOUNT_PATH_MAP_KEY) == jsonObj.end()) {
14540f5d65dSopenharmony_ci        LOGE("Json object find mount path map failed");
14640f5d65dSopenharmony_ci        return false;
14740f5d65dSopenharmony_ci    }
14840f5d65dSopenharmony_ci
14940f5d65dSopenharmony_ci    nlohmann::json mountPathMap = jsonObj[MOUNT_PATH_MAP_KEY];
15040f5d65dSopenharmony_ci    for (size_t i = 0; i < mountPathMap.size(); i++) {
15140f5d65dSopenharmony_ci        string srcPath = mountPathMap[i][PHYSICAL_PATH_KEY];
15240f5d65dSopenharmony_ci        string sandboxPath = mountPathMap[i][SANDBOX_PATH_KEY];
15340f5d65dSopenharmony_ci        sandboxPathMap_[sandboxPath] = srcPath;
15440f5d65dSopenharmony_ci    }
15540f5d65dSopenharmony_ci
15640f5d65dSopenharmony_ci    if (sandboxPathMap_.size() == 0) {
15740f5d65dSopenharmony_ci        return false;
15840f5d65dSopenharmony_ci    }
15940f5d65dSopenharmony_ci
16040f5d65dSopenharmony_ci    return true;
16140f5d65dSopenharmony_ci}
16240f5d65dSopenharmony_ci
16340f5d65dSopenharmony_cibool SandboxHelper::GetBackupSandboxPathMap()
16440f5d65dSopenharmony_ci{
16540f5d65dSopenharmony_ci    lock_guard<mutex> lock(mapMutex_);
16640f5d65dSopenharmony_ci    if (backupSandboxPathMap_.size() > 0) {
16740f5d65dSopenharmony_ci        return true;
16840f5d65dSopenharmony_ci    }
16940f5d65dSopenharmony_ci
17040f5d65dSopenharmony_ci    nlohmann::json jsonObj;
17140f5d65dSopenharmony_ci    int ret = JsonUtils::GetJsonObjFromPath(jsonObj, BACKUP_SANDBOX_JSON_FILE_PATH);
17240f5d65dSopenharmony_ci    if (ret != 0) {
17340f5d65dSopenharmony_ci        LOGE("Get json object failed with %{public}d", ret);
17440f5d65dSopenharmony_ci        return false;
17540f5d65dSopenharmony_ci    }
17640f5d65dSopenharmony_ci
17740f5d65dSopenharmony_ci    if (jsonObj.find(MOUNT_PATH_MAP_KEY) == jsonObj.end()) {
17840f5d65dSopenharmony_ci        LOGE("Json object find mount path map failed");
17940f5d65dSopenharmony_ci        return false;
18040f5d65dSopenharmony_ci    }
18140f5d65dSopenharmony_ci
18240f5d65dSopenharmony_ci    nlohmann::json mountPathMap = jsonObj[MOUNT_PATH_MAP_KEY];
18340f5d65dSopenharmony_ci    for (size_t i = 0; i < mountPathMap.size(); i++) {
18440f5d65dSopenharmony_ci        string srcPath = mountPathMap[i][PHYSICAL_PATH_KEY];
18540f5d65dSopenharmony_ci        string sandboxPath = mountPathMap[i][SANDBOX_PATH_KEY];
18640f5d65dSopenharmony_ci        backupSandboxPathMap_[sandboxPath] = srcPath;
18740f5d65dSopenharmony_ci    }
18840f5d65dSopenharmony_ci
18940f5d65dSopenharmony_ci    if (backupSandboxPathMap_.size() == 0) {
19040f5d65dSopenharmony_ci        return false;
19140f5d65dSopenharmony_ci    }
19240f5d65dSopenharmony_ci
19340f5d65dSopenharmony_ci    return true;
19440f5d65dSopenharmony_ci}
19540f5d65dSopenharmony_ci
19640f5d65dSopenharmony_cistatic int32_t GetPathSuffix(const std::string &path, string &pathSuffix)
19740f5d65dSopenharmony_ci{
19840f5d65dSopenharmony_ci    size_t pos = path.rfind('.');
19940f5d65dSopenharmony_ci    if (pos != string::npos) {
20040f5d65dSopenharmony_ci        pathSuffix = path.substr(pos);
20140f5d65dSopenharmony_ci        return 0;
20240f5d65dSopenharmony_ci    }
20340f5d65dSopenharmony_ci    return -EINVAL;
20440f5d65dSopenharmony_ci}
20540f5d65dSopenharmony_ci
20640f5d65dSopenharmony_cistatic int32_t CalAssetBucket(const int32_t &fileId)
20740f5d65dSopenharmony_ci{
20840f5d65dSopenharmony_ci    int32_t bucketNum = 0;
20940f5d65dSopenharmony_ci    if (fileId < 0) {
21040f5d65dSopenharmony_ci        LOGE("input fileId %{private}d is invalid", fileId);
21140f5d65dSopenharmony_ci        return -EINVAL;
21240f5d65dSopenharmony_ci    }
21340f5d65dSopenharmony_ci
21440f5d65dSopenharmony_ci    int32_t start = ASSET_DIR_START_NUM;
21540f5d65dSopenharmony_ci    int32_t divider = ASSET_DIR_START_NUM;
21640f5d65dSopenharmony_ci    while (fileId > start * ASSET_IN_BUCKET_NUM_MAX) {
21740f5d65dSopenharmony_ci        divider = start;
21840f5d65dSopenharmony_ci        start <<= 1;
21940f5d65dSopenharmony_ci    }
22040f5d65dSopenharmony_ci
22140f5d65dSopenharmony_ci    int32_t fileIdRemainder = fileId % divider;
22240f5d65dSopenharmony_ci    if (fileIdRemainder == 0) {
22340f5d65dSopenharmony_ci        bucketNum = start + fileIdRemainder;
22440f5d65dSopenharmony_ci    } else {
22540f5d65dSopenharmony_ci        bucketNum = (start - divider) + fileIdRemainder;
22640f5d65dSopenharmony_ci    }
22740f5d65dSopenharmony_ci    return bucketNum;
22840f5d65dSopenharmony_ci}
22940f5d65dSopenharmony_ci
23040f5d65dSopenharmony_cistatic int32_t GetFileIdFromFileName(const std::string &fileName)
23140f5d65dSopenharmony_ci{
23240f5d65dSopenharmony_ci    if (fileName.empty()) {
23340f5d65dSopenharmony_ci        return -EINVAL;
23440f5d65dSopenharmony_ci    }
23540f5d65dSopenharmony_ci
23640f5d65dSopenharmony_ci    string tmpName = fileName;
23740f5d65dSopenharmony_ci    std::replace(tmpName.begin(), tmpName.end(), '_', ' ');
23840f5d65dSopenharmony_ci    stringstream ss;
23940f5d65dSopenharmony_ci    ss << tmpName;
24040f5d65dSopenharmony_ci
24140f5d65dSopenharmony_ci    string mediaType;
24240f5d65dSopenharmony_ci    string dateTime;
24340f5d65dSopenharmony_ci    string idStr;
24440f5d65dSopenharmony_ci    string other;
24540f5d65dSopenharmony_ci    ss >> mediaType >> dateTime >> idStr >> other;
24640f5d65dSopenharmony_ci    if (idStr.empty()) {
24740f5d65dSopenharmony_ci        return -EINVAL;
24840f5d65dSopenharmony_ci    }
24940f5d65dSopenharmony_ci
25040f5d65dSopenharmony_ci    if (!std::all_of(idStr.begin(), idStr.end(), ::isdigit)) {
25140f5d65dSopenharmony_ci        return -EINVAL;
25240f5d65dSopenharmony_ci    }
25340f5d65dSopenharmony_ci
25440f5d65dSopenharmony_ci    return std::stoi(idStr);
25540f5d65dSopenharmony_ci}
25640f5d65dSopenharmony_ci
25740f5d65dSopenharmony_cistatic int32_t GetBucketNum(const std::string &fileName)
25840f5d65dSopenharmony_ci{
25940f5d65dSopenharmony_ci    int32_t fileId = GetFileIdFromFileName(fileName);
26040f5d65dSopenharmony_ci    if (fileId < 0) {
26140f5d65dSopenharmony_ci        LOGE("GetFileIdFromFileName failed with %{private}s", fileName.c_str());
26240f5d65dSopenharmony_ci        return fileId;
26340f5d65dSopenharmony_ci    }
26440f5d65dSopenharmony_ci    return CalAssetBucket(fileId);
26540f5d65dSopenharmony_ci}
26640f5d65dSopenharmony_ci
26740f5d65dSopenharmony_cistatic bool ParseMediaSandboxPath(const string &sandboxPath, MediaUriInfo &mediaUriInfo)
26840f5d65dSopenharmony_ci{
26940f5d65dSopenharmony_ci    string path = sandboxPath;
27040f5d65dSopenharmony_ci    std::replace(path.begin(), path.end(), '/', ' ');
27140f5d65dSopenharmony_ci    stringstream ss;
27240f5d65dSopenharmony_ci    ss << path;
27340f5d65dSopenharmony_ci    ss >> mediaUriInfo.mediaType >> mediaUriInfo.fileId >> mediaUriInfo.realName >> mediaUriInfo.displayName;
27440f5d65dSopenharmony_ci
27540f5d65dSopenharmony_ci    string buf;
27640f5d65dSopenharmony_ci    ss >> buf;
27740f5d65dSopenharmony_ci    if (!buf.empty()) {
27840f5d65dSopenharmony_ci        LOGE("media sandboxPath is invalid");
27940f5d65dSopenharmony_ci        return false;
28040f5d65dSopenharmony_ci    }
28140f5d65dSopenharmony_ci
28240f5d65dSopenharmony_ci    return true;
28340f5d65dSopenharmony_ci}
28440f5d65dSopenharmony_ci
28540f5d65dSopenharmony_cistatic int32_t GetMediaPhysicalPath(const std::string &sandboxPath, const std::string &userId,
28640f5d65dSopenharmony_ci                                    std::string &physicalPath)
28740f5d65dSopenharmony_ci{
28840f5d65dSopenharmony_ci    MediaUriInfo mediaUriInfo;
28940f5d65dSopenharmony_ci    if (!ParseMediaSandboxPath(sandboxPath, mediaUriInfo)) {
29040f5d65dSopenharmony_ci        return -EINVAL;
29140f5d65dSopenharmony_ci    }
29240f5d65dSopenharmony_ci
29340f5d65dSopenharmony_ci    int32_t bucketNum = GetBucketNum(mediaUriInfo.realName);
29440f5d65dSopenharmony_ci    if (bucketNum < 0) {
29540f5d65dSopenharmony_ci        return -EINVAL;
29640f5d65dSopenharmony_ci    }
29740f5d65dSopenharmony_ci
29840f5d65dSopenharmony_ci    std::string mediaSuffix;
29940f5d65dSopenharmony_ci    if (GetPathSuffix(sandboxPath, mediaSuffix) != 0) {
30040f5d65dSopenharmony_ci        LOGE("GetPathSuffix failed");
30140f5d65dSopenharmony_ci        return -EINVAL;
30240f5d65dSopenharmony_ci    }
30340f5d65dSopenharmony_ci
30440f5d65dSopenharmony_ci    physicalPath = SHAER_PATH_HEAD + userId + SHAER_PATH_MID + mediaUriInfo.mediaType +
30540f5d65dSopenharmony_ci                   BACKFLASH + to_string(bucketNum) + BACKFLASH + mediaUriInfo.realName + mediaSuffix;
30640f5d65dSopenharmony_ci    return 0;
30740f5d65dSopenharmony_ci}
30840f5d65dSopenharmony_ci
30940f5d65dSopenharmony_cistatic void GetNetworkIdFromUri(const std::string &fileUri, string &networkId)
31040f5d65dSopenharmony_ci{
31140f5d65dSopenharmony_ci    Uri uri(fileUri);
31240f5d65dSopenharmony_ci    std::string networkIdInfo = uri.GetQuery();
31340f5d65dSopenharmony_ci    if (networkIdInfo.empty()) {
31440f5d65dSopenharmony_ci        return;
31540f5d65dSopenharmony_ci    }
31640f5d65dSopenharmony_ci    size_t posIndex = networkIdInfo.find('=');
31740f5d65dSopenharmony_ci    if (posIndex == string::npos || posIndex == (networkIdInfo.size() - 1)) {
31840f5d65dSopenharmony_ci        return;
31940f5d65dSopenharmony_ci    }
32040f5d65dSopenharmony_ci    networkId = networkIdInfo.substr(posIndex + 1);
32140f5d65dSopenharmony_ci}
32240f5d65dSopenharmony_ci
32340f5d65dSopenharmony_cistatic void DoGetPhysicalPath(string &lowerPathTail, string &lowerPathHead, const string &sandboxPath,
32440f5d65dSopenharmony_ci    std::unordered_map<std::string, std::string> &sandboxPathMap)
32540f5d65dSopenharmony_ci{
32640f5d65dSopenharmony_ci    string::size_type curPrefixMatchLen = 0;
32740f5d65dSopenharmony_ci    for (auto it = sandboxPathMap.begin(); it != sandboxPathMap.end(); it++) {
32840f5d65dSopenharmony_ci        string sandboxPathPrefix = it->first;
32940f5d65dSopenharmony_ci        string::size_type prefixMatchLen = sandboxPathPrefix.length();
33040f5d65dSopenharmony_ci        if (sandboxPath.length() >= prefixMatchLen) {
33140f5d65dSopenharmony_ci            string sandboxPathTemp = sandboxPath.substr(0, prefixMatchLen);
33240f5d65dSopenharmony_ci            if (sandboxPathTemp == sandboxPathPrefix && curPrefixMatchLen <= prefixMatchLen) {
33340f5d65dSopenharmony_ci                curPrefixMatchLen = prefixMatchLen;
33440f5d65dSopenharmony_ci                lowerPathHead = it->second;
33540f5d65dSopenharmony_ci                lowerPathTail = sandboxPath.substr(prefixMatchLen);
33640f5d65dSopenharmony_ci            }
33740f5d65dSopenharmony_ci        }
33840f5d65dSopenharmony_ci    }
33940f5d65dSopenharmony_ci}
34040f5d65dSopenharmony_ci
34140f5d65dSopenharmony_ciint32_t SandboxHelper::GetPhysicalPath(const std::string &fileUri, const std::string &userId,
34240f5d65dSopenharmony_ci                                       std::string &physicalPath)
34340f5d65dSopenharmony_ci{
34440f5d65dSopenharmony_ci    Uri uri(fileUri);
34540f5d65dSopenharmony_ci    string bundleName = uri.GetAuthority();
34640f5d65dSopenharmony_ci    if (bundleName == MEDIA) {
34740f5d65dSopenharmony_ci        return GetMediaPhysicalPath(uri.GetPath(), userId, physicalPath);
34840f5d65dSopenharmony_ci    }
34940f5d65dSopenharmony_ci
35040f5d65dSopenharmony_ci    string sandboxPath = SandboxHelper::Decode(uri.GetPath());
35140f5d65dSopenharmony_ci    if ((sandboxPath.find(FILE_MANAGER_URI_HEAD) == 0 && bundleName != FILE_MANAGER_AUTHORITY) ||
35240f5d65dSopenharmony_ci        (sandboxPath.find(FUSE_URI_HEAD) == 0 && bundleName != DLP_MANAGER_BUNDLE_NAME)) {
35340f5d65dSopenharmony_ci        return -EINVAL;
35440f5d65dSopenharmony_ci    }
35540f5d65dSopenharmony_ci
35640f5d65dSopenharmony_ci    if (!GetSandboxPathMap()) {
35740f5d65dSopenharmony_ci        LOGE("GetSandboxPathMap failed");
35840f5d65dSopenharmony_ci        return -EINVAL;
35940f5d65dSopenharmony_ci    }
36040f5d65dSopenharmony_ci
36140f5d65dSopenharmony_ci    string lowerPathTail = "";
36240f5d65dSopenharmony_ci    string lowerPathHead = "";
36340f5d65dSopenharmony_ci    DoGetPhysicalPath(lowerPathTail, lowerPathHead, sandboxPath, sandboxPathMap_);
36440f5d65dSopenharmony_ci
36540f5d65dSopenharmony_ci    if (lowerPathHead == "") {
36640f5d65dSopenharmony_ci        LOGE("lowerPathHead is invalid");
36740f5d65dSopenharmony_ci        return -EINVAL;
36840f5d65dSopenharmony_ci    }
36940f5d65dSopenharmony_ci
37040f5d65dSopenharmony_ci    string networkId = LOCAL;
37140f5d65dSopenharmony_ci    GetNetworkIdFromUri(fileUri, networkId);
37240f5d65dSopenharmony_ci
37340f5d65dSopenharmony_ci    physicalPath = GetLowerPath(lowerPathHead, lowerPathTail, userId, bundleName, networkId);
37440f5d65dSopenharmony_ci    return 0;
37540f5d65dSopenharmony_ci}
37640f5d65dSopenharmony_ci
37740f5d65dSopenharmony_ciint32_t SandboxHelper::GetBackupPhysicalPath(const std::string &fileUri, const std::string &userId,
37840f5d65dSopenharmony_ci                                             std::string &physicalPath)
37940f5d65dSopenharmony_ci{
38040f5d65dSopenharmony_ci    Uri uri(fileUri);
38140f5d65dSopenharmony_ci    string bundleName = uri.GetAuthority();
38240f5d65dSopenharmony_ci    if (bundleName == MEDIA) {
38340f5d65dSopenharmony_ci        return GetMediaPhysicalPath(uri.GetPath(), userId, physicalPath);
38440f5d65dSopenharmony_ci    }
38540f5d65dSopenharmony_ci
38640f5d65dSopenharmony_ci    string sandboxPath = SandboxHelper::Decode(uri.GetPath());
38740f5d65dSopenharmony_ci    if ((sandboxPath.find(FILE_MANAGER_URI_HEAD) == 0 && bundleName != FILE_MANAGER_AUTHORITY) ||
38840f5d65dSopenharmony_ci        (sandboxPath.find(FUSE_URI_HEAD) == 0 && bundleName != DLP_MANAGER_BUNDLE_NAME)) {
38940f5d65dSopenharmony_ci        return -EINVAL;
39040f5d65dSopenharmony_ci    }
39140f5d65dSopenharmony_ci
39240f5d65dSopenharmony_ci    if (!GetBackupSandboxPathMap()) {
39340f5d65dSopenharmony_ci        LOGE("GetBackupSandboxPathMap failed");
39440f5d65dSopenharmony_ci        return -EINVAL;
39540f5d65dSopenharmony_ci    }
39640f5d65dSopenharmony_ci
39740f5d65dSopenharmony_ci    string lowerPathTail = "";
39840f5d65dSopenharmony_ci    string lowerPathHead = "";
39940f5d65dSopenharmony_ci    DoGetPhysicalPath(lowerPathTail, lowerPathHead, sandboxPath, backupSandboxPathMap_);
40040f5d65dSopenharmony_ci
40140f5d65dSopenharmony_ci    if (lowerPathHead == "") {
40240f5d65dSopenharmony_ci        LOGE("lowerPathHead is invalid");
40340f5d65dSopenharmony_ci        return -EINVAL;
40440f5d65dSopenharmony_ci    }
40540f5d65dSopenharmony_ci
40640f5d65dSopenharmony_ci    string networkId = LOCAL;
40740f5d65dSopenharmony_ci    GetNetworkIdFromUri(fileUri, networkId);
40840f5d65dSopenharmony_ci
40940f5d65dSopenharmony_ci    physicalPath = GetLowerPath(lowerPathHead, lowerPathTail, userId, bundleName, networkId);
41040f5d65dSopenharmony_ci    return 0;
41140f5d65dSopenharmony_ci}
41240f5d65dSopenharmony_ci
41340f5d65dSopenharmony_cibool SandboxHelper::IsValidPath(const std::string &path)
41440f5d65dSopenharmony_ci{
41540f5d65dSopenharmony_ci    if (path.find("/./") != std::string::npos ||
41640f5d65dSopenharmony_ci        path.find("/../") != std::string::npos) {
41740f5d65dSopenharmony_ci        return false;
41840f5d65dSopenharmony_ci    }
41940f5d65dSopenharmony_ci    return true;
42040f5d65dSopenharmony_ci}
42140f5d65dSopenharmony_ci
42240f5d65dSopenharmony_cibool SandboxHelper::CheckValidPath(const std::string &filePath)
42340f5d65dSopenharmony_ci{
42440f5d65dSopenharmony_ci    if (filePath.empty() || filePath.size() >= PATH_MAX) {
42540f5d65dSopenharmony_ci        LOGE("filePath is invalid, size = %{public}zu", filePath.size());
42640f5d65dSopenharmony_ci        return false;
42740f5d65dSopenharmony_ci    }
42840f5d65dSopenharmony_ci
42940f5d65dSopenharmony_ci    char realPath[PATH_MAX]{'\0'};
43040f5d65dSopenharmony_ci    if (realpath(filePath.c_str(), realPath) == nullptr) {
43140f5d65dSopenharmony_ci        LOGE("realpath failed with %{public}d", errno);
43240f5d65dSopenharmony_ci        return false;
43340f5d65dSopenharmony_ci    }
43440f5d65dSopenharmony_ci
43540f5d65dSopenharmony_ci    if (strncmp(realPath, filePath.c_str(), filePath.size()) != 0) {
43640f5d65dSopenharmony_ci        LOGE("filePath is not equal to realPath, realPath.size = %{public}zu, filePath.size() = %{public}zu",
43740f5d65dSopenharmony_ci            string_view(realPath).size(), filePath.size());
43840f5d65dSopenharmony_ci        return false;
43940f5d65dSopenharmony_ci    }
44040f5d65dSopenharmony_ci
44140f5d65dSopenharmony_ci    return true;
44240f5d65dSopenharmony_ci}
44340f5d65dSopenharmony_ci} // namespace AppFileService
44440f5d65dSopenharmony_ci} // namespace OHOS
44540f5d65dSopenharmony_ci
446