* Copyright (C) 2025 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "js_interface_helper.h"
#include "media_file_utils.h"
#include "media_column.h"
#include "photo_album_column.h"
using namespace std;
namespace OHOS {
namespace Media {
string JsInterfaceHelper::MaskString(const string& str)
{
constexpr char garble = '*';
constexpr size_t garbleSmall = 3;
constexpr size_t garbleLastTwo = 2;
constexpr size_t garbleLastOne = 1;
size_t length = str.size();
string maskedString;
if (length == 0) {
return maskedString;
}
if (length == 1) {
maskedString = garble;
} else if (length <= garbleSmall) {
maskedString = string(length - garbleLastOne, garble) + str.substr(length - garbleLastOne);
} else {
maskedString = "*" + str.substr(length - garbleLastTwo);
}
return maskedString;
}
string JsInterfaceHelper::GetSafeUri(const string& uri)
{
string safeUri = uri;
if (uri == "") {
return safeUri;
}
size_t splitIndex = safeUri.find_last_of("/");
string displayName;
if (splitIndex == string::npos) {
return safeUri;
} else {
displayName = safeUri.substr(splitIndex + 1);
}
string safeDisplayName = MediaFileUtils::DesensitizeName(displayName);
safeUri = safeUri.substr(0, splitIndex) + "/" + safeDisplayName;
return safeUri;
}
template <typename T>
static string VectorToString(const vector<T>& vector, bool needsRedact, bool isUri, bool isDisplayName)
{
std::string out = "[";
for (size_t i = 0; i < vector.size(); ++i) {
if (i > 0) {
out += ", ";
}
if constexpr (std::is_same_v<T, std::string>) {
if (!needsRedact) {
out += '"' + vector[i] + '"';
} else if (isUri) {
out += '"' + JsInterfaceHelper::GetSafeUri(vector[i]) + '"';
} else if (isDisplayName) {
out += '"' + MediaFileUtils::DesensitizeName(vector[i]) + '"';
} else {
out += '"' + JsInterfaceHelper::MaskString(vector[i]) + '"';
}
} else {
out += std::to_string(vector[i]);
}
}
out += "]";
return out;
}
static string MultiValueTypeToString(const DataShare::MutliValue::Type& multiValue, bool needsRedact, bool isUri,
bool isDisplayName)
{
return std::visit([needsRedact, isUri, isDisplayName](const auto& value) -> std::string {
using T = std::decay_t<decltype(value)>;
if constexpr (std::is_same_v<T, std::monostate>) {
return "T::monostate";
} else if constexpr (std::is_same_v<T, std::vector<int>>) {
return "int" + VectorToString(value, needsRedact, isUri, isDisplayName);
} else if constexpr (std::is_same_v<T, std::vector<int64_t>>) {
return "int64_t" + VectorToString(value, needsRedact, isUri, isDisplayName);
} else if constexpr (std::is_same_v<T, std::vector<double>>) {
return "double" + VectorToString(value, needsRedact, isUri, isDisplayName);
} else {
return "string" + VectorToString(value, needsRedact, isUri, isDisplayName);
}
}, multiValue);
}
static string SingleValueTypeToString(const DataShare::SingleValue::Type& singleValue, bool needsRedact, bool isUri,
bool isDisplayName)
{
return std::visit([needsRedact, isUri, isDisplayName](const auto& value) -> std::string {
using T = std::decay_t<decltype(value)>;
if constexpr (std::is_same_v<T, std::monostate>) {
return "T::monostate";
} else if constexpr (std::is_same_v<T, bool>) {
return value ? "bool::true" : "bool::false";
} else if constexpr (std::is_same_v<T, std::string>) {
if (!needsRedact) {
return '"' + value + '"';
} else if (isUri) {
return '"' + JsInterfaceHelper::GetSafeUri(value) + '"';
} else if (isDisplayName) {
return '"' + MediaFileUtils::DesensitizeName(value) + '"';
} else {
return '"' + JsInterfaceHelper::MaskString(value) + '"';
}
} else {
return std::to_string(value);
}
}, singleValue);
}
static void LogParams(const DataShare::OperationItem& item, string& toPrint)
{
const std::string mediaUri = "uri";
const vector<string> sensitiveInfo = {
mediaUri, MediaColumn::MEDIA_FILE_PATH, MediaColumn::MEDIA_TITLE, MediaColumn::MEDIA_NAME,
MediaColumn::MEDIA_RELATIVE_PATH, MediaColumn::MEDIA_VIRTUAL_PATH, PhotoColumn::PHOTO_LATITUDE,
PhotoColumn::PHOTO_LONGITUDE, PhotoColumn::PHOTO_SOURCE_PATH, PhotoColumn::PHOTO_STORAGE_PATH,
PhotoAlbumColumns::ALBUM_NAME, PhotoAlbumColumns::ALBUM_COVER_URI, PhotoAlbumColumns::ALBUM_LPATH
};
bool needsRedact = false;
bool isUri = false;
bool isDisplayName = false;
toPrint += "SingleParams: [";
for (size_t i = 0; i < item.singleParams.size(); i++) {
if (i > 0) {
toPrint += ", ";
}
toPrint += SingleValueTypeToString(item.singleParams[i], needsRedact, isUri, isDisplayName);
if (i == 0 && std::find(sensitiveInfo.begin(), sensitiveInfo.end(),
static_cast<string>(item.GetSingle(i))) != sensitiveInfo.end()) {
needsRedact = true;
isUri = (static_cast<string>(item.GetSingle(i)) == mediaUri ||
static_cast<string>(item.GetSingle(i)) == PhotoAlbumColumns::ALBUM_COVER_URI);
isDisplayName = (static_cast<string>(item.GetSingle(i)) == MediaColumn::MEDIA_NAME);
}
}
toPrint += "], MultiParams: [";
for (size_t i = 0; i < item.multiParams.size(); i++) {
toPrint += MultiValueTypeToString(item.multiParams[i], needsRedact, isUri, isDisplayName);
}
toPrint += "]";
}
string JsInterfaceHelper::PredicateToStringSafe(const shared_ptr<DataShare::DataShareAbsPredicates>& predicate)
{
if (predicate == nullptr) {
return "[null]";
}
auto &items = predicate->GetOperationList();
string toPrint = "";
for (size_t i = 0; i < items.size(); i++) {
if (i > 0) {
toPrint += " || ";
}
LogParams(items[i], toPrint);
toPrint += ", Operation: " + to_string(static_cast<int>(items[i].operation));
}
return toPrint;
}
bool JsInterfaceHelper::PredicatesHasOrderClause(const DataShare::DataShareAbsPredicates& predicate)
{
auto &items = predicate.GetOperationList();
for (size_t i = 0; i < items.size(); i++) {
if (items[i].operation == DataShare::OperationType::ORDER_BY_ASC ||
items[i].operation == DataShare::OperationType::ORDER_BY_DESC) {
return true;
}
}
return false;
}
}
}