169570cc8Sopenharmony_ci/*
269570cc8Sopenharmony_ci * Copyright (c) 2024 Huawei Device Co., Ltd.
369570cc8Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License");
469570cc8Sopenharmony_ci * you may not use this file except in compliance with the License.
569570cc8Sopenharmony_ci * You may obtain a copy of the License at
669570cc8Sopenharmony_ci *
769570cc8Sopenharmony_ci *     http://www.apache.org/licenses/LICENSE-2.0
869570cc8Sopenharmony_ci *
969570cc8Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software
1069570cc8Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS,
1169570cc8Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1269570cc8Sopenharmony_ci * See the License for the specific language governing permissions and
1369570cc8Sopenharmony_ci * limitations under the License.
1469570cc8Sopenharmony_ci */
1569570cc8Sopenharmony_ci
1669570cc8Sopenharmony_ci#include "appspawn_manager.h"
1769570cc8Sopenharmony_ci#include "appspawn_sandbox.h"
1869570cc8Sopenharmony_ci#include "appspawn_utils.h"
1969570cc8Sopenharmony_ci#include "modulemgr.h"
2069570cc8Sopenharmony_ci#include "parameter.h"
2169570cc8Sopenharmony_ci#include "securec.h"
2269570cc8Sopenharmony_ci
2369570cc8Sopenharmony_cistruct ListNode g_sandboxVarList = {&g_sandboxVarList, &g_sandboxVarList};
2469570cc8Sopenharmony_ci
2569570cc8Sopenharmony_cistatic int VarPackageNameIndexReplace(const SandboxContext *context,
2669570cc8Sopenharmony_ci    const char *buffer, uint32_t bufferLen, uint32_t *realLen, const VarExtraData *extraData)
2769570cc8Sopenharmony_ci{
2869570cc8Sopenharmony_ci    AppSpawnMsgBundleInfo *bundleInfo = (
2969570cc8Sopenharmony_ci        AppSpawnMsgBundleInfo *)GetSpawningMsgInfo(context, TLV_BUNDLE_INFO);
3069570cc8Sopenharmony_ci    APPSPAWN_CHECK(bundleInfo != NULL, return APPSPAWN_TLV_NONE,
3169570cc8Sopenharmony_ci        "No bundle info in msg %{public}s", context->bundleName);
3269570cc8Sopenharmony_ci    int len = 0;
3369570cc8Sopenharmony_ci    if (bundleInfo->bundleIndex > 0) {
3469570cc8Sopenharmony_ci        len = sprintf_s((char *)buffer, bufferLen, "%s_%d", bundleInfo->bundleName, bundleInfo->bundleIndex);
3569570cc8Sopenharmony_ci    } else {
3669570cc8Sopenharmony_ci        len = sprintf_s((char *)buffer, bufferLen, "%s", bundleInfo->bundleName);
3769570cc8Sopenharmony_ci    }
3869570cc8Sopenharmony_ci    APPSPAWN_CHECK(len > 0 && ((uint32_t)len < bufferLen),
3969570cc8Sopenharmony_ci        return -1, "Failed to format path app: %{public}s", context->bundleName);
4069570cc8Sopenharmony_ci    *realLen = (uint32_t)len;
4169570cc8Sopenharmony_ci    return 0;
4269570cc8Sopenharmony_ci}
4369570cc8Sopenharmony_ci
4469570cc8Sopenharmony_ciAPPSPAWN_STATIC int VarPackageNameReplace(const SandboxContext *context,
4569570cc8Sopenharmony_ci    const char *buffer, uint32_t bufferLen, uint32_t *realLen, const VarExtraData *extraData)
4669570cc8Sopenharmony_ci{
4769570cc8Sopenharmony_ci    int len = sprintf_s((char *)buffer, bufferLen, "%s", context->bundleName);
4869570cc8Sopenharmony_ci    APPSPAWN_CHECK(len > 0 && ((uint32_t)len < bufferLen),
4969570cc8Sopenharmony_ci        return -1, "Failed to format path app: %{public}s", context->bundleName);
5069570cc8Sopenharmony_ci    *realLen = (uint32_t)len;
5169570cc8Sopenharmony_ci    return 0;
5269570cc8Sopenharmony_ci}
5369570cc8Sopenharmony_ci
5469570cc8Sopenharmony_cistatic int VarCurrentUseIdReplace(const SandboxContext *context,
5569570cc8Sopenharmony_ci    const char *buffer, uint32_t bufferLen, uint32_t *realLen, const VarExtraData *extraData)
5669570cc8Sopenharmony_ci{
5769570cc8Sopenharmony_ci    AppSpawnMsgDacInfo *info = (AppSpawnMsgDacInfo *)GetSpawningMsgInfo(context, TLV_DAC_INFO);
5869570cc8Sopenharmony_ci    APPSPAWN_CHECK(info != NULL, return APPSPAWN_TLV_NONE,
5969570cc8Sopenharmony_ci        "No tlv %{public}d in msg %{public}s", TLV_DAC_INFO, context->bundleName);
6069570cc8Sopenharmony_ci    int len = 0;
6169570cc8Sopenharmony_ci    if (extraData == NULL || !CHECK_FLAGS_BY_INDEX(extraData->operation, SANDBOX_TAG_PERMISSION)) {
6269570cc8Sopenharmony_ci        len = sprintf_s((char *)buffer, bufferLen, "%u", info->uid / UID_BASE);
6369570cc8Sopenharmony_ci    } else {
6469570cc8Sopenharmony_ci        len = sprintf_s((char *)buffer, bufferLen, "%s", "currentUser");
6569570cc8Sopenharmony_ci    }
6669570cc8Sopenharmony_ci    APPSPAWN_CHECK(len > 0 && ((uint32_t)len < bufferLen),
6769570cc8Sopenharmony_ci        return -1, "Failed to format path app: %{public}s", context->bundleName);
6869570cc8Sopenharmony_ci    *realLen = (uint32_t)len;
6969570cc8Sopenharmony_ci    return 0;
7069570cc8Sopenharmony_ci}
7169570cc8Sopenharmony_ci
7269570cc8Sopenharmony_cistatic int VarArkWebPackageNameReplace(const SandboxContext *context,
7369570cc8Sopenharmony_ci    const char *buffer, uint32_t bufferLen, uint32_t *realLen,
7469570cc8Sopenharmony_ci    const VarExtraData *extraData)
7569570cc8Sopenharmony_ci{
7669570cc8Sopenharmony_ci    static char arkWebPackageName[PARAM_BUFFER_SIZE] = {0};
7769570cc8Sopenharmony_ci    if (strlen(arkWebPackageName) == 0) {
7869570cc8Sopenharmony_ci        int len = GetParameter(ARK_WEB_PERSIST_PACKAGE_NAME, "",
7969570cc8Sopenharmony_ci                               arkWebPackageName, sizeof(arkWebPackageName));
8069570cc8Sopenharmony_ci        APPSPAWN_CHECK(len > 0, return -1,
8169570cc8Sopenharmony_ci                "Failed to get param for var %{public}s",
8269570cc8Sopenharmony_ci                ARK_WEB_PERSIST_PACKAGE_NAME);
8369570cc8Sopenharmony_ci    }
8469570cc8Sopenharmony_ci    APPSPAWN_LOGV("ArkWebPackageNameReplace '%{public}s'", arkWebPackageName);
8569570cc8Sopenharmony_ci
8669570cc8Sopenharmony_ci    int len = sprintf_s((char*) buffer, bufferLen, "%s", arkWebPackageName);
8769570cc8Sopenharmony_ci    APPSPAWN_CHECK(len > 0 && ((uint32_t)len < bufferLen), return -1,
8869570cc8Sopenharmony_ci            "Failed to format path app: %{public}s", arkWebPackageName);
8969570cc8Sopenharmony_ci    *realLen = (uint32_t) len;
9069570cc8Sopenharmony_ci    return 0;
9169570cc8Sopenharmony_ci}
9269570cc8Sopenharmony_ci
9369570cc8Sopenharmony_cistatic int VariableNodeCompareName(ListNode *node, void *data)
9469570cc8Sopenharmony_ci{
9569570cc8Sopenharmony_ci    AppSandboxVarNode *varNode = (AppSandboxVarNode *)ListEntry(node, AppSandboxVarNode, node);
9669570cc8Sopenharmony_ci    return strcmp((char *)data, varNode->name);
9769570cc8Sopenharmony_ci}
9869570cc8Sopenharmony_ci
9969570cc8Sopenharmony_cistatic AppSandboxVarNode *GetAppSandboxVarNode(const char *name)
10069570cc8Sopenharmony_ci{
10169570cc8Sopenharmony_ci    ListNode *node = OH_ListFind(&g_sandboxVarList, (void *)name, VariableNodeCompareName);
10269570cc8Sopenharmony_ci    if (node == NULL) {
10369570cc8Sopenharmony_ci        return NULL;
10469570cc8Sopenharmony_ci    }
10569570cc8Sopenharmony_ci    return (AppSandboxVarNode *)ListEntry(node, AppSandboxVarNode, node);
10669570cc8Sopenharmony_ci}
10769570cc8Sopenharmony_ci
10869570cc8Sopenharmony_cistatic int ReplaceVariableByParameter(const char *varData, SandboxBuffer *sandboxBuffer)
10969570cc8Sopenharmony_ci{
11069570cc8Sopenharmony_ci    // "<param:persist.nweb.sandbox.src_path>"
11169570cc8Sopenharmony_ci    int len = GetParameter(varData + sizeof("<param:") - 1,
11269570cc8Sopenharmony_ci        DEFAULT_NWEB_SANDBOX_SEC_PATH, sandboxBuffer->buffer + sandboxBuffer->current,
11369570cc8Sopenharmony_ci        sandboxBuffer->bufferLen - sandboxBuffer->current - 1);
11469570cc8Sopenharmony_ci    APPSPAWN_CHECK(len > 0, return -1, "Failed to get param for var %{public}s", varData);
11569570cc8Sopenharmony_ci    sandboxBuffer->current += len;
11669570cc8Sopenharmony_ci    return 0;
11769570cc8Sopenharmony_ci}
11869570cc8Sopenharmony_ci
11969570cc8Sopenharmony_ciAPPSPAWN_STATIC int ReplaceVariableForDepSandboxPath(const SandboxContext *context,
12069570cc8Sopenharmony_ci    const char *buffer, uint32_t bufferLen, uint32_t *realLen, const VarExtraData *extraData)
12169570cc8Sopenharmony_ci{
12269570cc8Sopenharmony_ci    APPSPAWN_CHECK(extraData != NULL && extraData->data.depNode != NULL, return -1, "Invalid extra data ");
12369570cc8Sopenharmony_ci    uint32_t len = strlen(extraData->data.depNode->target);
12469570cc8Sopenharmony_ci    int ret = memcpy_s((char *)buffer, bufferLen, extraData->data.depNode->target, len);
12569570cc8Sopenharmony_ci    APPSPAWN_CHECK(ret == 0, return -1, "Failed to copy real data");
12669570cc8Sopenharmony_ci    *realLen = len;
12769570cc8Sopenharmony_ci    return 0;
12869570cc8Sopenharmony_ci}
12969570cc8Sopenharmony_ci
13069570cc8Sopenharmony_ciAPPSPAWN_STATIC int ReplaceVariableForDepSrcPath(const SandboxContext *context,
13169570cc8Sopenharmony_ci    const char *buffer, uint32_t bufferLen, uint32_t *realLen, const VarExtraData *extraData)
13269570cc8Sopenharmony_ci{
13369570cc8Sopenharmony_ci    APPSPAWN_CHECK(extraData != NULL && extraData->data.depNode != NULL, return -1, "Invalid extra data ");
13469570cc8Sopenharmony_ci    uint32_t len = strlen(extraData->data.depNode->source);
13569570cc8Sopenharmony_ci    int ret = memcpy_s((char *)buffer, bufferLen, extraData->data.depNode->source, len);
13669570cc8Sopenharmony_ci    APPSPAWN_CHECK(ret == 0, return -1, "Failed to copy real data");
13769570cc8Sopenharmony_ci    *realLen = len;
13869570cc8Sopenharmony_ci    return 0;
13969570cc8Sopenharmony_ci}
14069570cc8Sopenharmony_ci
14169570cc8Sopenharmony_ciAPPSPAWN_STATIC int ReplaceVariableForDepPath(const SandboxContext *context,
14269570cc8Sopenharmony_ci    const char *buffer, uint32_t bufferLen, uint32_t *realLen, const VarExtraData *extraData)
14369570cc8Sopenharmony_ci{
14469570cc8Sopenharmony_ci    APPSPAWN_CHECK(extraData != NULL && extraData->data.depNode != NULL, return -1, "Invalid extra data ");
14569570cc8Sopenharmony_ci    char *path = extraData->data.depNode->source;
14669570cc8Sopenharmony_ci    if (CHECK_FLAGS_BY_INDEX(extraData->operation, MOUNT_PATH_OP_REPLACE_BY_SANDBOX)) {
14769570cc8Sopenharmony_ci        path = extraData->data.depNode->target;
14869570cc8Sopenharmony_ci    } else if (CHECK_FLAGS_BY_INDEX(extraData->operation, MOUNT_PATH_OP_REPLACE_BY_SRC) && IsPathEmpty(path)) {
14969570cc8Sopenharmony_ci        path = extraData->data.depNode->target;
15069570cc8Sopenharmony_ci    }
15169570cc8Sopenharmony_ci    APPSPAWN_CHECK(path != NULL, return -1, "Invalid path %{public}x ", extraData->operation);
15269570cc8Sopenharmony_ci    uint32_t len = strlen(path);
15369570cc8Sopenharmony_ci    int ret = memcpy_s((char *)buffer, bufferLen, path, len);
15469570cc8Sopenharmony_ci    APPSPAWN_CHECK(ret == 0, return -1, "Failed to copy real data");
15569570cc8Sopenharmony_ci    *realLen = len;
15669570cc8Sopenharmony_ci    return 0;
15769570cc8Sopenharmony_ci}
15869570cc8Sopenharmony_ci
15969570cc8Sopenharmony_cistatic int ReplaceVariableForpackageName(const SandboxContext *context,
16069570cc8Sopenharmony_ci    const char *buffer, uint32_t bufferLen, uint32_t *realLen, const VarExtraData *extraData)
16169570cc8Sopenharmony_ci{
16269570cc8Sopenharmony_ci    APPSPAWN_CHECK(context != NULL, return -1, "Invalid context");
16369570cc8Sopenharmony_ci    AppSpawnMsgBundleInfo *bundleInfo = (AppSpawnMsgBundleInfo *)GetSpawningMsgInfo(context, TLV_BUNDLE_INFO);
16469570cc8Sopenharmony_ci    APPSPAWN_CHECK(bundleInfo != NULL, return APPSPAWN_TLV_NONE,
16569570cc8Sopenharmony_ci        "No bundle info in msg %{public}s", context->bundleName);
16669570cc8Sopenharmony_ci
16769570cc8Sopenharmony_ci    uint32_t flags = 0;
16869570cc8Sopenharmony_ci    char *extension = NULL;
16969570cc8Sopenharmony_ci    if (CheckAppSpawnMsgFlag(context->message, TLV_MSG_FLAGS, APP_FLAGS_ATOMIC_SERVICE)) {
17069570cc8Sopenharmony_ci        flags |= SANDBOX_PACKAGENAME_ATOMIC_SERVICE;
17169570cc8Sopenharmony_ci    } else {
17269570cc8Sopenharmony_ci        flags |= (CheckAppSpawnMsgFlag(context->message, TLV_MSG_FLAGS, APP_FLAGS_CLONE_ENABLE) &&
17369570cc8Sopenharmony_ci            bundleInfo->bundleIndex > 0) ? SANDBOX_PACKAGENAME_CLONE : 0;
17469570cc8Sopenharmony_ci        flags |= CheckAppSpawnMsgFlag(context->message, TLV_MSG_FLAGS, APP_FLAGS_EXTENSION_SANDBOX)
17569570cc8Sopenharmony_ci            ? SANDBOX_PACKAGENAME_EXTENSION : 0;
17669570cc8Sopenharmony_ci        extension = (char *)GetAppSpawnMsgExtInfo(context->message, MSG_EXT_NAME_APP_EXTENSION, NULL);
17769570cc8Sopenharmony_ci    }
17869570cc8Sopenharmony_ci
17969570cc8Sopenharmony_ci    int32_t len = 0;
18069570cc8Sopenharmony_ci    switch (flags) {
18169570cc8Sopenharmony_ci        case SANDBOX_PACKAGENAME_DEFAULT:               // 0 packageName
18269570cc8Sopenharmony_ci            len = sprintf_s((char *)buffer, bufferLen, "%s", bundleInfo->bundleName);
18369570cc8Sopenharmony_ci            break;
18469570cc8Sopenharmony_ci        case SANDBOX_PACKAGENAME_CLONE:                 // 1 +clone-bundleIndex+packageName
18569570cc8Sopenharmony_ci            len = sprintf_s((char *)buffer, bufferLen, "+clone-%u+%s", bundleInfo->bundleIndex, bundleInfo->bundleName);
18669570cc8Sopenharmony_ci            break;
18769570cc8Sopenharmony_ci        case SANDBOX_PACKAGENAME_EXTENSION: {           // 2 +extension-<extensionType>+packageName
18869570cc8Sopenharmony_ci            APPSPAWN_CHECK(extension != NULL, return -1, "Invalid extension data");
18969570cc8Sopenharmony_ci            len = sprintf_s((char *)buffer, bufferLen, "+extension-%s+%s", extension, bundleInfo->bundleName);
19069570cc8Sopenharmony_ci            break;
19169570cc8Sopenharmony_ci        }
19269570cc8Sopenharmony_ci        case SANDBOX_PACKAGENAME_CLONE_AND_EXTENSION: { // 3 +clone-bundleIndex+extension-<extensionType>+packageName
19369570cc8Sopenharmony_ci            APPSPAWN_CHECK(extension != NULL, return -1, "Invalid extension data");
19469570cc8Sopenharmony_ci            len = sprintf_s((char *)buffer, bufferLen, "+clone-%u+extension-%s+%s",
19569570cc8Sopenharmony_ci                bundleInfo->bundleIndex, extension, bundleInfo->bundleName);
19669570cc8Sopenharmony_ci            break;
19769570cc8Sopenharmony_ci        }
19869570cc8Sopenharmony_ci        case SANDBOX_PACKAGENAME_ATOMIC_SERVICE: {      // 4 +auid-<accountId>+packageName
19969570cc8Sopenharmony_ci            char *accountId = (char *)GetAppSpawnMsgExtInfo(context->message, MSG_EXT_NAME_ACCOUNT_ID, NULL);
20069570cc8Sopenharmony_ci            APPSPAWN_CHECK(accountId != NULL, return -1, "Invalid accountId data");
20169570cc8Sopenharmony_ci            len = sprintf_s((char *)buffer, bufferLen, "+auid-%s+%s", accountId, bundleInfo->bundleName);
20269570cc8Sopenharmony_ci            break;
20369570cc8Sopenharmony_ci        }
20469570cc8Sopenharmony_ci        default:
20569570cc8Sopenharmony_ci            break;
20669570cc8Sopenharmony_ci    }
20769570cc8Sopenharmony_ci    APPSPAWN_CHECK(len > 0 && ((uint32_t)len < bufferLen),
20869570cc8Sopenharmony_ci        return -1, "Failed to format path app: %{public}s flags %{public}u", context->bundleName, flags);
20969570cc8Sopenharmony_ci    *realLen = (uint32_t)len;
21069570cc8Sopenharmony_ci    return 0;
21169570cc8Sopenharmony_ci}
21269570cc8Sopenharmony_ci
21369570cc8Sopenharmony_cistatic int GetVariableName(char *varData, uint32_t len, const char *varStart, uint32_t *varLen)
21469570cc8Sopenharmony_ci{
21569570cc8Sopenharmony_ci    uint32_t i = 0;
21669570cc8Sopenharmony_ci    uint32_t sourceLen = strlen(varStart);
21769570cc8Sopenharmony_ci    for (; i < sourceLen; i++) {
21869570cc8Sopenharmony_ci        if (i > len) {
21969570cc8Sopenharmony_ci            return -1;
22069570cc8Sopenharmony_ci        }
22169570cc8Sopenharmony_ci        varData[i] = *(varStart + i);
22269570cc8Sopenharmony_ci        if (varData[i] == '>') {
22369570cc8Sopenharmony_ci            break;
22469570cc8Sopenharmony_ci        }
22569570cc8Sopenharmony_ci    }
22669570cc8Sopenharmony_ci    varData[i + 1] = '\0';
22769570cc8Sopenharmony_ci    *varLen = i + 1;
22869570cc8Sopenharmony_ci    return 0;
22969570cc8Sopenharmony_ci}
23069570cc8Sopenharmony_ci
23169570cc8Sopenharmony_cistatic int ReplaceVariable(const SandboxContext *context,
23269570cc8Sopenharmony_ci    const char *varStart, SandboxBuffer *sandboxBuffer, uint32_t *varLen, const VarExtraData *extraData)
23369570cc8Sopenharmony_ci{
23469570cc8Sopenharmony_ci    char varName[128] = {0};  // 128 max len for var
23569570cc8Sopenharmony_ci    int ret = GetVariableName(varName, sizeof(varName), varStart, varLen);
23669570cc8Sopenharmony_ci    APPSPAWN_CHECK(ret == 0, return -1, "Failed to get variable name");
23769570cc8Sopenharmony_ci
23869570cc8Sopenharmony_ci    uint32_t valueLen = 0;
23969570cc8Sopenharmony_ci    AppSandboxVarNode *node = GetAppSandboxVarNode(varName);
24069570cc8Sopenharmony_ci    if (node != NULL) {
24169570cc8Sopenharmony_ci        ret = node->replaceVar(context, sandboxBuffer->buffer + sandboxBuffer->current,
24269570cc8Sopenharmony_ci            sandboxBuffer->bufferLen - sandboxBuffer->current - 1, &valueLen, extraData);
24369570cc8Sopenharmony_ci        APPSPAWN_CHECK(ret == 0 && valueLen < (sandboxBuffer->bufferLen - sandboxBuffer->current),
24469570cc8Sopenharmony_ci            return -1, "Failed to fill real data");
24569570cc8Sopenharmony_ci        sandboxBuffer->current += valueLen;
24669570cc8Sopenharmony_ci        return 0;
24769570cc8Sopenharmony_ci    }
24869570cc8Sopenharmony_ci    // "<param:persist.nweb.sandbox.src_path>"
24969570cc8Sopenharmony_ci    if (strncmp(varName, "<param:", sizeof("<param:") - 1) == 0) {  // retry param:
25069570cc8Sopenharmony_ci        varName[*varLen - 1] = '\0';                                // erase last >
25169570cc8Sopenharmony_ci        return ReplaceVariableByParameter(varName, sandboxBuffer);
25269570cc8Sopenharmony_ci    }
25369570cc8Sopenharmony_ci    if (strncmp(varName, "<lib>", sizeof("<lib>") - 1) == 0) {  // retry lib
25469570cc8Sopenharmony_ci        ret = memcpy_s(sandboxBuffer->buffer + sandboxBuffer->current,
25569570cc8Sopenharmony_ci            sandboxBuffer->bufferLen - sandboxBuffer->current, APPSPAWN_LIB_NAME, strlen(APPSPAWN_LIB_NAME));
25669570cc8Sopenharmony_ci        APPSPAWN_CHECK(ret == 0, return -1, "Failed to copy real data");
25769570cc8Sopenharmony_ci        sandboxBuffer->current += strlen(APPSPAWN_LIB_NAME);
25869570cc8Sopenharmony_ci        return 0;
25969570cc8Sopenharmony_ci    }
26069570cc8Sopenharmony_ci    // no match revered origin data
26169570cc8Sopenharmony_ci    APPSPAWN_LOGE("ReplaceVariable var '%{public}s' no match variable", varName);
26269570cc8Sopenharmony_ci    ret = memcpy_s(sandboxBuffer->buffer + sandboxBuffer->current,
26369570cc8Sopenharmony_ci        sandboxBuffer->bufferLen - sandboxBuffer->current, varName, *varLen);
26469570cc8Sopenharmony_ci    APPSPAWN_CHECK(ret == 0, return -1, "Failed to copy real data");
26569570cc8Sopenharmony_ci    sandboxBuffer->current += *varLen;
26669570cc8Sopenharmony_ci    return 0;
26769570cc8Sopenharmony_ci}
26869570cc8Sopenharmony_ci
26969570cc8Sopenharmony_cistatic int HandleVariableReplace(const SandboxContext *context,
27069570cc8Sopenharmony_ci    SandboxBuffer *sandboxBuffer, const char *source, const VarExtraData *extraData)
27169570cc8Sopenharmony_ci{
27269570cc8Sopenharmony_ci    size_t sourceLen = strlen(source);
27369570cc8Sopenharmony_ci    for (size_t i = 0; i < sourceLen; i++) {
27469570cc8Sopenharmony_ci        if ((sandboxBuffer->current + 1) >= sandboxBuffer->bufferLen) {
27569570cc8Sopenharmony_ci            return -1;
27669570cc8Sopenharmony_ci        }
27769570cc8Sopenharmony_ci        if (*(source + i) != '<') {  // copy source
27869570cc8Sopenharmony_ci            *(sandboxBuffer->buffer + sandboxBuffer->current) = *(source + i);
27969570cc8Sopenharmony_ci            sandboxBuffer->current++;
28069570cc8Sopenharmony_ci            continue;
28169570cc8Sopenharmony_ci        }
28269570cc8Sopenharmony_ci        uint32_t varLen = 0;
28369570cc8Sopenharmony_ci        int ret = ReplaceVariable(context, source + i, sandboxBuffer, &varLen, extraData);
28469570cc8Sopenharmony_ci        APPSPAWN_CHECK(ret == 0, return ret, "Failed to fill real data");
28569570cc8Sopenharmony_ci        i += (varLen - 1);
28669570cc8Sopenharmony_ci    }
28769570cc8Sopenharmony_ci    return 0;
28869570cc8Sopenharmony_ci}
28969570cc8Sopenharmony_ci
29069570cc8Sopenharmony_ciconst char *GetSandboxRealVar(const SandboxContext *context,
29169570cc8Sopenharmony_ci    uint32_t bufferType, const char *source, const char *prefix, const VarExtraData *extraData)
29269570cc8Sopenharmony_ci{
29369570cc8Sopenharmony_ci    APPSPAWN_CHECK_ONLY_EXPER(context != NULL, return NULL);
29469570cc8Sopenharmony_ci    APPSPAWN_CHECK(bufferType < ARRAY_LENGTH(context->buffer), return NULL, "Invalid index for buffer");
29569570cc8Sopenharmony_ci    SandboxBuffer *sandboxBuffer = &((SandboxContext *)context)->buffer[bufferType];
29669570cc8Sopenharmony_ci    APPSPAWN_CHECK_ONLY_EXPER(sandboxBuffer != NULL && sandboxBuffer->buffer != NULL, return NULL);
29769570cc8Sopenharmony_ci    const char *tmp = source;
29869570cc8Sopenharmony_ci    int ret = 0;
29969570cc8Sopenharmony_ci    if (!IsPathEmpty(prefix)) {  // copy prefix data
30069570cc8Sopenharmony_ci        ret = HandleVariableReplace(context, sandboxBuffer, prefix, extraData);
30169570cc8Sopenharmony_ci        APPSPAWN_CHECK(ret == 0, return NULL, "Failed to replace source %{public}s ", prefix);
30269570cc8Sopenharmony_ci
30369570cc8Sopenharmony_ci        if (tmp != NULL && sandboxBuffer->buffer[sandboxBuffer->current - 1] == '/' && *tmp == '/') {
30469570cc8Sopenharmony_ci            tmp = source + 1;
30569570cc8Sopenharmony_ci        }
30669570cc8Sopenharmony_ci    }
30769570cc8Sopenharmony_ci    if (!IsPathEmpty(tmp)) {  // copy source data
30869570cc8Sopenharmony_ci        ret = HandleVariableReplace(context, sandboxBuffer, tmp, extraData);
30969570cc8Sopenharmony_ci        APPSPAWN_CHECK(ret == 0, return NULL, "Failed to replace source %{public}s ", source);
31069570cc8Sopenharmony_ci    }
31169570cc8Sopenharmony_ci    sandboxBuffer->buffer[sandboxBuffer->current] = '\0';
31269570cc8Sopenharmony_ci    // restore buffer
31369570cc8Sopenharmony_ci    sandboxBuffer->current = 0;
31469570cc8Sopenharmony_ci
31569570cc8Sopenharmony_ci    // For the depNode scenario, if there are variables in the deps path, a secondary replacement is required
31669570cc8Sopenharmony_ci    if (extraData != NULL && extraData->sandboxTag == SANDBOX_TAG_NAME_GROUP && extraData->data.depNode != NULL) {
31769570cc8Sopenharmony_ci        if (strstr(sandboxBuffer->buffer, "<") != NULL) {
31869570cc8Sopenharmony_ci            SandboxBuffer *tmpBuffer = &((SandboxContext *)context)->buffer[BUFFER_FOR_TMP];
31969570cc8Sopenharmony_ci            ret = HandleVariableReplace(context, tmpBuffer, sandboxBuffer->buffer, extraData);
32069570cc8Sopenharmony_ci            APPSPAWN_CHECK(ret == 0, return NULL, "Failed to replace source %{public}s ", sandboxBuffer->buffer);
32169570cc8Sopenharmony_ci            tmpBuffer->buffer[tmpBuffer->current] = '\0';
32269570cc8Sopenharmony_ci            ret = strcpy_s(sandboxBuffer->buffer, sandboxBuffer->bufferLen, tmpBuffer->buffer);
32369570cc8Sopenharmony_ci            APPSPAWN_CHECK(ret == 0, return NULL, "Failed to copy source %{public}s ", sandboxBuffer->buffer);
32469570cc8Sopenharmony_ci        }
32569570cc8Sopenharmony_ci    }
32669570cc8Sopenharmony_ci    return sandboxBuffer->buffer;
32769570cc8Sopenharmony_ci}
32869570cc8Sopenharmony_ci
32969570cc8Sopenharmony_ciint AddVariableReplaceHandler(const char *name, ReplaceVarHandler handler)
33069570cc8Sopenharmony_ci{
33169570cc8Sopenharmony_ci    APPSPAWN_CHECK(name != NULL && handler != NULL, return APPSPAWN_ARG_INVALID, "Invalid arg ");
33269570cc8Sopenharmony_ci    if (GetAppSandboxVarNode(name) != NULL) {
33369570cc8Sopenharmony_ci        return APPSPAWN_NODE_EXIST;
33469570cc8Sopenharmony_ci    }
33569570cc8Sopenharmony_ci
33669570cc8Sopenharmony_ci    size_t len = APPSPAWN_ALIGN(strlen(name) + 1);
33769570cc8Sopenharmony_ci    AppSandboxVarNode *node = (AppSandboxVarNode *)malloc(sizeof(AppSandboxVarNode) + len);
33869570cc8Sopenharmony_ci    APPSPAWN_CHECK(node != NULL, return APPSPAWN_SYSTEM_ERROR, "Failed to create sandbox");
33969570cc8Sopenharmony_ci    OH_ListInit(&node->node);
34069570cc8Sopenharmony_ci    node->replaceVar = handler;
34169570cc8Sopenharmony_ci    int ret = strcpy_s(node->name, len, name);
34269570cc8Sopenharmony_ci    APPSPAWN_CHECK(ret == 0, free(node);
34369570cc8Sopenharmony_ci        return -1, "Failed to copy name %{public}s", name);
34469570cc8Sopenharmony_ci    OH_ListAddTail(&g_sandboxVarList, &node->node);
34569570cc8Sopenharmony_ci    return 0;
34669570cc8Sopenharmony_ci}
34769570cc8Sopenharmony_ci
34869570cc8Sopenharmony_civoid AddDefaultVariable(void)
34969570cc8Sopenharmony_ci{
35069570cc8Sopenharmony_ci    AddVariableReplaceHandler(PARAMETER_PACKAGE_NAME, VarPackageNameReplace);
35169570cc8Sopenharmony_ci    AddVariableReplaceHandler(PARAMETER_USER_ID, VarCurrentUseIdReplace);
35269570cc8Sopenharmony_ci    AddVariableReplaceHandler(PARAMETER_PACKAGE_INDEX, VarPackageNameIndexReplace);
35369570cc8Sopenharmony_ci    AddVariableReplaceHandler(PARAMETER_ARK_WEB_PACKAGE_INDEX, VarArkWebPackageNameReplace);
35469570cc8Sopenharmony_ci    /*
35569570cc8Sopenharmony_ci        deps-path路径变量的含义:
35669570cc8Sopenharmony_ci        1)首次挂载时,表示mount-paths-deps->sandbox-path  【STAGE_GLOBAL或者应用孵化时的挂载】
35769570cc8Sopenharmony_ci        使用 MOUNT_PATH_OP_REPLACE_BY_SANDBOX 标记
35869570cc8Sopenharmony_ci        2)二次挂载时,表示mount-paths-deps->src-path;
35969570cc8Sopenharmony_ci            如果mount-paths-deps->src-path为空,则使用mount-paths-deps->sandbox-path
36069570cc8Sopenharmony_ci        使用 MOUNT_PATH_OP_ONLY_SANDBOX + MOUNT_PATH_OP_REPLACE_BY_SRC,只使用源目录,不添加root-dir
36169570cc8Sopenharmony_ci        【RemountByName时,如el2解锁或nweb更新时】
36269570cc8Sopenharmony_ci    */
36369570cc8Sopenharmony_ci    AddVariableReplaceHandler("<deps-sandbox-path>", ReplaceVariableForDepSandboxPath);
36469570cc8Sopenharmony_ci    AddVariableReplaceHandler("<deps-src-path>", ReplaceVariableForDepSrcPath);
36569570cc8Sopenharmony_ci    AddVariableReplaceHandler("<deps-path>", ReplaceVariableForDepPath);
36669570cc8Sopenharmony_ci    AddVariableReplaceHandler("<variablePackageName>", ReplaceVariableForpackageName);
36769570cc8Sopenharmony_ci}
36869570cc8Sopenharmony_ci
36969570cc8Sopenharmony_civoid ClearVariable(void)
37069570cc8Sopenharmony_ci{
37169570cc8Sopenharmony_ci    OH_ListRemoveAll(&g_sandboxVarList, NULL);
37269570cc8Sopenharmony_ci}
373