mirror of
https://github.com/javascript-obfuscator/javascript-obfuscator
synced 2026-08-09 12:42:29 +00:00
Fixed https://github.com/javascript-obfuscator/javascript-obfuscator/issues/147
121 lines
4.0 KiB
TypeScript
121 lines
4.0 KiB
TypeScript
import { inject, injectable } from 'inversify';
|
|
import { ServiceIdentifiers } from '../../container/ServiceIdentifiers';
|
|
|
|
import { IOptions } from '../../interfaces/options/IOptions';
|
|
import { IRandomGenerator } from '../../interfaces/utils/IRandomGenerator';
|
|
|
|
import { AbstractIdentifierNamesGenerator } from './AbstractIdentifierNamesGenerator';
|
|
|
|
@injectable()
|
|
export class MangledIdentifierNamesGenerator extends AbstractIdentifierNamesGenerator {
|
|
/**
|
|
* @type {string}
|
|
*/
|
|
private static initMangledNameCharacter: string = '9';
|
|
|
|
/**
|
|
* @type {string[]}
|
|
*/
|
|
private static nameSequence: string[] = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'.split('');
|
|
|
|
/**
|
|
* Reserved JS words with length of 2-4 symbols that can be possible generated with this replacer
|
|
*
|
|
* @type {string[]}
|
|
*/
|
|
private static reservedNames: string[] = [
|
|
'byte', 'case', 'char', 'do', 'else', 'enum', 'eval', 'for', 'goto',
|
|
'if', 'in', 'int', 'let', 'long', 'new', 'null', 'this', 'true', 'try',
|
|
'var', 'void', 'with'
|
|
];
|
|
|
|
/**
|
|
* @type {string}
|
|
*/
|
|
private previousMangledName: string = MangledIdentifierNamesGenerator.initMangledNameCharacter;
|
|
|
|
/**
|
|
* @param {IRandomGenerator} randomGenerator
|
|
* @param {IOptions} options
|
|
*/
|
|
constructor (
|
|
@inject(ServiceIdentifiers.IRandomGenerator) randomGenerator: IRandomGenerator,
|
|
@inject(ServiceIdentifiers.IOptions) options: IOptions
|
|
) {
|
|
super(randomGenerator, options);
|
|
}
|
|
|
|
/**
|
|
* @param {string} previousMangledName
|
|
* @returns {string}
|
|
*/
|
|
private static generateNewMangledName (previousMangledName: string): string {
|
|
const generateNewMangledName: (name: string) => string = (name: string): string => {
|
|
const nameSequence: string[] = MangledIdentifierNamesGenerator.nameSequence;
|
|
const zeroSequenceCache: string[] = [];
|
|
const nameLength: number = name.length;
|
|
|
|
const zeroSequence: (num: number) => string = (num: number): string => {
|
|
let result: string = zeroSequenceCache[num];
|
|
|
|
if (result !== undefined) {
|
|
return result;
|
|
}
|
|
|
|
result = '0'.repeat(num);
|
|
zeroSequenceCache[num] = result;
|
|
|
|
return result;
|
|
};
|
|
|
|
let index: number = nameLength - 1;
|
|
|
|
do {
|
|
const character: string = name.charAt(index);
|
|
const indexInSequence: number = nameSequence.indexOf(character);
|
|
const lastNameSequenceIndex: number = nameSequence.length - 1;
|
|
|
|
if (indexInSequence !== lastNameSequenceIndex) {
|
|
const previousNamePart: string = name.substring(0, index);
|
|
const nextCharacter: string = nameSequence[indexInSequence + 1];
|
|
const zeroSequenceCharacters: string = zeroSequence(nameLength - (index + 1));
|
|
|
|
return previousNamePart + nextCharacter + zeroSequenceCharacters;
|
|
}
|
|
|
|
--index;
|
|
} while (index >= 0);
|
|
|
|
return `a${zeroSequence(nameLength)}`;
|
|
};
|
|
|
|
let newMangledName: string = generateNewMangledName(previousMangledName);
|
|
|
|
if (!MangledIdentifierNamesGenerator.validateMangledName(newMangledName)) {
|
|
newMangledName = MangledIdentifierNamesGenerator.generateNewMangledName(newMangledName);
|
|
}
|
|
|
|
return newMangledName;
|
|
}
|
|
|
|
/**
|
|
* @param {string} mangledName
|
|
* @returns {boolean}
|
|
*/
|
|
private static validateMangledName (mangledName: string): boolean {
|
|
return !MangledIdentifierNamesGenerator.reservedNames.includes(mangledName);
|
|
}
|
|
|
|
/**
|
|
* @param {number} length
|
|
* @returns {string}
|
|
*/
|
|
public generate (length: number): string {
|
|
const newName: string = MangledIdentifierNamesGenerator.generateNewMangledName(this.previousMangledName);
|
|
|
|
this.previousMangledName = newName;
|
|
|
|
return newName;
|
|
}
|
|
}
|