• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1/*
2 * Copyright (c) 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
16import fs from 'fs';
17import path from 'path';
18
19import { ArkObfuscator, blockPrinter, renameIdentifierModule } from '../ArkObfuscator';
20import { collectResevedFileNameInIDEConfig, MergedConfig, ObConfigResolver, readNameCache } from './ConfigResolver';
21import { type IOptions } from '../configs/IOptions';
22import type { HvigorErrorInfo } from '../common/type';
23
24// Record all unobfuscated properties and reasons.
25export const historyUnobfuscatedPropMap: Map<string, string[]> = new Map<string, string[]>();
26// Record all files and the unobfuscated names and reasons in the files.
27export const historyAllUnobfuscatedNamesMap: Map<string, Object> = new Map<string, Object>();
28
29// Clear the map after one compilation is completed.
30export function clearHistoryUnobfuscatedMap(): void {
31  historyUnobfuscatedPropMap.clear();
32  historyAllUnobfuscatedNamesMap.clear();
33}
34
35export const printerConfig = {
36  // Print obfuscation time&memory usage of all files and obfuscation processes
37  mFilesPrinter: false,
38  // Print time&memory usage of a single file obfuscation in transform processes
39  mSingleFilePrinter: false,
40  // Print sum up time of transform processes during obfuscation
41  mSumPrinter: false,
42  // Output path of printer
43  mOutputPath: '',
44};
45
46export function initObfuscationConfig(projectConfig: any, arkProjectConfig: any, printObfLogger: Function): void {
47  const obConfig: ObConfigResolver = new ObConfigResolver(projectConfig, printObfLogger, true);
48  const mergedObConfig: MergedConfig = obConfig.resolveObfuscationConfigs();
49  const isHarCompiled: boolean = projectConfig.compileHar;
50  if (mergedObConfig.options.disableObfuscation) {
51    blockPrinter();
52    return;
53  }
54
55  if (mergedObConfig.options.enableFileNameObfuscation) {
56    const ohPackagePath = path.join(projectConfig.modulePath, 'oh-package.json5');
57    const entryArray = arkProjectConfig.entryArrayForObf;
58    const reservedFileNamesInIDEconfig = collectResevedFileNameInIDEConfig(
59      ohPackagePath,
60      projectConfig,
61      arkProjectConfig.modulePathMap,
62      entryArray,
63    );
64    mergedObConfig.reservedFileNames.push(...reservedFileNamesInIDEconfig);
65  }
66  arkProjectConfig.obfuscationMergedObConfig = mergedObConfig;
67
68  arkProjectConfig.arkObfuscator = initArkGuardConfig(
69    projectConfig.obfuscationOptions?.obfuscationCacheDir,
70    printObfLogger,
71    mergedObConfig,
72    isHarCompiled,
73  );
74  arkProjectConfig.arkObfuscator.obfConfigResolver = obConfig;
75}
76
77function initArkGuardConfig(
78  obfuscationCacheDir: string | undefined,
79  printObfLogger: Function,
80  mergedObConfig: MergedConfig,
81  isHarCompiled: boolean,
82): ArkObfuscator {
83  const arkguardConfig: IOptions = {
84    mCompact: mergedObConfig.options.compact,
85    mDisableConsole: mergedObConfig.options.removeLog,
86    mSimplify: false,
87    mRemoveComments: true,
88    mNameObfuscation: {
89      mEnable: true,
90      mNameGeneratorType: 1,
91      mReservedNames: mergedObConfig.reservedNames,
92      mRenameProperties: mergedObConfig.options.enablePropertyObfuscation,
93      mReservedProperties: mergedObConfig.reservedPropertyNames,
94      mKeepStringProperty: !mergedObConfig.options.enableStringPropertyObfuscation,
95      mTopLevel: mergedObConfig.options.enableToplevelObfuscation,
96      mReservedToplevelNames: mergedObConfig.reservedGlobalNames,
97      mKeepParameterNames: mergedObConfig.options.keepParameterNames,
98      mUniversalReservedProperties: mergedObConfig.universalReservedPropertyNames,
99      mUniversalReservedToplevelNames: mergedObConfig.universalReservedGlobalNames,
100      mEnableAtKeep: mergedObConfig.options.enableAtKeep
101    },
102    mUnobfuscationOption: {
103      mPrintKeptNames: mergedObConfig.options.printKeptNames,
104      mPrintPath: mergedObConfig.options.printKeptNamesPath
105    },
106    mRemoveDeclarationComments: {
107      mEnable: mergedObConfig.options.removeComments,
108      mReservedComments: mergedObConfig.keepComments,
109    },
110    mEnableSourceMap: true,
111    mEnableNameCache: true,
112    mRenameFileName: {
113      mEnable: mergedObConfig.options.enableFileNameObfuscation,
114      mNameGeneratorType: 1,
115      mReservedFileNames: mergedObConfig.reservedFileNames,
116    },
117    mExportObfuscation: mergedObConfig.options.enableExportObfuscation,
118    mPerformancePrinter: printerConfig,
119    mKeepFileSourceCode: {
120      mKeepSourceOfPaths: new Set(),
121      mkeepFilesAndDependencies: new Set(),
122    },
123    mStripLanguageDefaultWhitelist: mergedObConfig.options.stripLanguageDefault
124  };
125
126  const arkObfuscator: ArkObfuscator = new ArkObfuscator();
127  arkObfuscator.init(arkguardConfig, obfuscationCacheDir);
128  if (mergedObConfig.options.applyNameCache && mergedObConfig.options.applyNameCache.length > 0) {
129    readNameCache(mergedObConfig.options.applyNameCache, printObfLogger);
130  } else {
131    if (obfuscationCacheDir) {
132      const defaultNameCachePath: string = path.join(obfuscationCacheDir, 'nameCache.json');
133      if (fs.existsSync(defaultNameCachePath)) {
134        readNameCache(defaultNameCachePath, printObfLogger);
135      }
136    }
137  }
138  if (mergedObConfig.options.printKeptNames && obfuscationCacheDir) {
139    const defaultUnobfuscationPath: string = path.join(obfuscationCacheDir, 'keptNames.json');
140    if (fs.existsSync(defaultUnobfuscationPath)) {
141      readUnobfuscationContentCache(defaultUnobfuscationPath, printObfLogger);
142    }
143  }
144  return arkObfuscator;
145}
146
147function readUnobfuscationContentCache(defaultUnobfuscationPath: string, printObfLogger: Function): void {
148  try {
149    const unobfuscationContent = fs.readFileSync(defaultUnobfuscationPath, 'utf-8');
150    const unobfuscationObj: {
151      keptReasons: Object;
152      keptNames: {
153        property: Object;
154        [key: string]: Object;
155      };
156    } = JSON.parse(unobfuscationContent);
157
158    Object.keys(unobfuscationObj.keptNames.property).forEach((key) => {
159      historyUnobfuscatedPropMap.set(key, unobfuscationObj.keptNames.property[key]);
160    });
161
162    const { property, ...rest } = unobfuscationObj.keptNames;
163    Object.keys(rest).forEach((key) => {
164      historyAllUnobfuscatedNamesMap.set(key, rest[key]);
165    });
166  } catch (err) {
167    const errorInfo: string = `Failed to open ${defaultUnobfuscationPath}. Error message: ${err}`;
168    const errorCodeInfo: HvigorErrorInfo = {
169      code: '10804003',
170      description: 'ArkTS compiler Error',
171      cause: `Failed to open ${defaultUnobfuscationPath}. Error message: ${err}`,
172      position: defaultUnobfuscationPath,
173      solutions: [`Please check ${defaultUnobfuscationPath} as error message suggested.`],
174    };
175    printObfLogger(errorInfo, errorCodeInfo, 'error');
176  }
177}
178