From 2977c682ef5f9f62ff377b989199a17e41dbae6e Mon Sep 17 00:00:00 2001 From: zhangchen Date: Sun, 19 Nov 2023 16:11:58 +0800 Subject: [PATCH] Fix the error constructor parameter Signed-off-by: zhangchen Change-Id: I60bd314ae5cfcaaa6288f8d7ee40bb14f9147074 --- .../rename/RenameIdentifierTransformer.ts | 15 ++++---- arkguard/src/utils/OhsUtil.ts | 2 +- arkguard/src/utils/ScopeAnalyzer.ts | 34 +++++++++-------- .../constructor_property.ts | 37 +++++++++++++++++++ .../constructor_variables.ts | 37 +++++++++++++++++++ .../identifier_validation/obfConfig.json | 18 +++++++++ .../interface_demo_01-assert.ts | 2 +- 7 files changed, 120 insertions(+), 25 deletions(-) create mode 100644 arkguard/test/grammar/identifier_validation/constructor_property.ts create mode 100644 arkguard/test/grammar/identifier_validation/constructor_variables.ts create mode 100644 arkguard/test/grammar/identifier_validation/obfConfig.json diff --git a/arkguard/src/transformers/rename/RenameIdentifierTransformer.ts b/arkguard/src/transformers/rename/RenameIdentifierTransformer.ts index 412928c20a..b101e3e4a4 100644 --- a/arkguard/src/transformers/rename/RenameIdentifierTransformer.ts +++ b/arkguard/src/transformers/rename/RenameIdentifierTransformer.ts @@ -41,7 +41,8 @@ import { isGlobalScope, isEnumScope, isInterfaceScope, - isObjectLiteralScope + isObjectLiteralScope, + mangledIdentifierNames } from '../../utils/ScopeAnalyzer'; import type { @@ -153,8 +154,8 @@ namespace secharmony { function renameNamesInScope(scope: Scope): void { if (scope.parent) { - scope.parent.mangledNames.forEach((value) => { - scope.mangledNames.add(value); + mangledIdentifierNames.forEach((value) => { + mangledIdentifierNames.add(value); }); scope.parent.importNames.forEach((value) => { @@ -185,7 +186,7 @@ namespace secharmony { let mangled: string = original; // No allow to rename reserved names. if (reservedNames.includes(original) || scope.exportNames.has(def.name) || isSkippedGlobal(openTopLevel, scope)) { - scope.mangledNames.add(mangled); + mangledIdentifierNames.add(mangled); mangledSymbolNames.set(def, mangled); return; } @@ -206,7 +207,7 @@ namespace secharmony { // add new names to name cache nameCache.set(path, mangled); - scope.mangledNames.add(mangled); + mangledIdentifierNames.add(mangled); mangledSymbolNames.set(def, mangled); localCache.set(original, mangled); }); @@ -254,7 +255,7 @@ namespace secharmony { } // the anme has already been generated in the current scope - if (scope.mangledNames.has(mangled)) { + if (mangledIdentifierNames.has(mangled)) { mangled = ''; } } while (mangled === ''); @@ -337,7 +338,7 @@ namespace secharmony { const sym: Symbol | undefined = checker.getSymbolAtLocation(targetNode); if (!sym) { - scope.mangledNames.add((targetNode as Identifier).escapedText.toString()); + mangledIdentifierNames.add((targetNode as Identifier).escapedText.toString()); } }; diff --git a/arkguard/src/utils/OhsUtil.ts b/arkguard/src/utils/OhsUtil.ts index 2588197cf1..f729f7f026 100644 --- a/arkguard/src/utils/OhsUtil.ts +++ b/arkguard/src/utils/OhsUtil.ts @@ -249,7 +249,7 @@ export function getInterfaceProperties(interfaceNode: InterfaceDeclaration, prop }); } -function isParameterPropertyModifier(modifier: Modifier): boolean { +export function isParameterPropertyModifier(modifier: Modifier): boolean { if (modifier.kind === SyntaxKind.PublicKeyword || modifier.kind === SyntaxKind.PrivateKeyword || modifier.kind === SyntaxKind.ProtectedKeyword || diff --git a/arkguard/src/utils/ScopeAnalyzer.ts b/arkguard/src/utils/ScopeAnalyzer.ts index abb71ec030..8f6994aa9c 100644 --- a/arkguard/src/utils/ScopeAnalyzer.ts +++ b/arkguard/src/utils/ScopeAnalyzer.ts @@ -40,10 +40,12 @@ import type { ImportSpecifier, InterfaceDeclaration, LabeledStatement, + Modifier, ModuleDeclaration, Node, ObjectBindingPattern, ObjectLiteralExpression, + ParameterDeclaration, SourceFile, Symbol, SymbolTable, @@ -53,7 +55,7 @@ import type { } from 'typescript'; import {NodeUtils} from './NodeUtils'; -import {isViewPUBasedClass} from './OhsUtil'; +import {isParameterPropertyModifier, isViewPUBasedClass} from './OhsUtil'; /** * kind of a scope @@ -103,6 +105,7 @@ namespace secharmony { return scope.kind === ScopeKind.OBJECT_LITERAL; } + export const mangledIdentifierNames: Set = new Set(); /** * Structure of a scope */ @@ -151,8 +154,6 @@ namespace secharmony { exportNames?: Set; - mangledNames?: Set; - /** * add a sub scope to current scope * @@ -228,7 +229,6 @@ namespace secharmony { 'loc': loc, 'importNames': importNames, 'exportNames': exportNames, - 'mangledNames': mangledNames, addChild, addDefinition, addLabel, @@ -622,7 +622,7 @@ namespace secharmony { } /** - * exclude constructor's parameter witch should be treated as property, example: + * exclude constructor's parameter which should be treated as property, example: * constructor(public name){}, name should be treated as property * @param node */ @@ -631,18 +631,20 @@ namespace secharmony { return; } - const visitParam = (param: Node): void => { - if (isIdentifier(param)) { - current.defs.forEach((def) => { - if (def.name === param.text) { - current.defs.delete(def); - current.mangledNames.add(def.name); - } - }); + const visitParam = (param: ParameterDeclaration): void => { + const modifiers = param.modifiers; + if (modifiers && (modifiers.length > 0)) { + const hasParameterPropertyModifier: boolean = modifiers.find(modifier => isParameterPropertyModifier(modifier)) !== undefined; + if (isIdentifier(param.name) && hasParameterPropertyModifier) { + current.defs.forEach((def) => { + if (def.name === param.name.getText()) { + current.defs.delete(def); + mangledIdentifierNames.add(def.name); + } + }); + } } - - forEachChild(param, visitParam); - }; + } node.parameters.forEach((param) => { visitParam(param); diff --git a/arkguard/test/grammar/identifier_validation/constructor_property.ts b/arkguard/test/grammar/identifier_validation/constructor_property.ts new file mode 100644 index 0000000000..a12585a1e6 --- /dev/null +++ b/arkguard/test/grammar/identifier_validation/constructor_property.ts @@ -0,0 +1,37 @@ +// @target: es2015 +namespace ts { + let friendA: { getX(o: A): number, setX(o: A, v: number): void }; + + + class A { + x: number; + + constructor (v: number) { + this.x = v; + } + + getX () { + return this.x; + } + + obj() { + friendA = { + getX(obj) { return obj.x }, + setX(obj, value) { obj.x = value } + }; + } + }; + + class B { + constructor(public a: A, private x1: number = 1, protected x2: string = '', readonly x3: number = 2) { + const x = friendA.getX(a); // ok + + friendA.setX(a, x + 1); // ok + } + }; + + const a = new A(41); + a.obj(); + const b = new B(a); + a.getX(); +} \ No newline at end of file diff --git a/arkguard/test/grammar/identifier_validation/constructor_variables.ts b/arkguard/test/grammar/identifier_validation/constructor_variables.ts new file mode 100644 index 0000000000..715c9730cf --- /dev/null +++ b/arkguard/test/grammar/identifier_validation/constructor_variables.ts @@ -0,0 +1,37 @@ +// @target: es2015 +namespace ts { + let friendA: { getX(o: A): number, setX(o: A, v: number): void }; + + + class A { + x: number; + + constructor (v: number) { + this.x = v; + } + + getX () { + return this.x; + } + + obj() { + friendA = { + getX(obj) { return obj.x }, + setX(obj, value) { obj.x = value } + }; + } + }; + + class B { + constructor(a: A) { + const x = friendA.getX(a); // ok + + friendA.setX(a, x + 1); // ok + } + }; + + const a = new A(41); + a.obj(); + const b = new B(a); + a.getX(); +} \ No newline at end of file diff --git a/arkguard/test/grammar/identifier_validation/obfConfig.json b/arkguard/test/grammar/identifier_validation/obfConfig.json new file mode 100644 index 0000000000..218f100677 --- /dev/null +++ b/arkguard/test/grammar/identifier_validation/obfConfig.json @@ -0,0 +1,18 @@ +{ + "mCompact": false, + "mRemoveComments": false, + "mOutputDir": "../../local", + "mDisableHilog": false, + "mDisableConsole": false, + "mSimplify": false, + "mNameObfuscation": { + "mEnable": true, + "mNameGeneratorType": 1, + "mDictionaryList": [], + "mRenameProperties": false, + "mKeepStringProperty": false + }, + "mEnableSourceMap": false, + "mEnableNameCache": false, + "mTopLevel": false +} \ No newline at end of file diff --git a/arkguard/test/grammar/obfuscation_validation/interface_demo_01-assert.ts b/arkguard/test/grammar/obfuscation_validation/interface_demo_01-assert.ts index ec65d7e885..33d82bb5c2 100644 --- a/arkguard/test/grammar/obfuscation_validation/interface_demo_01-assert.ts +++ b/arkguard/test/grammar/obfuscation_validation/interface_demo_01-assert.ts @@ -29,7 +29,7 @@ export class class01 { classP12 = 3; }; get classP13() { return 1; } - set classP14(a) { } + set classP14(g) { } } export enum enum01 { enumP1, -- Gitee