1/* 2 * Copyright (c) 2023 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 "hiview_napi_util.h" 17 18#include "hiview_err_code.h" 19#include "hiview_logger.h" 20#include "ipc_skeleton.h" 21#include "tokenid_kit.h" 22 23namespace OHOS { 24namespace HiviewDFX { 25DEFINE_LOG_LABEL(0xD002D03, "HiviewNapiUtil"); 26namespace { 27constexpr char FILE_NAME_KEY[] = "name"; 28constexpr char FILE_TIME_KEY[] = "mtime"; 29constexpr char FILE_SIZE_KEY[] = "size"; 30constexpr int32_t BUF_SIZE = 1024; 31} 32 33void HiviewNapiUtil::CreateUndefined(const napi_env env, napi_value& ret) 34{ 35 if (napi_get_undefined(env, &ret) != napi_ok) { 36 HIVIEW_LOGE("failed to create undefined value."); 37 } 38} 39 40void HiviewNapiUtil::CreateInt32Value(const napi_env env, int32_t value, napi_value& ret) 41{ 42 if (napi_create_int32(env, value, &ret) != napi_ok) { 43 HIVIEW_LOGE("failed to create int32 napi value."); 44 } 45} 46 47void HiviewNapiUtil::CreateInt64Value(const napi_env env, int64_t value, napi_value& ret) 48{ 49 if (napi_create_int64(env, value, &ret) != napi_ok) { 50 HIVIEW_LOGE("failed to create int64 napi value."); 51 } 52} 53 54void HiviewNapiUtil::CreateStringValue(const napi_env env, const std::string& value, napi_value& ret) 55{ 56 if (napi_create_string_utf8(env, value.c_str(), NAPI_AUTO_LENGTH, &ret) != napi_ok) { 57 HIVIEW_LOGE("failed to create string napi value."); 58 } 59} 60 61void HiviewNapiUtil::CreateErrorByRet(napi_env env, const int32_t retCode, napi_value& ret) 62{ 63 auto detail = GetErrorDetailByRet(env, retCode); 64 napi_value napiCode = nullptr; 65 CreateStringValue(env, std::to_string(detail.first), napiCode); 66 napi_value napiStr = nullptr; 67 CreateStringValue(env, detail.second, napiStr); 68 if (napi_create_error(env, napiCode, napiStr, &ret) != napi_ok) { 69 HIVIEW_LOGE("failed to create napi error"); 70 } 71} 72 73std::pair<int32_t, std::string> HiviewNapiUtil::GetErrorDetailByRet(napi_env env, const int32_t retCode) 74{ 75 HIVIEW_LOGI("origin result code is %{public}d.", retCode); 76 const std::unordered_map<int32_t, std::pair<int32_t, std::string>> errMap = { 77 {HiviewNapiErrCode::ERR_PERMISSION_CHECK, {HiviewNapiErrCode::ERR_PERMISSION_CHECK, 78 "Permission denied. The app does not have the necessary permissions."}}, 79 {HiviewNapiErrCode::ERR_INNER_INVALID_LOGTYPE, 80 {HiviewNapiErrCode::ERR_PARAM_CHECK, "Parameter error. The value of logType is invalid."}}, 81 {HiviewNapiErrCode::ERR_INNER_READ_ONLY, 82 {HiviewNapiErrCode::ERR_PARAM_CHECK, "Parameter error. The specified logType is read-only."}}, 83 {HiviewNapiErrCode::ERR_SOURCE_FILE_NOT_EXIST, 84 {HiviewNapiErrCode::ERR_SOURCE_FILE_NOT_EXIST, "Source file does not exists."}} 85 }; 86 return errMap.find(retCode) == errMap.end() ? 87 std::make_pair(HiviewNapiErrCode::ERR_DEFAULT, "Environment is abnormal.") : errMap.at(retCode); 88} 89 90bool HiviewNapiUtil::IsMatchType(napi_env env, const napi_value& value, napi_valuetype type) 91{ 92 napi_valuetype paramType; 93 napi_typeof(env, value, ¶mType); 94 return paramType == type; 95} 96 97void HiviewNapiUtil::SetNamedProperty( 98 const napi_env env, napi_value& object, const std::string& propertyName, napi_value& propertyValue) 99{ 100 if (napi_set_named_property(env, object, propertyName.c_str(), propertyValue) != napi_ok) { 101 HIVIEW_LOGE("set %{public}s property failed", propertyName.c_str()); 102 } 103} 104 105bool HiviewNapiUtil::ParseStringValue( 106 const napi_env env, const std::string& paramName, const napi_value& value, std::string& retValue) 107{ 108 if (!IsMatchType(env, value, napi_string)) { 109 HIVIEW_LOGE("parameter %{public}s type isn't string", paramName.c_str()); 110 ThrowParamTypeError(env, paramName, "string"); 111 return false; 112 } 113 char buf[BUF_SIZE] = {0}; 114 size_t bufLength = 0; 115 if (napi_get_value_string_utf8(env, value, buf, BUF_SIZE - 1, &bufLength) != napi_ok) { 116 HIVIEW_LOGE("failed to parse napi value of string type."); 117 } else { 118 retValue = std::string {buf}; 119 } 120 return true; 121} 122 123void HiviewNapiUtil::CreateJsFileInfo(const napi_env env, const HiviewFileInfo& fileInfo, napi_value& val) 124{ 125 napi_value name; 126 CreateStringValue(env, fileInfo.name, name); 127 SetNamedProperty(env, val, FILE_NAME_KEY, name); 128 129 napi_value mtime; 130 CreateInt64Value(env, fileInfo.mtime, mtime); 131 SetNamedProperty(env, val, FILE_TIME_KEY, mtime); 132 133 napi_value size; 134 CreateInt64Value(env, fileInfo.size, size); 135 SetNamedProperty(env, val, FILE_SIZE_KEY, size); 136} 137 138napi_value HiviewNapiUtil::GenerateFileInfoResult(const napi_env env, const std::vector<HiviewFileInfo>& fileInfos) 139{ 140 napi_value result; 141 auto length = fileInfos.size(); 142 napi_create_array_with_length(env, length, &result); 143 for (decltype(length) i = 0; i < length; ++i) { 144 napi_value item; 145 if (napi_create_object(env, &item) != napi_ok) { 146 HIVIEW_LOGE("failed to create a new napi object."); 147 break; 148 } 149 CreateJsFileInfo(env, fileInfos[i], item); 150 napi_set_element(env, result, i, item); 151 } 152 return result; 153} 154 155bool HiviewNapiUtil::CheckDirPath(const std::string& path) 156{ 157 return path.empty() || path.find("..") == std::string::npos; 158} 159 160void HiviewNapiUtil::ThrowErrorByCode(napi_env env, int32_t errCode) 161{ 162 auto detail = GetErrorDetailByRet(env, errCode); 163 ThrowError(env, detail.first, detail.second); 164} 165 166void HiviewNapiUtil::ThrowParamContentError(napi_env env, const std::string& paramName) 167{ 168 ThrowError(env, HiviewNapiErrCode::ERR_PARAM_CHECK, 169 "Parameter error. The content of " + paramName + " is invalid."); 170} 171 172void HiviewNapiUtil::ThrowParamTypeError(napi_env env, const std::string& paramName, const std::string& paramType) 173{ 174 ThrowError(env, HiviewNapiErrCode::ERR_PARAM_CHECK, 175 "Parameter error. The type of " + paramName + " must be " + paramType + "."); 176} 177 178void HiviewNapiUtil::ThrowError(napi_env env, const int32_t code, const std::string& msg) 179{ 180 if (napi_throw_error(env, std::to_string(code).c_str(), msg.c_str()) != napi_ok) { 181 HIVIEW_LOGE("failed to throw error, code=%{public}d, msg=%{public}s", code, msg.c_str()); 182 } 183} 184 185void HiviewNapiUtil::ThrowSystemAppPermissionError(napi_env env) 186{ 187 ThrowError(env, HiviewNapiErrCode::ERR_NON_SYS_APP_PERMISSION, 188 "Permission denied, non-system app called system api."); 189} 190 191bool HiviewNapiUtil::IsSystemAppCall() 192{ 193 uint64_t tokenId = IPCSkeleton::GetCallingFullTokenID(); 194 return Security::AccessToken::TokenIdKit::IsSystemAppByFullTokenID(tokenId); 195} 196} // namespace HiviewDFX 197} // namespace OHOS