13af6ab5fSopenharmony_ci/*
23af6ab5fSopenharmony_ci * Copyright (c) 2024 Huawei Device Co., Ltd.
33af6ab5fSopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License");
43af6ab5fSopenharmony_ci * you may not use this file except in compliance with the License.
53af6ab5fSopenharmony_ci * You may obtain a copy of the License at
63af6ab5fSopenharmony_ci *
73af6ab5fSopenharmony_ci *     http://www.apache.org/licenses/LICENSE-2.0
83af6ab5fSopenharmony_ci *
93af6ab5fSopenharmony_ci * Unless required by applicable law or agreed to in writing, software
103af6ab5fSopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS,
113af6ab5fSopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
123af6ab5fSopenharmony_ci * See the License for the specific language governing permissions and
133af6ab5fSopenharmony_ci * limitations under the License.
143af6ab5fSopenharmony_ci */
153af6ab5fSopenharmony_ci
163af6ab5fSopenharmony_ciimport fs from 'fs';
173af6ab5fSopenharmony_ciimport path from 'path';
183af6ab5fSopenharmony_ci
193af6ab5fSopenharmony_ciimport { ArkObfuscator, renameIdentifierModule } from '../ArkObfuscator';
203af6ab5fSopenharmony_ciimport { collectResevedFileNameInIDEConfig, MergedConfig, ObConfigResolver, readNameCache } from './ConfigResolver';
213af6ab5fSopenharmony_ciimport { type IOptions } from '../configs/IOptions';
223af6ab5fSopenharmony_ci
233af6ab5fSopenharmony_ci// Record all unobfuscated properties and reasons.
243af6ab5fSopenharmony_ciexport let historyUnobfuscatedPropMap: Map<string, string[]> | undefined;
253af6ab5fSopenharmony_ciexport let historyAllUnobfuscatedNamesMap: Map<string, Object> = new Map();
263af6ab5fSopenharmony_ci
273af6ab5fSopenharmony_ciexport const printerConfig = {
283af6ab5fSopenharmony_ci  // Print obfuscation time&memory usage of all files and obfuscation processes
293af6ab5fSopenharmony_ci  mFilesPrinter: false,
303af6ab5fSopenharmony_ci  // Print time&memory usage of a single file obfuscation in transform processes
313af6ab5fSopenharmony_ci  mSingleFilePrinter: false,
323af6ab5fSopenharmony_ci  // Print sum up time of transform processes during obfuscation
333af6ab5fSopenharmony_ci  mSumPrinter: false,
343af6ab5fSopenharmony_ci  // Output path of printer
353af6ab5fSopenharmony_ci  mOutputPath: '',
363af6ab5fSopenharmony_ci};
373af6ab5fSopenharmony_ci
383af6ab5fSopenharmony_ciexport function initObfuscationConfig(projectConfig: any, arkProjectConfig: any, logger: any): void {
393af6ab5fSopenharmony_ci  const obConfig: ObConfigResolver = new ObConfigResolver(projectConfig, logger, true);
403af6ab5fSopenharmony_ci  const mergedObConfig: MergedConfig = obConfig.resolveObfuscationConfigs();
413af6ab5fSopenharmony_ci  const isHarCompiled: boolean = projectConfig.compileHar;
423af6ab5fSopenharmony_ci  if (mergedObConfig.options.disableObfuscation) {
433af6ab5fSopenharmony_ci    return;
443af6ab5fSopenharmony_ci  }
453af6ab5fSopenharmony_ci
463af6ab5fSopenharmony_ci  if (mergedObConfig.options.enableFileNameObfuscation) {
473af6ab5fSopenharmony_ci    const ohPackagePath = path.join(projectConfig.modulePath, 'oh-package.json5');
483af6ab5fSopenharmony_ci    const entryArray = arkProjectConfig.entryArrayForObf;
493af6ab5fSopenharmony_ci    const reservedFileNamesInIDEconfig = collectResevedFileNameInIDEConfig(
503af6ab5fSopenharmony_ci      ohPackagePath,
513af6ab5fSopenharmony_ci      projectConfig,
523af6ab5fSopenharmony_ci      arkProjectConfig.modulePathMap,
533af6ab5fSopenharmony_ci      entryArray,
543af6ab5fSopenharmony_ci    );
553af6ab5fSopenharmony_ci    mergedObConfig.reservedFileNames.push(...reservedFileNamesInIDEconfig);
563af6ab5fSopenharmony_ci  }
573af6ab5fSopenharmony_ci  arkProjectConfig.obfuscationMergedObConfig = mergedObConfig;
583af6ab5fSopenharmony_ci
593af6ab5fSopenharmony_ci  arkProjectConfig.arkObfuscator = initArkGuardConfig(
603af6ab5fSopenharmony_ci    projectConfig.obfuscationOptions?.obfuscationCacheDir,
613af6ab5fSopenharmony_ci    logger,
623af6ab5fSopenharmony_ci    mergedObConfig,
633af6ab5fSopenharmony_ci    isHarCompiled,
643af6ab5fSopenharmony_ci  );
653af6ab5fSopenharmony_ci}
663af6ab5fSopenharmony_ci
673af6ab5fSopenharmony_cifunction initArkGuardConfig(
683af6ab5fSopenharmony_ci  obfuscationCacheDir: string | undefined,
693af6ab5fSopenharmony_ci  logger: any,
703af6ab5fSopenharmony_ci  mergedObConfig: MergedConfig,
713af6ab5fSopenharmony_ci  isHarCompiled: boolean,
723af6ab5fSopenharmony_ci): ArkObfuscator {
733af6ab5fSopenharmony_ci  const arkguardConfig: IOptions = {
743af6ab5fSopenharmony_ci    mCompact: mergedObConfig.options.compact,
753af6ab5fSopenharmony_ci    mDisableConsole: mergedObConfig.options.removeLog,
763af6ab5fSopenharmony_ci    mSimplify: false,
773af6ab5fSopenharmony_ci    mRemoveComments: true,
783af6ab5fSopenharmony_ci    mNameObfuscation: {
793af6ab5fSopenharmony_ci      mEnable: true,
803af6ab5fSopenharmony_ci      mNameGeneratorType: 1,
813af6ab5fSopenharmony_ci      mReservedNames: mergedObConfig.reservedNames,
823af6ab5fSopenharmony_ci      mRenameProperties: mergedObConfig.options.enablePropertyObfuscation,
833af6ab5fSopenharmony_ci      mReservedProperties: mergedObConfig.reservedPropertyNames,
843af6ab5fSopenharmony_ci      mKeepStringProperty: !mergedObConfig.options.enableStringPropertyObfuscation,
853af6ab5fSopenharmony_ci      mTopLevel: mergedObConfig.options.enableToplevelObfuscation,
863af6ab5fSopenharmony_ci      mReservedToplevelNames: mergedObConfig.reservedGlobalNames,
873af6ab5fSopenharmony_ci      mUniversalReservedProperties: mergedObConfig.universalReservedPropertyNames,
883af6ab5fSopenharmony_ci      mUniversalReservedToplevelNames: mergedObConfig.universalReservedGlobalNames
893af6ab5fSopenharmony_ci    },
903af6ab5fSopenharmony_ci    mUnobfuscationOption: {
913af6ab5fSopenharmony_ci      mPrintKeptNames: mergedObConfig.options.printKeptNames,
923af6ab5fSopenharmony_ci      mPrintPath: mergedObConfig.options.printKeptNamesPath
933af6ab5fSopenharmony_ci    },
943af6ab5fSopenharmony_ci    mRemoveDeclarationComments: {
953af6ab5fSopenharmony_ci      mEnable: mergedObConfig.options.removeComments,
963af6ab5fSopenharmony_ci      mReservedComments: mergedObConfig.keepComments,
973af6ab5fSopenharmony_ci    },
983af6ab5fSopenharmony_ci    mEnableSourceMap: true,
993af6ab5fSopenharmony_ci    mEnableNameCache: true,
1003af6ab5fSopenharmony_ci    mRenameFileName: {
1013af6ab5fSopenharmony_ci      mEnable: mergedObConfig.options.enableFileNameObfuscation,
1023af6ab5fSopenharmony_ci      mNameGeneratorType: 1,
1033af6ab5fSopenharmony_ci      mReservedFileNames: mergedObConfig.reservedFileNames,
1043af6ab5fSopenharmony_ci    },
1053af6ab5fSopenharmony_ci    mExportObfuscation: mergedObConfig.options.enableExportObfuscation,
1063af6ab5fSopenharmony_ci    mPerformancePrinter: printerConfig,
1073af6ab5fSopenharmony_ci    mKeepFileSourceCode: {
1083af6ab5fSopenharmony_ci      mKeepSourceOfPaths: new Set(),
1093af6ab5fSopenharmony_ci      mkeepFilesAndDependencies: new Set(),
1103af6ab5fSopenharmony_ci    },
1113af6ab5fSopenharmony_ci  };
1123af6ab5fSopenharmony_ci
1133af6ab5fSopenharmony_ci  const arkObfuscator: ArkObfuscator = new ArkObfuscator();
1143af6ab5fSopenharmony_ci  arkObfuscator.init(arkguardConfig);
1153af6ab5fSopenharmony_ci  if (mergedObConfig.options.applyNameCache && mergedObConfig.options.applyNameCache.length > 0) {
1163af6ab5fSopenharmony_ci    readNameCache(mergedObConfig.options.applyNameCache, logger);
1173af6ab5fSopenharmony_ci  } else {
1183af6ab5fSopenharmony_ci    if (obfuscationCacheDir) {
1193af6ab5fSopenharmony_ci      const defaultNameCachePath: string = path.join(obfuscationCacheDir, 'nameCache.json');
1203af6ab5fSopenharmony_ci      if (fs.existsSync(defaultNameCachePath)) {
1213af6ab5fSopenharmony_ci        readNameCache(defaultNameCachePath, logger);
1223af6ab5fSopenharmony_ci      }
1233af6ab5fSopenharmony_ci    }
1243af6ab5fSopenharmony_ci  }
1253af6ab5fSopenharmony_ci  if (mergedObConfig.options.printKeptNames && obfuscationCacheDir) {
1263af6ab5fSopenharmony_ci    const defaultUnobfuscationPath: string = path.join(obfuscationCacheDir, 'keptNames.json');
1273af6ab5fSopenharmony_ci    if (fs.existsSync(defaultUnobfuscationPath)) {
1283af6ab5fSopenharmony_ci      readUnobfuscationContent(defaultUnobfuscationPath, logger);
1293af6ab5fSopenharmony_ci    }
1303af6ab5fSopenharmony_ci  }
1313af6ab5fSopenharmony_ci  return arkObfuscator;
1323af6ab5fSopenharmony_ci}
1333af6ab5fSopenharmony_ci
1343af6ab5fSopenharmony_cifunction readUnobfuscationContent(defaultUnobfuscationPath: string, logger: any): void {
1353af6ab5fSopenharmony_ci  try {
1363af6ab5fSopenharmony_ci    const unobfuscationContent = fs.readFileSync(defaultUnobfuscationPath, 'utf-8');
1373af6ab5fSopenharmony_ci    const unobfuscationObj: {
1383af6ab5fSopenharmony_ci      keptReasons: Object;
1393af6ab5fSopenharmony_ci      keptNames: {
1403af6ab5fSopenharmony_ci        property: Object;
1413af6ab5fSopenharmony_ci        [key: string]: Object;
1423af6ab5fSopenharmony_ci      };
1433af6ab5fSopenharmony_ci    } = JSON.parse(unobfuscationContent);
1443af6ab5fSopenharmony_ci
1453af6ab5fSopenharmony_ci    if (Object.keys(unobfuscationObj.keptNames.property).length !== 0) {
1463af6ab5fSopenharmony_ci      historyUnobfuscatedPropMap = new Map<string, string[]>(Object.entries(unobfuscationObj.keptNames.property));
1473af6ab5fSopenharmony_ci    }
1483af6ab5fSopenharmony_ci    const { property, ...rest } = unobfuscationObj.keptNames;
1493af6ab5fSopenharmony_ci    Object.keys(rest).forEach((key) => {
1503af6ab5fSopenharmony_ci      historyAllUnobfuscatedNamesMap.set(key, rest[key]);
1513af6ab5fSopenharmony_ci    });
1523af6ab5fSopenharmony_ci  } catch (err) {
1533af6ab5fSopenharmony_ci    logger.error(`Failed to open ${defaultUnobfuscationPath}. Error message: ${err}`);
1543af6ab5fSopenharmony_ci  }
1553af6ab5fSopenharmony_ci}
156