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 { describe, it } from 'mocha'; 17import { assert } from 'chai'; 18import { ArkObfuscator, FileUtils, wildcardTransformer } from '../../../src/ArkObfuscator'; 19import { ArkObfuscatorForTest } from '../../../src/ArkObfuscatorForTest' 20import path from 'path'; 21import { TransformerFactory, Node, SourceFile, createSourceFile, ScriptTarget, Printer, createTextWriter, RawSourceMap } from 'typescript'; 22import { IOptions } from '../../../src/configs/IOptions'; 23import { getSourceMapGenerator } from '../../../src/utils/SourceMapUtil'; 24import fs from 'fs'; 25 26describe('Tester Cases for <ArkObfuscatorForTest>.', function () { 27 describe('Tester Cases for <ArkObfuscatorForTest>.', function () { 28 let etsSourceFile: SourceFile; 29 let dEtsSourceFile: SourceFile; 30 let tsSourceFile: SourceFile; 31 let etsSourceFilePath: string = 'demo.ets'; 32 let dEtsSourceFilePath: string = 'demo.d.ets'; 33 let tsSourceFilePath: string = 'demo.ts'; 34 35 before('init sourceFile', function () { 36 const etsfileContent = `//This is a comment 37//This is a comment 38//This is a comment 39//This is a comment 40class Demo{ 41 constructor(public title: string, public content: string, public mark: number) { 42 this.title = title 43 this.content = content 44 this.mark = mark 45 } 46} 47`; 48 const dEtsFileContent = ` 49 /** 50 * This is a comment 51 */ 52 53 class Demo{ 54 constructor(public title: string, public content: string, public mark: number) { 55 this.title = title 56 this.content = content 57 this.mark = mark 58 } 59 } 60 `; 61 62 const tsFileContent = ` 63 //This is a comment 64 class Demo{ 65 constructor(public title: string, public content: string, public mark: number) { 66 this.title = title 67 this.content = content 68 this.mark = mark 69 } 70 } 71 `; 72 73 etsSourceFile = createSourceFile('demo.ts', etsfileContent, ScriptTarget.ES2015, true); 74 dEtsSourceFile = createSourceFile(dEtsSourceFilePath, dEtsFileContent, ScriptTarget.ES2015, true); 75 tsSourceFile = createSourceFile(tsSourceFilePath, tsFileContent, ScriptTarget.ES2015, true); 76 }); 77 78 it('Tester: test case for handleTsHarComments for ets file', function () { 79 let mCustomProfiles: IOptions | undefined = FileUtils.readFileAsJson(path.join(__dirname, "default_config.json")); 80 let arkobfuscator = new ArkObfuscatorForTest(); 81 arkobfuscator.init(mCustomProfiles); 82 let originalFilePath = 'demo.ets'; 83 ArkObfuscatorForTest.projectInfo = { packageDir: '', projectRootPath: '', localPackageSet: new Set<string>(), useNormalized: false, useTsHar: true }; 84 arkobfuscator.handleTsHarComments(etsSourceFile, originalFilePath); 85 let sourceMapGenerator = getSourceMapGenerator(originalFilePath); 86 const textWriter = createTextWriter('\n'); 87 arkobfuscator.createObfsPrinter(etsSourceFile.isDeclarationFile).writeFile(etsSourceFile, textWriter, sourceMapGenerator); 88 const actualContent = textWriter.getText(); 89 const expectContent = ` 90 // @keepTs 91 // @ts-nocheck 92 class Demo { 93 constructor(public title: string, public content: string, public mark: number) { 94 this.title = title; 95 this.content = content; 96 this.mark = mark; 97 } 98 }`; 99 100 let actualSourceMap: RawSourceMap = sourceMapGenerator.toJSON(); 101 actualSourceMap.sourceRoot = ""; 102 let expectSourceMap = { 103 "version": 3, 104 "file": "demo.ets", 105 "sourceRoot": "", 106 "sources": [ 107 "demo.ts" 108 ], 109 "names": [], 110 "mappings": ";;AAIA,MAAM,IAAI;IACR,YAAY,MAAM,CAAE,KAAK,EAAE,MAAM,EAAE,MAAM,CAAE,OAAO,EAAE,MAAM,EAAE,MAAM,CAAE,IAAI,EAAE,MAAM;QAC5E,IAAI,CAAC,KAAK,GAAG,KAAK,CAAA;QAClB,IAAI,CAAC,OAAO,GAAG,OAAO,CAAA;QACtB,IAAI,CAAC,IAAI,GAAG,IAAI,CAAA;IACpB,CAAC;CACF" 111 } 112 console.log(JSON.stringify(actualSourceMap, null, 2)) 113 assert.strictEqual(compareStringsIgnoreNewlines(actualContent, expectContent), true); 114 assert.strictEqual(compareStringsIgnoreNewlines(JSON.stringify(actualSourceMap, null, 2), JSON.stringify(expectSourceMap, null, 2)), true); 115 }); 116 117 it('Tester: test case for handleTsHarComments for d.ets file', function () { 118 let mCustomProfiles: IOptions | undefined = FileUtils.readFileAsJson(path.join(__dirname, "default_config.json")); 119 let arkobfuscator = new ArkObfuscatorForTest(); 120 arkobfuscator.init(mCustomProfiles); 121 ArkObfuscatorForTest.projectInfo = { packageDir: '', projectRootPath: '', localPackageSet: new Set<string>(), useNormalized: false, useTsHar: true }; 122 arkobfuscator.handleTsHarComments(dEtsSourceFile, dEtsSourceFilePath); 123 let sourceMapGenerator = getSourceMapGenerator(dEtsSourceFilePath); 124 const textWriter = createTextWriter('\n'); 125 arkobfuscator.createObfsPrinter(dEtsSourceFile.isDeclarationFile).writeFile(dEtsSourceFile, textWriter, sourceMapGenerator); 126 const actualContent = textWriter.getText(); 127 const expectContent = ` 128 /** 129 * This is a comment 130 */ 131 class Demo { 132 constructor(public title: string, public content: string, public mark: number) { 133 this.title = title; 134 this.content = content; 135 this.mark = mark; 136 } 137 }`; 138 assert.strictEqual(compareStringsIgnoreNewlines(actualContent, expectContent), true); 139 }); 140 141 it('Tester: test case for handleTsHarComments for ts file', function () { 142 let mCustomProfiles: IOptions | undefined = FileUtils.readFileAsJson(path.join(__dirname, "default_config.json")); 143 let arkobfuscator = new ArkObfuscatorForTest(); 144 arkobfuscator.init(mCustomProfiles); 145 ArkObfuscatorForTest.projectInfo = { packageDir: '', projectRootPath: '', localPackageSet: new Set<string>(), useNormalized: false, useTsHar: true }; 146 arkobfuscator.handleTsHarComments(tsSourceFile, tsSourceFilePath); 147 let sourceMapGenerator = getSourceMapGenerator(tsSourceFilePath); 148 const textWriter = createTextWriter('\n'); 149 arkobfuscator.createObfsPrinter(tsSourceFile.isDeclarationFile).writeFile(tsSourceFile, textWriter, sourceMapGenerator); 150 const actualContent = textWriter.getText(); 151 const expectContent = ` 152 class Demo { 153 constructor(public title: string, public content: string, public mark: number) { 154 this.title = title; 155 this.content = content; 156 this.mark = mark; 157 } 158 }`; 159 console.log(actualContent) 160 assert.strictEqual(compareStringsIgnoreNewlines(actualContent, expectContent), true); 161 console.log(actualContent); 162 }); 163 }); 164 165 describe('Tester Cases for <ArkObfuscatorForTest>.', function () { 166 it('Tester: test case for ArkObfuscatorForTest.ini', function (){ 167 let configPath = "test/ut/arkobfuscator/iniTestObfConfig.json" 168 let obfuscator: ArkObfuscatorForTest = new ArkObfuscatorForTest(); 169 const originalConfig: IOptions | undefined = FileUtils.readFileAsJson(configPath); 170 obfuscator.init(originalConfig); 171 let config = obfuscator.customProfiles; 172 let reservedTopelevelNames = config.mNameObfuscation?.mReservedToplevelNames; 173 let reservedProperty = config.mNameObfuscation?.mReservedProperties; 174 let universalReservedToplevelNames = config.mNameObfuscation?.mUniversalReservedToplevelNames as RegExp[]; 175 let universalReservedProperties = config.mNameObfuscation?.mUniversalReservedProperties as RegExp[]; 176 assert.isTrue(reservedTopelevelNames?.includes("func2")); 177 assert.isTrue(reservedProperty?.includes("prop")); 178 assert.equal(universalReservedToplevelNames[0].toString(), new RegExp(`^${wildcardTransformer("a*")}$`).toString()); 179 assert.equal(universalReservedToplevelNames[1].toString(), new RegExp(`^${wildcardTransformer("*shoul?keep*")}$`).toString()); 180 assert.equal(universalReservedProperties[0].toString(), new RegExp(`^${wildcardTransformer("prop?")}$`).toString()); 181 assert.equal(universalReservedProperties[2].toString(), new RegExp(`^${wildcardTransformer("*pro?")}$`).toString()); 182 assert.equal(universalReservedProperties[1].toString(), new RegExp(`^${wildcardTransformer("function*")}$`).toString()); 183 }); 184 }); 185 186 describe('Tester Cases for <ArkObfuscator>.', function () { 187 it('Tester: test case for ArkObfuscator.ini', function (){ 188 let configPath = "test/ut/arkobfuscator/iniTestObfConfig.json" 189 let obfuscator: ArkObfuscator = new ArkObfuscator(); 190 let config = FileUtils.readFileAsJson(configPath) as IOptions; 191 obfuscator.init(config); 192 let reservedTopelevelNames = config.mNameObfuscation?.mReservedToplevelNames; 193 let reservedProperty = config.mNameObfuscation?.mReservedProperties; 194 let universalReservedToplevelNames = config.mNameObfuscation?.mUniversalReservedToplevelNames; 195 let universalReservedProperties = config.mNameObfuscation?.mUniversalReservedProperties; 196 assert.isTrue(reservedTopelevelNames?.includes("func2")); 197 assert.isTrue(reservedTopelevelNames?.includes("a*")); 198 assert.isTrue(reservedTopelevelNames?.includes("*shoul?keep*")); 199 assert.isTrue(reservedProperty?.includes("prop")); 200 assert.isTrue(reservedProperty?.includes("prop?")); 201 assert.isTrue(reservedProperty?.includes("*pro?")); 202 assert.isTrue(reservedProperty?.includes("function*")); 203 assert.equal(universalReservedToplevelNames, undefined); 204 assert.equal(universalReservedProperties, undefined); 205 }); 206 }); 207}); 208 209function compareStringsIgnoreNewlines(str1: string, str2: string): boolean { 210 const normalize = (str: string) => str.replace(/[\n\r\s]+/g, ''); 211 return normalize(str1) === normalize(str2); 212}