/* * Copyright (c) 2023 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. */ import path from 'path'; import {ApiExtractor} from './ApiExtractor'; import {ListUtil} from '../utils/ListUtil'; import type {IOptions} from '../configs/IOptions'; import { stringPropsSet, structPropsSet, enumPropsSet } from '../utils/OhsUtil'; export const scanProjectConfig: { mPropertyObfuscation?: boolean, mKeepStringProperty?: boolean, mExportObfuscation?: boolean, mkeepFilesAndDependencies?: Set, isHarCompiled?: boolean } = {}; /** * if rename property is not open, api read and extract can be skipped * * init plugin, read api info of openHarmony sdk and generate file of reserved name, property and string. * @param sdkDir absolute path like D:\\HuaweiApp\\ohsdk * @param outputDir */ export function initPlugin(sdkDir: string, outputDir: string): void { // create sdk api file if not exist const ohSdkPath: string = path.resolve(sdkDir); if (!ohSdkPath) { console.error('SDK path is not found.'); } const apiVersions: string[] = ['']; apiVersions.forEach((versionString) => { ApiExtractor.parseOhSdk(ohSdkPath, versionString, true, outputDir); }); } /** * need read api info or not * @param customProfiles */ export function needReadApiInfo(customProfiles: IOptions): boolean { return isEnabledPropertyObfuscation(customProfiles) || customProfiles.mExportObfuscation; } export function isEnabledPropertyObfuscation(customProfiles: IOptions): boolean { return (customProfiles.mNameObfuscation && customProfiles.mNameObfuscation.mEnable && customProfiles.mNameObfuscation.mRenameProperties); } function initScanProjectConfig(customProfiles: IOptions, isHarCompiled?: boolean) { scanProjectConfig.mPropertyObfuscation = customProfiles.mNameObfuscation?.mRenameProperties; scanProjectConfig.mKeepStringProperty = customProfiles.mNameObfuscation?.mKeepStringProperty; scanProjectConfig.mExportObfuscation = customProfiles.mExportObfuscation; scanProjectConfig.mkeepFilesAndDependencies = customProfiles.mKeepFileSourceCode?.mkeepFilesAndDependencies; scanProjectConfig.isHarCompiled = isHarCompiled; } export interface ReseverdSetForArkguard { structPropertySet: Set | undefined; stringPropertySet: Set | undefined; exportNameAndPropSet: Set | undefined; exportNameSet: Set | undefined; enumPropertySet: Set | undefined; } /** * read project reserved properties by collected paths * @param filesForCompilation set collection of files * @param customProfiles */ export function readProjectPropertiesByCollectedPaths(filesForCompilation: Set, customProfiles: IOptions, isHarCompiled: boolean): ReseverdSetForArkguard { const ApiType = ApiExtractor.ApiType; let scanningCommonType = undefined; let scanningLibsType = undefined; if (needReadApiInfo(customProfiles)) { scanningCommonType = ApiType.PROJECT; scanningLibsType = ApiType.PROJECT_DEPENDS; } else { scanningCommonType = ApiType.CONSTRUCTOR_PROPERTY; scanningLibsType = ApiType.CONSTRUCTOR_PROPERTY; } // The purpose of collecting constructor properties is to avoid generating the same name as the constructor property when obfuscating identifier names. ApiExtractor.mConstructorPropertySet = new Set(); initScanProjectConfig(customProfiles, isHarCompiled); stringPropsSet.clear(); const exportWhiteList = ApiExtractor.parseFileByPaths(filesForCompilation, scanningCommonType); const exportNamesAndProperties: Set | undefined = exportWhiteList.reservedExportPropertyAndName; const exportNames: Set | undefined = exportWhiteList.reservedExportNames; // if -enable-property-obfuscation, collect structPropsSet, exportNamesAndProperties and // stringPropsSet(if -enable-string-property-obufscation is not enabled) as whitelists. let exportNameAndPropSet: Set; let structPropertySet: Set; let stringPropertySet: Set; let enumPropertySet: Set; if (isEnabledPropertyObfuscation(customProfiles)) { exportNameAndPropSet = new Set(exportNamesAndProperties); structPropertySet = new Set(structPropsSet); enumPropertySet = new Set(enumPropsSet); if (scanProjectConfig.mKeepStringProperty) { stringPropertySet = new Set(stringPropsSet); } } structPropsSet.clear(); stringPropsSet.clear(); enumPropsSet.clear(); let exportNameSet: Set; if (scanProjectConfig.mExportObfuscation) { exportNameSet = new Set(exportNames); } return { structPropertySet: structPropertySet, stringPropertySet: stringPropertySet, exportNameAndPropSet: exportNameAndPropSet, exportNameSet: exportNameSet, enumPropertySet: enumPropertySet, }; }