• 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 ts from 'typescript';
17import { shouldKeepCurFileParamerters, shouldKeepParameter } from '../../../src/utils/KeepParameterUtils';
18import { INameObfuscationOption } from '../../../src/configs/INameObfuscationOption';
19import assert from 'assert';
20import { MangledSymbolInfo } from '../../../src/common/type';
21import { TypeUtils } from '../../../src/utils/TypeUtils';
22import { NodeUtils } from '../../../src/utils/NodeUtils';
23import { PropCollections } from '../../../src/ArkObfuscator';
24import { nodeSymbolMap } from '../../../src/utils/ScopeAnalyzer';
25
26describe('Tester Cases for shouldKeepCurFileParamerters.', function () {
27  it('Tester 1-1: shouldKeepCurFileParamerters returns true', function () {
28    let path = '/user/local/tester.d.ts';
29    let content = 'export declare let a: number';
30    const ast = ts.createSourceFile(path, content, ts.ScriptTarget.ES2015, true);
31    const config: INameObfuscationOption = {
32      'mEnable': true,
33      'mNameGeneratorType': 1,
34      'mDictionaryList': [],
35      'mRenameProperties': false,
36      'mKeepStringProperty': true,
37      'mTopLevel': false,
38      'mKeepParameterNames': true,
39      'mReservedProperties': []
40    };
41    const actual = shouldKeepCurFileParamerters(ast, config);
42    assert.strictEqual(actual, true);
43  });
44
45  it('Tester 1-2: When mKeepParameterNames is disabled, shouldKeepCurFileParamerters returns false', function () {
46    let path = '/user/local/tester.d.ts';
47    let content = 'export declare let a: number';
48    const ast = ts.createSourceFile(path, content, ts.ScriptTarget.ES2015, true);
49    const config: INameObfuscationOption = {
50      'mEnable': true,
51      'mNameGeneratorType': 1,
52      'mDictionaryList': [],
53      'mRenameProperties': false,
54      'mKeepStringProperty': true,
55      'mTopLevel': false,
56      'mKeepParameterNames': false,
57      'mReservedProperties': []
58    };
59    const actual = shouldKeepCurFileParamerters(ast, config);
60    assert.strictEqual(actual, false);
61  });
62
63  it('Tester 1-3: When file is not declaration file, shouldKeepCurFileParamerters returns false', function () {
64    let path = '/user/local/tester.ts';
65    let content = 'export declare let a: number';
66    const ast = ts.createSourceFile(path, content, ts.ScriptTarget.ES2015, true);
67    const config: INameObfuscationOption = {
68      'mEnable': true,
69      'mNameGeneratorType': 1,
70      'mDictionaryList': [],
71      'mRenameProperties': false,
72      'mKeepStringProperty': true,
73      'mTopLevel': false,
74      'mKeepParameterNames': true,
75      'mReservedProperties': []
76    };
77    const actual = shouldKeepCurFileParamerters(ast, config);
78    assert.strictEqual(actual, false);
79  });
80});
81
82describe('Tester Cases for shouldKeepParameter.', function () {
83  let path = '';
84  let config: INameObfuscationOption;
85  this.beforeAll(() => {
86    path = '/user/local/tester.d.ts';
87    config = {
88      'mEnable': true,
89      'mNameGeneratorType': 1,
90      'mDictionaryList': [],
91      'mRenameProperties': false,
92      'mKeepStringProperty': true,
93      'mTopLevel': false,
94      'mKeepParameterNames': true,
95      'mReservedProperties': []
96    }
97  });
98  it('Tester 2-1: When node is undefined, shouldKeepParameter returns false', function () {
99    let content = 'export declare let a: number';
100    const ast = ts.createSourceFile(path, content, ts.ScriptTarget.ES2015, true);
101    let node: ts.Identifier = undefined;
102    let mangledSymbolNames: Map<ts.Symbol, MangledSymbolInfo> = new Map<ts.Symbol, MangledSymbolInfo>();
103    const checker: ts.TypeChecker = TypeUtils.createChecker(ast);
104    const actual = shouldKeepParameter(node, config, mangledSymbolNames, checker);
105    assert.strictEqual(actual, false);
106  });
107
108  it('Tester 2-2: When node is not parameter, shouldKeepParameter returns false', function () {
109    let content = 'export declare let a: number';
110    const ast = ts.createSourceFile(path, content, ts.ScriptTarget.ES2015, true);
111    let node = (ast.statements[0] as ts.VariableStatement).declarationList.declarations[0].name;
112    let mangledSymbolNames: Map<ts.Symbol, MangledSymbolInfo> = new Map<ts.Symbol, MangledSymbolInfo>();
113    const checker: ts.TypeChecker = TypeUtils.createChecker(ast);
114    // @ts-ignore
115    const actual = shouldKeepParameter(node, config, mangledSymbolNames, checker);
116    assert.strictEqual(actual, false);
117  });
118
119  it('Tester 2-3: When node is parameter has no parent node, shouldKeepParameter returns false', function () {
120    let content = 'export declare function foo(para1: number): void';
121    const ast = ts.createSourceFile(path, content, ts.ScriptTarget.ES2015, true);
122    const customNode = ts.createParameter(undefined, undefined, 'a');
123    let mangledSymbolNames: Map<ts.Symbol, MangledSymbolInfo> = new Map<ts.Symbol, MangledSymbolInfo>();
124    const checker: ts.TypeChecker = TypeUtils.createChecker(ast);
125    const actual = shouldKeepParameter(customNode, config, mangledSymbolNames, checker);
126    assert.strictEqual(actual, false);
127  });
128
129  it('Tester 2-4: When node is parameter, shouldKeepParameter returns true', function () {
130    let content = 'export declare function foo(para1: number): void';
131    const ast = ts.createSourceFile(path, content, ts.ScriptTarget.ES2015, true);
132    let node = (ast.statements[0] as ts.FunctionDeclaration).parameters[0];
133    let mangledSymbolNames: Map<ts.Symbol, MangledSymbolInfo> = new Map<ts.Symbol, MangledSymbolInfo>();
134    const checker: ts.TypeChecker = TypeUtils.createChecker(ast);
135    const actual = shouldKeepParameter(node, config, mangledSymbolNames, checker);
136    assert.strictEqual(actual, true);
137  });
138
139  it('Tester 2-5: When node is TypeParameter, shouldKeepParameter returns true', function () {
140    let content = 'export declare function foo<T>(para1: number): void';
141    const ast = ts.createSourceFile(path, content, ts.ScriptTarget.ES2015, true);
142    let node = (ast.statements[0] as ts.FunctionDeclaration).typeParameters[0] as ts.TypeParameterDeclaration;
143    const checker: ts.TypeChecker = TypeUtils.createChecker(ast);
144    let mangledSymbolNames: Map<ts.Symbol, MangledSymbolInfo> = new Map<ts.Symbol, MangledSymbolInfo>();
145    const actual = shouldKeepParameter(node, config, mangledSymbolNames, checker);
146    assert.strictEqual(actual, true);
147  });
148
149  it('Tester 2-6: When node is parameter and function name is not kept, shouldKeepParameter returns false', function () {
150    let content = 'export declare function foo<T>(para1: number): void';
151    const ast = ts.createSourceFile(path, content, ts.ScriptTarget.ES2015, true);
152    let node: ts.ParameterDeclaration = (ast.statements[0] as ts.FunctionDeclaration).parameters[0];
153    const checker: ts.TypeChecker = TypeUtils.createChecker(ast);
154    const parentNode: ts.FunctionDeclaration = node.parent as ts.FunctionDeclaration;
155    assert.strictEqual(!!parentNode, true);
156    const functionName: ts.Identifier = parentNode.name as ts.Identifier;
157    assert.strictEqual(!!functionName, true);
158    const sym: ts.Symbol = NodeUtils.findSymbolOfIdentifier(checker, functionName, nodeSymbolMap) as ts.Symbol;
159    let mangledSymbolNames: Map<ts.Symbol, MangledSymbolInfo> = new Map<ts.Symbol, MangledSymbolInfo>();
160    mangledSymbolNames.set(sym, { mangledName: 'a', originalNameWithScope: '' });
161    const actual = shouldKeepParameter(node, config, mangledSymbolNames, checker);
162    assert.strictEqual(actual, false);
163  });
164
165  it('Tester 2-7: When node is parameter and function name is kept, shouldKeepParameter returns true', function () {
166    let content = 'export declare function foo<T>(para1: number): void';
167    const ast = ts.createSourceFile(path, content, ts.ScriptTarget.ES2015, true);
168    let node: ts.ParameterDeclaration = (ast.statements[0] as ts.FunctionDeclaration).parameters[0];
169    const checker: ts.TypeChecker = TypeUtils.createChecker(ast);
170    const parentNode: ts.FunctionDeclaration = node.parent as ts.FunctionDeclaration;
171    assert.strictEqual(!!parentNode, true);
172    const functionName: ts.Identifier = parentNode.name as ts.Identifier;
173    assert.strictEqual(!!functionName, true);
174    const sym: ts.Symbol = NodeUtils.findSymbolOfIdentifier(checker, functionName, nodeSymbolMap) as ts.Symbol;
175    let mangledSymbolNames: Map<ts.Symbol, MangledSymbolInfo> = new Map<ts.Symbol, MangledSymbolInfo>();
176    mangledSymbolNames.set(sym, { mangledName: 'foo', originalNameWithScope: '' });
177    const actual = shouldKeepParameter(node, config, mangledSymbolNames, checker);
178    assert.strictEqual(actual, true);
179  });
180
181  it('Tester 2-8: When node is parameter and function name is kept, shouldKeepParameter returns true', function () {
182    let content = 'export declare function foo<T>(para1: number): void';
183    const ast = ts.createSourceFile(path, content, ts.ScriptTarget.ES2015, true);
184    let node: ts.ParameterDeclaration = (ast.statements[0] as ts.FunctionDeclaration).parameters[0];
185    const checker: ts.TypeChecker = TypeUtils.createChecker(ast);
186    const parentNode: ts.FunctionDeclaration = node.parent as ts.FunctionDeclaration;
187    assert.strictEqual(!!parentNode, true);
188    const functionName: ts.Identifier = parentNode.name as ts.Identifier;
189    assert.strictEqual(!!functionName, true);
190    const sym: ts.Symbol = NodeUtils.findSymbolOfIdentifier(checker, functionName, nodeSymbolMap) as ts.Symbol;
191    let mangledSymbolNames: Map<ts.Symbol, MangledSymbolInfo> = new Map<ts.Symbol, MangledSymbolInfo>();
192    mangledSymbolNames.set(sym, { mangledName: 'foo', originalNameWithScope: '' });
193    const actual = shouldKeepParameter(node, config, mangledSymbolNames, checker);
194    assert.strictEqual(actual, true);
195  });
196
197  it('Tester 2-9: When node is method and property obf is not enabled, shouldKeepParameter returns true', function () {
198    let content = `declare class A {
199      constructor(para1: number);
200      method(para2: number): void;
201      }`;
202    const ast = ts.createSourceFile(path, content, ts.ScriptTarget.ES2015, true);
203    let method: ts.MethodDeclaration = (ast.statements[0] as ts.ClassDeclaration).members[1] as ts.MethodDeclaration;
204    let node: ts.ParameterDeclaration = method.parameters[0];
205    const checker: ts.TypeChecker = TypeUtils.createChecker(ast);
206    const methodName: ts.Identifier = method.name as ts.Identifier;
207    assert.strictEqual(!!methodName, true);
208    let mangledSymbolNames: Map<ts.Symbol, MangledSymbolInfo> = new Map<ts.Symbol, MangledSymbolInfo>();
209    const actual = shouldKeepParameter(node, config, mangledSymbolNames, checker);
210    assert.strictEqual(actual, true);
211  });
212
213  it('Tester 2-10: When node is method and method name is not kept, shouldKeepParameter returns false', function () {
214    let content = `declare class A {
215      constructor(para1: number);
216      method(para2: number): void;
217      }`;
218    const ast = ts.createSourceFile(path, content, ts.ScriptTarget.ES2015, true);
219    let method: ts.MethodDeclaration = (ast.statements[0] as ts.ClassDeclaration).members[1] as ts.MethodDeclaration;
220    let node: ts.ParameterDeclaration = method.parameters[0];
221    const checker: ts.TypeChecker = TypeUtils.createChecker(ast);
222    const methodName: ts.Identifier = method.name as ts.Identifier;
223    assert.strictEqual(!!methodName, true);
224    const customConfig: INameObfuscationOption = JSON.parse(JSON.stringify(config));
225    // @ts-ignore
226    customConfig['mRenameProperties'] = true;
227    let mangledSymbolNames: Map<ts.Symbol, MangledSymbolInfo> = new Map<ts.Symbol, MangledSymbolInfo>();
228    const actual = shouldKeepParameter(node, customConfig, mangledSymbolNames, checker);
229    assert.strictEqual(actual, false);
230  });
231
232  it('Tester 2-11: When node is method and method name is kept, shouldKeepParameter returns true', function () {
233    let content = `declare class A {
234      constructor(para1: number);
235      method(para2: number): void;
236      }`;
237    const ast = ts.createSourceFile(path, content, ts.ScriptTarget.ES2015, true);
238    let method: ts.MethodDeclaration = (ast.statements[0] as ts.ClassDeclaration).members[1] as ts.MethodDeclaration;
239    let node: ts.ParameterDeclaration = method.parameters[0];
240    const checker: ts.TypeChecker = TypeUtils.createChecker(ast);
241    const methodName: ts.Identifier = method.name as ts.Identifier;
242    assert.strictEqual(!!methodName, true);
243    let mangledSymbolNames: Map<ts.Symbol, MangledSymbolInfo> = new Map<ts.Symbol, MangledSymbolInfo>();
244    PropCollections.reservedProperties.add('method');
245    const customConfig: INameObfuscationOption = JSON.parse(JSON.stringify(config));
246    // @ts-ignore
247    customConfig['mRenameProperties'] = true;
248    const actual = shouldKeepParameter(node, customConfig, mangledSymbolNames, checker);
249    assert.strictEqual(actual, true);
250  });
251
252  it('Tester 2-12: When node is constructor and class name is not kept, shouldKeepParameter returns false', function () {
253    let content = `declare class A {
254      constructor(para1: number);
255      method(para2: number): void;
256      }`;
257    const ast = ts.createSourceFile(path, content, ts.ScriptTarget.ES2015, true);
258    let construcotr: ts.ConstructorDeclaration = (ast.statements[0] as ts.ClassDeclaration).members[0] as ts.ConstructorDeclaration;
259    let node: ts.ParameterDeclaration = construcotr.parameters[0];
260    assert.strictEqual(!!node, true);
261    const checker: ts.TypeChecker = TypeUtils.createChecker(ast);
262    const className: ts.Identifier = construcotr.parent.name as ts.Identifier;
263    assert.strictEqual(!!className, true);
264    const sym: ts.Symbol = NodeUtils.findSymbolOfIdentifier(checker, className, nodeSymbolMap) as ts.Symbol;
265    let mangledSymbolNames: Map<ts.Symbol, MangledSymbolInfo> = new Map<ts.Symbol, MangledSymbolInfo>();
266    mangledSymbolNames.set(sym, { mangledName: 'a', originalNameWithScope: '' });
267    const actual = shouldKeepParameter(node, config, mangledSymbolNames, checker);
268    assert.strictEqual(actual, false);
269  });
270
271  it('Tester 2-13: When node is constructor and class name is kept, shouldKeepParameter returns true', function () {
272    let content = `declare class A {
273      constructor(para1: number);
274      method(para2: number): void;
275      }`;
276    const ast = ts.createSourceFile(path, content, ts.ScriptTarget.ES2015, true);
277    let construcotr: ts.ConstructorDeclaration = (ast.statements[0] as ts.ClassDeclaration).members[0] as ts.ConstructorDeclaration;
278    const className: ts.Identifier = construcotr.parent.name as ts.Identifier;
279    assert.strictEqual(!!className, true);
280    let node: ts.ParameterDeclaration = construcotr.parameters[0];
281    const checker: ts.TypeChecker = TypeUtils.createChecker(ast);
282    const sym: ts.Symbol = NodeUtils.findSymbolOfIdentifier(checker, className, nodeSymbolMap) as ts.Symbol;
283    let mangledSymbolNames: Map<ts.Symbol, MangledSymbolInfo> = new Map<ts.Symbol, MangledSymbolInfo>();
284    mangledSymbolNames.set(sym, { mangledName: 'A', originalNameWithScope: '' });
285    const actual = shouldKeepParameter(node, config, mangledSymbolNames, checker);
286    assert.strictEqual(actual, true);
287  });
288
289  it('Tester 2-14: When node is MethodSignature, shouldKeepParameter returns false', function () {
290    let content = 'export declare function foo(para1: number): void';
291    const ast = ts.createSourceFile(path, content, ts.ScriptTarget.ES2015, true);
292    const customIdentifier = ts.createIdentifier('a1');
293    const customParaNode = ts.createParameter(undefined, undefined, customIdentifier);
294    // @ts-ignore
295    customIdentifier.parent = customParaNode;
296    const customMethodSig = ts.createMethodSignature(undefined, [customParaNode], undefined, '', undefined);
297    // @ts-ignore
298    customParaNode.parent = customMethodSig;
299    let mangledSymbolNames: Map<ts.Symbol, MangledSymbolInfo> = new Map<ts.Symbol, MangledSymbolInfo>();
300    const checker: ts.TypeChecker = TypeUtils.createChecker(ast);
301    const actual = shouldKeepParameter(customParaNode, config, mangledSymbolNames, checker);
302    assert.strictEqual(actual, false);
303  });
304
305  it('Tester 2-15: When node is method and name is stringType, shouldKeepParameter returns true', function () {
306    let content = `declare class A {
307      constructor(para1: number);
308      ['strProp'](para2: number): void;
309      }`;
310    const ast = ts.createSourceFile(path, content, ts.ScriptTarget.ES2015, true);
311    let method: ts.MethodDeclaration = (ast.statements[0] as ts.ClassDeclaration).members[1] as ts.MethodDeclaration;
312    let node: ts.ParameterDeclaration = method.parameters[0];
313    const checker: ts.TypeChecker = TypeUtils.createChecker(ast);
314    const methodName: ts.Identifier = method.name as ts.Identifier;
315    assert.strictEqual(!!methodName, true);
316    let mangledSymbolNames: Map<ts.Symbol, MangledSymbolInfo> = new Map<ts.Symbol, MangledSymbolInfo>();
317    PropCollections.reservedProperties.add('strProp');
318    const customConfig: INameObfuscationOption = JSON.parse(JSON.stringify(config));
319    // @ts-ignore
320    customConfig['mRenameProperties'] = true;
321    const actual = shouldKeepParameter(node, customConfig, mangledSymbolNames, checker);
322    assert.strictEqual(actual, true);
323  });
324
325  it('Tester 2-16: When node is method and the type is unexpected, shouldKeepParameter returns true', function () {
326    let content = `declare class A {
327      constructor(para1: number);
328      ['strProp' + 'prop'](para2: number): void;
329      }`;
330    const ast = ts.createSourceFile(path, content, ts.ScriptTarget.ES2015, false);
331    let method: ts.MethodDeclaration = (ast.statements[0] as ts.ClassDeclaration).members[1] as ts.MethodDeclaration;
332    let node: ts.ParameterDeclaration = method.parameters[0];
333    const checker: ts.TypeChecker = TypeUtils.createChecker(ast);
334    const methodName: ts.Identifier = method.name as ts.Identifier;
335    assert.strictEqual(!!methodName, true);
336    let mangledSymbolNames: Map<ts.Symbol, MangledSymbolInfo> = new Map<ts.Symbol, MangledSymbolInfo>();
337    PropCollections.reservedProperties.add('strProp');
338    const customConfig: INameObfuscationOption = JSON.parse(JSON.stringify(config));
339    // @ts-ignore
340    customConfig['mRenameProperties'] = true;
341    const actual = shouldKeepParameter(node, customConfig, mangledSymbolNames, checker);
342    assert.strictEqual(actual, false);
343  });
344});
345