1/*
2 * Copyright (c) 2022-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 "exception_branch_checker.h"
17#include "hilog/log.h"
18#include "securec.h"
19
20#define MAX_LOG_LEN 1024
21#define PERMISSION_NUM 3
22
23namespace {
24std::vector<std::string> g_hilogPermissionList = {"{public}", "{private}", "{protect}"};
25
26void RemoveHilogModifiers(const char *fmt, char *modifiedFmt)
27{
28    std::string strTypeFmt = fmt;
29    std::string::size_type pos = 0;
30    for (int32_t i = 0; i < PERMISSION_NUM; i++) {
31        while ((pos = strTypeFmt.find(g_hilogPermissionList[i], pos)) != std::string::npos) {
32            strTypeFmt.erase(pos, g_hilogPermissionList[i].length());
33        }
34    }
35    if (strcpy_s(modifiedFmt, strTypeFmt.length() + 1, strTypeFmt.c_str()) != EOK) {
36        return;
37    }
38}
39}
40
41#ifdef HILOG_FMTID
42int32_t HiLogPrintDictNew(const LogType type, const LogLevel level, const unsigned int domain, const char *tag,
43    const unsigned int uuid, const unsigned int fmtOffset, const char *fmt, ...)
44#else
45int32_t HiLogPrint(LogType type, LogLevel level, unsigned int domain, const char *tag, const char *fmt, ...)
46#endif
47{
48    va_list args = { 0 };
49    char buffer[MAX_LOG_LEN] = { 0 };
50    char modifiedFmt[MAX_LOG_LEN] = { 0 };
51
52    RemoveHilogModifiers(fmt, modifiedFmt);
53
54    va_start(args, fmt);
55    int32_t ret = vsprintf_s(&buffer[0], sizeof(buffer), modifiedFmt, args);
56    va_end(args);
57    if (ret < 0) {
58        return ret;
59    }
60
61    auto *checker = ExceptionBranchChecker::GetCurrentInstance();
62    if (checker != nullptr) {
63        checker->WriteLog(buffer);
64    }
65
66    return ret;
67}
68
69ExceptionBranchChecker* ExceptionBranchChecker::GetCurrentInstance()
70{
71    return instance_.load();
72}
73
74ExceptionBranchChecker::ExceptionBranchChecker(const std::string &branch)
75    : isMatched_(false), matchBranch_(branch)
76{
77    instance_.store(this);
78}
79
80ExceptionBranchChecker::~ExceptionBranchChecker()
81{
82    instance_.store(nullptr);
83}
84
85void ExceptionBranchChecker::WriteLog(const std::string& log)
86{
87    if (log.find(matchBranch_) != std::string::npos) {
88        isMatched_ = true;
89    }
90}
91
92bool ExceptionBranchChecker::GetResult() const
93{
94    return isMatched_;
95}