mirror of
https://github.com/javascript-obfuscator/javascript-obfuscator
synced 2026-08-09 12:42:29 +00:00
Added additional self defending mechanisms. Updated tests
This commit is contained in:
@@ -84,6 +84,7 @@
|
||||
"rimraf": "3.0.2",
|
||||
"sinon": "11.1.1",
|
||||
"source-map-resolve": "0.6.0",
|
||||
"terser": "^5.7.1",
|
||||
"threads": "1.6.5",
|
||||
"ts-loader": "9.2.3",
|
||||
"ts-node": "10.1.0",
|
||||
|
||||
@@ -13,9 +13,12 @@ export class StringArrayCallsWrapperBase64CodeHelper extends StringArrayCallsWra
|
||||
protected override getDecodeStringArrayTemplate (): string {
|
||||
const atobFunctionName: string = this.randomGenerator.getRandomString(6);
|
||||
|
||||
const atobPolyfill: string = this.customCodeHelperFormatter.formatTemplate(AtobTemplate(), {
|
||||
atobFunctionName: atobFunctionName
|
||||
});
|
||||
const atobPolyfill: string = this.customCodeHelperFormatter.formatTemplate(
|
||||
AtobTemplate(this.options.selfDefending),
|
||||
{
|
||||
atobFunctionName: atobFunctionName
|
||||
}
|
||||
);
|
||||
|
||||
const selfDefendingCode: string = this.getSelfDefendingTemplate();
|
||||
|
||||
|
||||
@@ -15,13 +15,19 @@ export class StringArrayCallsWrapperRc4CodeHelper extends StringArrayCallsWrappe
|
||||
const atobFunctionName: string = this.randomGenerator.getRandomString(6);
|
||||
const rc4FunctionName: string = this.randomGenerator.getRandomString(6);
|
||||
|
||||
const atobPolyfill: string = this.customCodeHelperFormatter.formatTemplate(AtobTemplate(), {
|
||||
atobFunctionName
|
||||
});
|
||||
const rc4Polyfill: string = this.customCodeHelperFormatter.formatTemplate(Rc4Template(), {
|
||||
atobFunctionName,
|
||||
rc4FunctionName
|
||||
});
|
||||
const atobPolyfill: string = this.customCodeHelperFormatter.formatTemplate(
|
||||
AtobTemplate(this.options.selfDefending),
|
||||
{
|
||||
atobFunctionName
|
||||
}
|
||||
);
|
||||
const rc4Polyfill: string = this.customCodeHelperFormatter.formatTemplate(
|
||||
Rc4Template(),
|
||||
{
|
||||
atobFunctionName,
|
||||
rc4FunctionName
|
||||
}
|
||||
);
|
||||
|
||||
const selfDefendingCode: string = this.getSelfDefendingTemplate();
|
||||
|
||||
|
||||
+11
-3
@@ -5,19 +5,27 @@ import { base64alphabetSwapped } from '../../../../constants/Base64AlphabetSwapp
|
||||
*
|
||||
* @returns {string}
|
||||
*/
|
||||
export function AtobTemplate (): string {
|
||||
export function AtobTemplate (selfDefending: boolean): string {
|
||||
return `
|
||||
var {atobFunctionName} = function (input) {
|
||||
const chars = '${base64alphabetSwapped}';
|
||||
|
||||
let output = '';
|
||||
let tempEncodedString = '';
|
||||
${selfDefending ? 'let func = output + {atobFunctionName};' : ''}
|
||||
|
||||
for (
|
||||
let bc = 0, bs, buffer, idx = 0;
|
||||
buffer = input.charAt(idx++);
|
||||
~buffer && (bs = bc % 4 ? bs * 64 + buffer : buffer,
|
||||
bc++ % 4) ? output += String.fromCharCode(255 & bs >> (-2 * bc & 6)) : 0
|
||||
~buffer && (bs = bc % 4 ? bs * 64 + buffer : buffer, bc++ % 4)
|
||||
? output += ${((): string => {
|
||||
const basePart: string = 'String.fromCharCode(255 & bs >> (-2 * bc & 6))';
|
||||
|
||||
return selfDefending
|
||||
? `(func.charCodeAt(idx + 10) - 10 ? ${basePart} : bc)`
|
||||
: basePart;
|
||||
})()}
|
||||
: 0
|
||||
) {
|
||||
buffer = chars.indexOf(buffer);
|
||||
}
|
||||
|
||||
+2
-1
@@ -37,7 +37,8 @@ import { NO_ADDITIONAL_NODES_PRESET } from '../../src/options/presets/NoCustomNo
|
||||
stringArrayEncoding: ['rc4', 'base64'],
|
||||
stringArrayWrappersCount: 5,
|
||||
rotateStringArray: true,
|
||||
identifierNamesGenerator: 'mangled'
|
||||
identifierNamesGenerator: 'mangled',
|
||||
selfDefending: true
|
||||
}
|
||||
).getObfuscatedCode();
|
||||
|
||||
|
||||
+3
-2
@@ -2,6 +2,7 @@ import { assert } from 'chai';
|
||||
|
||||
import { NO_ADDITIONAL_NODES_PRESET } from '../../../../../src/options/presets/NoCustomNodes';
|
||||
|
||||
import { getStringArrayRegExp } from '../../../../helpers/get-string-array-regexp';
|
||||
import { readFileAsString } from '../../../../helpers/readFileAsString';
|
||||
|
||||
import { JavaScriptObfuscator } from '../../../../../src/JavaScriptObfuscatorFacade';
|
||||
@@ -59,8 +60,8 @@ describe('HashbangOperatorTransformer', () => {
|
||||
|
||||
describe('Variant #3: `stringArray` option enabled', () => {
|
||||
const regExp: RegExp = new RegExp(
|
||||
`^#!\/usr\/bin\/env node${lineSeparator}` +
|
||||
`var _0x(\\w){4} *= *\\['abc'];`
|
||||
`^#!\/usr\/bin\/env node${lineSeparator}.*` +
|
||||
`${getStringArrayRegExp(['abc']).source}`
|
||||
);
|
||||
|
||||
let obfuscatedCode: string;
|
||||
|
||||
+4
-3
@@ -56,9 +56,10 @@ describe('StringArrayCallsWrapperCodeHelper', () => {
|
||||
describe('Preserve string array name', () => {
|
||||
const callsWrapperRegExp: RegExp = new RegExp(`` +
|
||||
`function *b *\\(c, *d\\) *{ *` +
|
||||
`b *= *function *\\(e, *f\\) *{` +
|
||||
`e *= *e *- *0x0; *` +
|
||||
`var g *= *a\\[e]; *` +
|
||||
`var e *= *a\\(\\); *` +
|
||||
`b *= *function *\\(f, *g\\) *{` +
|
||||
`f *= *f *- *0x0; *` +
|
||||
`var h *= *e\\[f]; *` +
|
||||
``);
|
||||
|
||||
let obfuscatedCode: string;
|
||||
|
||||
+2
-1
@@ -2,12 +2,13 @@ import { assert } from 'chai';
|
||||
|
||||
import { NO_ADDITIONAL_NODES_PRESET } from '../../../../src/options/presets/NoCustomNodes';
|
||||
|
||||
import { getStringArrayRegExp } from '../../../helpers/get-string-array-regexp';
|
||||
import { readFileAsString } from '../../../helpers/readFileAsString';
|
||||
|
||||
import { JavaScriptObfuscator } from '../../../../src/JavaScriptObfuscatorFacade';
|
||||
|
||||
describe('StringArrayCodeHelper', () => {
|
||||
const regExp: RegExp = /^var _0x([a-f0-9]){4} *= *\[/;
|
||||
const regExp: RegExp = getStringArrayRegExp(['test']);
|
||||
|
||||
describe('`stringArray` option is set', () => {
|
||||
let obfuscatedCode: string;
|
||||
|
||||
+2
-2
@@ -84,8 +84,8 @@ describe('StringArrayRotateFunctionCodeHelper', () => {
|
||||
});
|
||||
|
||||
describe('Preserve string array name', () => {
|
||||
const arrayRotateRegExp: RegExp = /c\['push']\(c\['shift']\(\)\);/;
|
||||
const comparisonRegExp: RegExp = /if *\(e *=== *d\) *{/;
|
||||
const arrayRotateRegExp: RegExp = /e\['push']\(e\['shift']\(\)\);/;
|
||||
const comparisonRegExp: RegExp = /if *\(f *=== *d\) *{/;
|
||||
|
||||
let obfuscatedCode: string;
|
||||
|
||||
|
||||
+36
-18
@@ -5,41 +5,59 @@ import { IdentifierNamesGenerator } from '../../../../../src/enums/generators/id
|
||||
|
||||
import { NO_ADDITIONAL_NODES_PRESET } from '../../../../../src/options/presets/NoCustomNodes';
|
||||
|
||||
import { getRegExpMatch } from '../../../../helpers/getRegExpMatch';
|
||||
import { readFileAsString } from '../../../../helpers/readFileAsString';
|
||||
|
||||
import { JavaScriptObfuscator } from '../../../../../src/JavaScriptObfuscatorFacade';
|
||||
|
||||
describe('StringArrayCodeHelperGroup', () => {
|
||||
const regExp: RegExp = new RegExp(
|
||||
'function *b *\\(\\w, *\\w\\) *{.*return \\w;}.*' +
|
||||
'function *c *\\(\\w, *\\w\\) *{.*return \\w;}.*' +
|
||||
'function *d *\\(\\w, *\\w\\) *{.*return \\w;}'
|
||||
'function *\\w *\\(\\w, *\\w\\) *{.*return \\w;}.*' +
|
||||
'function *\\w *\\(\\w, *\\w\\) *{.*return \\w;}.*' +
|
||||
'function *\\w *\\(\\w, *\\w\\) *{.*return \\w;}'
|
||||
);
|
||||
const stringArrayCallsWrapperRegExp: RegExp = new RegExp(
|
||||
`function *(\\w) *\\(\\w, *\\w\\) *{.*return \\w;}.*`
|
||||
);
|
||||
|
||||
describe('StringArrayCallsWrapper code helper names', () => {
|
||||
const stringArrayCallsWrapperNames: Set<string> = new Set();
|
||||
const samplesCount: number = 30;
|
||||
let obfuscatedCode: string;
|
||||
|
||||
const expectedUniqStringArrayCallsWrapperNamesCount: number = 3;
|
||||
|
||||
before(() => {
|
||||
const code: string = readFileAsString(__dirname + '/fixtures/simple-input.js');
|
||||
|
||||
obfuscatedCode = JavaScriptObfuscator.obfuscate(
|
||||
code,
|
||||
{
|
||||
...NO_ADDITIONAL_NODES_PRESET,
|
||||
identifierNamesGenerator: IdentifierNamesGenerator.MangledIdentifierNamesGenerator,
|
||||
stringArray: true,
|
||||
stringArrayThreshold: 1,
|
||||
stringArrayEncoding: [
|
||||
StringArrayEncoding.None,
|
||||
StringArrayEncoding.Base64,
|
||||
StringArrayEncoding.Rc4
|
||||
]
|
||||
}
|
||||
).getObfuscatedCode();
|
||||
for (let i = 0; i < samplesCount; i++) {
|
||||
obfuscatedCode = JavaScriptObfuscator.obfuscate(
|
||||
code,
|
||||
{
|
||||
...NO_ADDITIONAL_NODES_PRESET,
|
||||
identifierNamesGenerator: IdentifierNamesGenerator.MangledIdentifierNamesGenerator,
|
||||
stringArray: true,
|
||||
stringArrayThreshold: 1,
|
||||
stringArrayEncoding: [
|
||||
StringArrayEncoding.None,
|
||||
StringArrayEncoding.Base64,
|
||||
StringArrayEncoding.Rc4
|
||||
]
|
||||
}
|
||||
).getObfuscatedCode();
|
||||
|
||||
const callsWrapperName: string = getRegExpMatch(obfuscatedCode, stringArrayCallsWrapperRegExp);
|
||||
|
||||
stringArrayCallsWrapperNames.add(callsWrapperName);
|
||||
}
|
||||
});
|
||||
|
||||
it('should place multiple StringArrayCallsWrapper code helper names in the correct order', () => {
|
||||
it('should correct place all StringArrayCallsWrapper code helpers', () => {
|
||||
assert.match(obfuscatedCode, regExp);
|
||||
});
|
||||
|
||||
it('should place multiple StringArrayCallsWrapper code helper names in the random order', () => {
|
||||
assert.equal(stringArrayCallsWrapperNames.size, expectedUniqStringArrayCallsWrapperNamesCount);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
+459
-189
@@ -16,16 +16,19 @@ import { Rc4Template } from '../../../../../../src/custom-code-helpers/string-ar
|
||||
import { StringArrayBase64DecodeTemplate } from '../../../../../../src/custom-code-helpers/string-array/templates/string-array-calls-wrapper/StringArrayBase64DecodeTemplate';
|
||||
import { StringArrayCallsWrapperTemplate } from '../../../../../../src/custom-code-helpers/string-array/templates/string-array-calls-wrapper/StringArrayCallsWrapperTemplate';
|
||||
import { StringArrayRC4DecodeTemplate } from '../../../../../../src/custom-code-helpers/string-array/templates/string-array-calls-wrapper/StringArrayRC4DecodeTemplate';
|
||||
import { StringArrayTemplate } from '../../../../../../src/custom-code-helpers/string-array/templates/string-array/StringArrayTemplate';
|
||||
|
||||
import { NO_ADDITIONAL_NODES_PRESET } from '../../../../../../src/options/presets/NoCustomNodes';
|
||||
|
||||
import { InversifyContainerFacade } from '../../../../../../src/container/InversifyContainerFacade';
|
||||
import { JavaScriptObfuscator } from '../../../../../../src/JavaScriptObfuscatorFacade';
|
||||
import { minimizeCode } from '../../../../../helpers/minimizeCode';
|
||||
import { readFileAsString } from '../../../../../helpers/readFileAsString';
|
||||
import { swapLettersCase } from '../../../../../helpers/swapLettersCase';
|
||||
|
||||
describe('StringArrayCallsWrapperTemplate', () => {
|
||||
const stringArrayName: string = 'stringArrayName';
|
||||
const stringArrayFunctionName: string = 'stringArrayFunctionName';
|
||||
const stringArrayCallsWrapperName: string = 'stringArrayCallsWrapperName';
|
||||
const stringArrayCacheName: string = 'stringArrayCache';
|
||||
const atobFunctionName: string = 'atob';
|
||||
@@ -45,243 +48,510 @@ describe('StringArrayCallsWrapperTemplate', () => {
|
||||
});
|
||||
|
||||
describe('Variant #1: `base64` encoding', () => {
|
||||
describe('Variant #1: index shift amount is `0`', () => {
|
||||
const index: string = '0x0';
|
||||
describe('Variant #1: `selfDefending` option is disabled', () => {
|
||||
const selfDefendingEnabled: boolean = false;
|
||||
|
||||
const indexShiftAmount: number = 0;
|
||||
describe('Variant #1: index shift amount is `0`', () => {
|
||||
const index: string = '0x0';
|
||||
|
||||
const expectedDecodedValue: string = 'test1';
|
||||
const indexShiftAmount: number = 0;
|
||||
|
||||
let decodedValue: string;
|
||||
const expectedDecodedValue: string = 'test1';
|
||||
|
||||
before(() => {
|
||||
const atobPolyfill = format(AtobTemplate(), {
|
||||
atobFunctionName
|
||||
});
|
||||
const atobDecodeTemplate: string = format(
|
||||
StringArrayBase64DecodeTemplate(randomGenerator),
|
||||
{
|
||||
atobPolyfill,
|
||||
atobFunctionName,
|
||||
selfDefendingCode: '',
|
||||
let decodedValue: string;
|
||||
|
||||
before(() => {
|
||||
const stringArrayTemplate = format(StringArrayTemplate(), {
|
||||
stringArrayName,
|
||||
stringArrayFunctionName,
|
||||
stringArrayStorageItems: `'${cryptUtilsSwappedAlphabet.btoa('test1')}'`
|
||||
});
|
||||
const atobPolyfill = format(AtobTemplate(selfDefendingEnabled), {
|
||||
atobFunctionName
|
||||
});
|
||||
const atobDecodeTemplate: string = format(
|
||||
StringArrayBase64DecodeTemplate(randomGenerator),
|
||||
{
|
||||
atobPolyfill,
|
||||
atobFunctionName,
|
||||
selfDefendingCode: '',
|
||||
stringArrayCacheName,
|
||||
stringArrayCallsWrapperName
|
||||
}
|
||||
);
|
||||
const stringArrayCallsWrapperTemplate: string = format(StringArrayCallsWrapperTemplate(), {
|
||||
decodeCodeHelperTemplate: atobDecodeTemplate,
|
||||
indexShiftAmount,
|
||||
stringArrayCacheName,
|
||||
stringArrayCallsWrapperName
|
||||
}
|
||||
);
|
||||
const stringArrayCallsWrapperTemplate: string = format(StringArrayCallsWrapperTemplate(), {
|
||||
decodeCodeHelperTemplate: atobDecodeTemplate,
|
||||
indexShiftAmount,
|
||||
stringArrayCacheName,
|
||||
stringArrayCallsWrapperName,
|
||||
stringArrayName
|
||||
stringArrayCallsWrapperName,
|
||||
stringArrayFunctionName
|
||||
});
|
||||
|
||||
decodedValue = Function(`
|
||||
${stringArrayTemplate}
|
||||
|
||||
${stringArrayCallsWrapperTemplate}
|
||||
|
||||
return ${stringArrayCallsWrapperName}(${index});
|
||||
`)();
|
||||
});
|
||||
|
||||
decodedValue = Function(`
|
||||
var ${stringArrayName} = ['${cryptUtilsSwappedAlphabet.btoa('test1')}'];
|
||||
|
||||
${stringArrayCallsWrapperTemplate}
|
||||
|
||||
return ${stringArrayCallsWrapperName}(${index});
|
||||
`)();
|
||||
it('should correctly return decoded value', () => {
|
||||
assert.deepEqual(decodedValue, expectedDecodedValue);
|
||||
});
|
||||
});
|
||||
|
||||
it('should correctly return decoded value', () => {
|
||||
assert.deepEqual(decodedValue, expectedDecodedValue);
|
||||
describe('Variant #2: index shift amount is `5`', () => {
|
||||
const index: string = '0x5';
|
||||
|
||||
const indexShiftAmount: number = 5;
|
||||
|
||||
const expectedDecodedValue: string = 'test1';
|
||||
|
||||
let decodedValue: string;
|
||||
|
||||
before(() => {
|
||||
const stringArrayTemplate = format(StringArrayTemplate(), {
|
||||
stringArrayName,
|
||||
stringArrayFunctionName,
|
||||
stringArrayStorageItems: `'${cryptUtilsSwappedAlphabet.btoa('test1')}'`
|
||||
});
|
||||
const atobPolyfill = format(AtobTemplate(selfDefendingEnabled), {
|
||||
atobFunctionName
|
||||
});
|
||||
const atobDecodeTemplate: string = format(
|
||||
StringArrayBase64DecodeTemplate(randomGenerator),
|
||||
{
|
||||
atobPolyfill,
|
||||
atobFunctionName,
|
||||
selfDefendingCode: '',
|
||||
stringArrayCacheName,
|
||||
stringArrayCallsWrapperName
|
||||
}
|
||||
);
|
||||
const stringArrayCallsWrapperTemplate: string = format(StringArrayCallsWrapperTemplate(), {
|
||||
decodeCodeHelperTemplate: atobDecodeTemplate,
|
||||
indexShiftAmount,
|
||||
stringArrayCacheName,
|
||||
stringArrayCallsWrapperName,
|
||||
stringArrayFunctionName
|
||||
});
|
||||
|
||||
decodedValue = Function(`
|
||||
${stringArrayTemplate}
|
||||
|
||||
${stringArrayCallsWrapperTemplate}
|
||||
|
||||
return ${stringArrayCallsWrapperName}(${index});
|
||||
`)();
|
||||
});
|
||||
|
||||
it('should correctly return decoded value', () => {
|
||||
assert.deepEqual(decodedValue, expectedDecodedValue);
|
||||
});
|
||||
});
|
||||
|
||||
describe('Variant #3: no regexp inside atob template', () => {
|
||||
const indexShiftAmount: number = 0;
|
||||
|
||||
const expectedRegExpTestValue: string = '12345';
|
||||
|
||||
let decodedValue: string;
|
||||
|
||||
before(() => {
|
||||
const stringArrayTemplate = format(StringArrayTemplate(), {
|
||||
stringArrayName,
|
||||
stringArrayFunctionName,
|
||||
stringArrayStorageItems: `'${swapLettersCase('c3RyaQ==')}'`
|
||||
});
|
||||
const atobPolyfill = format(AtobTemplate(selfDefendingEnabled), {
|
||||
atobFunctionName
|
||||
});
|
||||
const atobDecodeTemplate: string = format(
|
||||
StringArrayBase64DecodeTemplate(randomGenerator),
|
||||
{
|
||||
atobPolyfill,
|
||||
atobFunctionName,
|
||||
selfDefendingCode: '',
|
||||
stringArrayCacheName,
|
||||
stringArrayCallsWrapperName
|
||||
}
|
||||
);
|
||||
const stringArrayCallsWrapperTemplate: string = format(StringArrayCallsWrapperTemplate(), {
|
||||
decodeCodeHelperTemplate: atobDecodeTemplate,
|
||||
indexShiftAmount,
|
||||
stringArrayCacheName,
|
||||
stringArrayCallsWrapperName,
|
||||
stringArrayFunctionName
|
||||
});
|
||||
|
||||
decodedValue = Function(`
|
||||
${stringArrayTemplate}
|
||||
|
||||
${stringArrayCallsWrapperTemplate}
|
||||
|
||||
/(.+)/.test("12345");
|
||||
${stringArrayCallsWrapperName}(0x0);
|
||||
|
||||
return RegExp.$1;
|
||||
`)();
|
||||
});
|
||||
|
||||
it('should correctly return RegExp.$1 match without mutation by atob template', () => {
|
||||
assert.deepEqual(decodedValue, expectedRegExpTestValue);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('Variant #2: index shift amount is `5`', () => {
|
||||
const index: string = '0x5';
|
||||
describe('Variant #2: `selfDefending` option is enabled', () => {
|
||||
const selfDefendingEnabled: boolean = true;
|
||||
|
||||
const indexShiftAmount: number = 5;
|
||||
describe('Variant #1: correct code evaluation for single-line code', () => {
|
||||
describe('Variant #1: index shift amount is `0`', () => {
|
||||
const index: string = '0x0';
|
||||
|
||||
const expectedDecodedValue: string = 'test1';
|
||||
const indexShiftAmount: number = 0;
|
||||
|
||||
let decodedValue: string;
|
||||
const expectedDecodedValue: string = 'test1test1';
|
||||
|
||||
before(() => {
|
||||
const atobPolyfill = format(AtobTemplate(), {
|
||||
atobFunctionName
|
||||
let decodedValue: string;
|
||||
|
||||
before(async() => {
|
||||
const stringArrayTemplate = format(StringArrayTemplate(), {
|
||||
stringArrayName,
|
||||
stringArrayFunctionName,
|
||||
stringArrayStorageItems: `'${cryptUtilsSwappedAlphabet.btoa('test1test1')}'`
|
||||
});
|
||||
const atobPolyfill = format(AtobTemplate(selfDefendingEnabled), {
|
||||
atobFunctionName
|
||||
});
|
||||
const atobDecodeTemplate: string = format(
|
||||
StringArrayBase64DecodeTemplate(randomGenerator),
|
||||
{
|
||||
atobPolyfill,
|
||||
atobFunctionName,
|
||||
selfDefendingCode: '',
|
||||
stringArrayCacheName,
|
||||
stringArrayCallsWrapperName
|
||||
}
|
||||
);
|
||||
const stringArrayCallsWrapperTemplate: string = await minimizeCode(
|
||||
format(StringArrayCallsWrapperTemplate(), {
|
||||
decodeCodeHelperTemplate: atobDecodeTemplate,
|
||||
indexShiftAmount,
|
||||
stringArrayCacheName,
|
||||
stringArrayCallsWrapperName,
|
||||
stringArrayFunctionName
|
||||
})
|
||||
);
|
||||
|
||||
decodedValue = Function(`
|
||||
${stringArrayTemplate}
|
||||
|
||||
${stringArrayCallsWrapperTemplate}
|
||||
|
||||
return ${stringArrayCallsWrapperName}(${index});
|
||||
`)();
|
||||
});
|
||||
|
||||
it('should correctly return decoded value', () => {
|
||||
assert.deepEqual(decodedValue, expectedDecodedValue);
|
||||
});
|
||||
});
|
||||
const atobDecodeTemplate: string = format(
|
||||
StringArrayBase64DecodeTemplate(randomGenerator),
|
||||
{
|
||||
atobPolyfill,
|
||||
atobFunctionName,
|
||||
selfDefendingCode: '',
|
||||
stringArrayCacheName,
|
||||
stringArrayCallsWrapperName
|
||||
}
|
||||
);
|
||||
const stringArrayCallsWrapperTemplate: string = format(StringArrayCallsWrapperTemplate(), {
|
||||
decodeCodeHelperTemplate: atobDecodeTemplate,
|
||||
indexShiftAmount,
|
||||
stringArrayCacheName,
|
||||
stringArrayCallsWrapperName,
|
||||
stringArrayName
|
||||
});
|
||||
|
||||
decodedValue = Function(`
|
||||
var ${stringArrayName} = ['${cryptUtilsSwappedAlphabet.btoa('test1')}'];
|
||||
|
||||
${stringArrayCallsWrapperTemplate}
|
||||
|
||||
return ${stringArrayCallsWrapperName}(${index});
|
||||
`)();
|
||||
});
|
||||
|
||||
it('should correctly return decoded value', () => {
|
||||
assert.deepEqual(decodedValue, expectedDecodedValue);
|
||||
});
|
||||
});
|
||||
describe('Variant #2: invalid code evaluation for multi-line code', () => {
|
||||
describe('Variant #1: index shift amount is `0`', () => {
|
||||
const index: string = '0x0';
|
||||
|
||||
describe('Variant #3: no regexp inside atob template', () => {
|
||||
const indexShiftAmount: number = 0;
|
||||
const indexShiftAmount: number = 0;
|
||||
|
||||
const expectedRegExpTestValue: string = '12345';
|
||||
const expectedDecodedValue: string = 'test18est1';
|
||||
|
||||
let decodedValue: string;
|
||||
let decodedValue: string;
|
||||
|
||||
before(() => {
|
||||
const atobPolyfill = format(AtobTemplate(), {
|
||||
atobFunctionName
|
||||
before(() => {
|
||||
const stringArrayTemplate = format(StringArrayTemplate(), {
|
||||
stringArrayName,
|
||||
stringArrayFunctionName,
|
||||
stringArrayStorageItems: `'${cryptUtilsSwappedAlphabet.btoa('test1test1')}'`
|
||||
});
|
||||
const atobPolyfill = format(AtobTemplate(selfDefendingEnabled), {
|
||||
atobFunctionName
|
||||
});
|
||||
const atobDecodeTemplate: string = format(
|
||||
StringArrayBase64DecodeTemplate(randomGenerator),
|
||||
{
|
||||
atobPolyfill,
|
||||
atobFunctionName,
|
||||
selfDefendingCode: '',
|
||||
stringArrayCacheName,
|
||||
stringArrayCallsWrapperName
|
||||
}
|
||||
);
|
||||
const stringArrayCallsWrapperTemplate: string = format(StringArrayCallsWrapperTemplate(), {
|
||||
decodeCodeHelperTemplate: atobDecodeTemplate,
|
||||
indexShiftAmount,
|
||||
stringArrayCacheName,
|
||||
stringArrayCallsWrapperName,
|
||||
stringArrayFunctionName
|
||||
});
|
||||
|
||||
decodedValue = Function(`
|
||||
${stringArrayTemplate}
|
||||
|
||||
${stringArrayCallsWrapperTemplate}
|
||||
|
||||
return ${stringArrayCallsWrapperName}(${index});
|
||||
`)();
|
||||
});
|
||||
|
||||
it('should correctly return decoded value', () => {
|
||||
assert.deepEqual(decodedValue, expectedDecodedValue);
|
||||
});
|
||||
});
|
||||
const atobDecodeTemplate: string = format(
|
||||
StringArrayBase64DecodeTemplate(randomGenerator),
|
||||
{
|
||||
atobPolyfill,
|
||||
atobFunctionName,
|
||||
selfDefendingCode: '',
|
||||
stringArrayCacheName,
|
||||
stringArrayCallsWrapperName
|
||||
}
|
||||
);
|
||||
const stringArrayCallsWrapperTemplate: string = format(StringArrayCallsWrapperTemplate(), {
|
||||
decodeCodeHelperTemplate: atobDecodeTemplate,
|
||||
indexShiftAmount,
|
||||
stringArrayCacheName,
|
||||
stringArrayCallsWrapperName,
|
||||
stringArrayName
|
||||
});
|
||||
|
||||
decodedValue = Function(`
|
||||
var ${stringArrayName} = ['${swapLettersCase('c3RyaQ==')}'];
|
||||
|
||||
${stringArrayCallsWrapperTemplate}
|
||||
|
||||
/(.+)/.test("12345");
|
||||
${stringArrayCallsWrapperName}(0x0);
|
||||
|
||||
return RegExp.$1;
|
||||
`)();
|
||||
});
|
||||
|
||||
it('should correctly return RegExp.$1 match without mutation by atob template', () => {
|
||||
assert.deepEqual(decodedValue, expectedRegExpTestValue);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('Variant #2: `rc4` encoding', () => {
|
||||
describe('Variant #1: index shift amount is `0`', () => {
|
||||
const index: string = '0x0';
|
||||
const key: string = 'key';
|
||||
describe('Variant #1: `selfDefending` option is disabled', () => {
|
||||
const selfDefendingEnabled: boolean = false;
|
||||
|
||||
const indexShiftAmount: number = 0;
|
||||
describe('Variant #1: index shift amount is `0`', () => {
|
||||
const index: string = '0x0';
|
||||
const key: string = 'key';
|
||||
|
||||
const expectedDecodedValue: string = 'test1';
|
||||
const indexShiftAmount: number = 0;
|
||||
|
||||
let decodedValue: string;
|
||||
const expectedDecodedValue: string = 'test1';
|
||||
|
||||
before(() => {
|
||||
const atobPolyfill = format(AtobTemplate(), {
|
||||
atobFunctionName
|
||||
});
|
||||
const rc4Polyfill = format(Rc4Template(), {
|
||||
atobFunctionName,
|
||||
rc4FunctionName
|
||||
});
|
||||
const rc4decodeCodeHelperTemplate: string = format(
|
||||
StringArrayRC4DecodeTemplate(randomGenerator),
|
||||
{
|
||||
atobPolyfill,
|
||||
rc4Polyfill,
|
||||
rc4FunctionName,
|
||||
selfDefendingCode: '',
|
||||
let decodedValue: string;
|
||||
|
||||
before(() => {
|
||||
const stringArrayTemplate = format(StringArrayTemplate(), {
|
||||
stringArrayName,
|
||||
stringArrayFunctionName,
|
||||
stringArrayStorageItems: `'${cryptUtilsSwappedAlphabet.btoa(cryptUtilsSwappedAlphabet.rc4('test1', key))}'`
|
||||
});
|
||||
const atobPolyfill = format(AtobTemplate(selfDefendingEnabled), {
|
||||
atobFunctionName
|
||||
});
|
||||
const rc4Polyfill = format(Rc4Template(), {
|
||||
atobFunctionName,
|
||||
rc4FunctionName
|
||||
});
|
||||
const rc4decodeCodeHelperTemplate: string = format(
|
||||
StringArrayRC4DecodeTemplate(randomGenerator),
|
||||
{
|
||||
atobPolyfill,
|
||||
rc4Polyfill,
|
||||
rc4FunctionName,
|
||||
selfDefendingCode: '',
|
||||
stringArrayCacheName,
|
||||
stringArrayCallsWrapperName
|
||||
}
|
||||
);
|
||||
const stringArrayCallsWrapperTemplate: string = format(StringArrayCallsWrapperTemplate(), {
|
||||
decodeCodeHelperTemplate: rc4decodeCodeHelperTemplate,
|
||||
indexShiftAmount,
|
||||
stringArrayCacheName,
|
||||
stringArrayCallsWrapperName
|
||||
}
|
||||
);
|
||||
const stringArrayCallsWrapperTemplate: string = format(StringArrayCallsWrapperTemplate(), {
|
||||
decodeCodeHelperTemplate: rc4decodeCodeHelperTemplate,
|
||||
indexShiftAmount,
|
||||
stringArrayCacheName,
|
||||
stringArrayCallsWrapperName,
|
||||
stringArrayName
|
||||
stringArrayCallsWrapperName,
|
||||
stringArrayFunctionName
|
||||
});
|
||||
|
||||
decodedValue = Function(`
|
||||
${stringArrayTemplate}
|
||||
|
||||
${stringArrayCallsWrapperTemplate}
|
||||
|
||||
return ${stringArrayCallsWrapperName}('${index}', '${key}');
|
||||
`)();
|
||||
});
|
||||
|
||||
decodedValue = Function(`
|
||||
var ${stringArrayName} = ['${cryptUtilsSwappedAlphabet.btoa(cryptUtilsSwappedAlphabet.rc4('test1', key))}'];
|
||||
|
||||
${stringArrayCallsWrapperTemplate}
|
||||
|
||||
return ${stringArrayCallsWrapperName}('${index}', '${key}');
|
||||
`)();
|
||||
it('should correctly return decoded value', () => {
|
||||
assert.deepEqual(decodedValue, expectedDecodedValue);
|
||||
});
|
||||
});
|
||||
|
||||
it('should correctly return decoded value', () => {
|
||||
assert.deepEqual(decodedValue, expectedDecodedValue);
|
||||
describe('Variant #2: index shift amount is `5`', () => {
|
||||
const index: string = '0x5';
|
||||
const key: string = 'key';
|
||||
|
||||
const indexShiftAmount: number = 5;
|
||||
|
||||
const expectedDecodedValue: string = 'test1';
|
||||
|
||||
let decodedValue: string;
|
||||
|
||||
before(() => {
|
||||
const stringArrayTemplate = format(StringArrayTemplate(), {
|
||||
stringArrayName,
|
||||
stringArrayFunctionName,
|
||||
stringArrayStorageItems: `'${cryptUtilsSwappedAlphabet.btoa(cryptUtilsSwappedAlphabet.rc4('test1', key))}'`
|
||||
});
|
||||
const atobPolyfill = format(AtobTemplate(selfDefendingEnabled), {
|
||||
atobFunctionName
|
||||
});
|
||||
const rc4Polyfill = format(Rc4Template(), {
|
||||
atobFunctionName,
|
||||
rc4FunctionName
|
||||
});
|
||||
const rc4decodeCodeHelperTemplate: string = format(
|
||||
StringArrayRC4DecodeTemplate(randomGenerator),
|
||||
{
|
||||
atobPolyfill,
|
||||
rc4Polyfill,
|
||||
rc4FunctionName,
|
||||
selfDefendingCode: '',
|
||||
stringArrayCacheName,
|
||||
stringArrayCallsWrapperName
|
||||
}
|
||||
);
|
||||
const stringArrayCallsWrapperTemplate: string = format(StringArrayCallsWrapperTemplate(), {
|
||||
decodeCodeHelperTemplate: rc4decodeCodeHelperTemplate,
|
||||
indexShiftAmount,
|
||||
stringArrayCacheName,
|
||||
stringArrayCallsWrapperName,
|
||||
stringArrayFunctionName
|
||||
});
|
||||
|
||||
decodedValue = Function(`
|
||||
${stringArrayTemplate}
|
||||
|
||||
${stringArrayCallsWrapperTemplate}
|
||||
|
||||
return ${stringArrayCallsWrapperName}('${index}', '${key}');
|
||||
`)();
|
||||
});
|
||||
|
||||
it('should correctly return decoded value', () => {
|
||||
assert.deepEqual(decodedValue, expectedDecodedValue);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('Variant #2: index shift amount is `5`', () => {
|
||||
const index: string = '0x5';
|
||||
const key: string = 'key';
|
||||
describe('Variant #2: `selfDefending` option is enabled', () => {
|
||||
const selfDefendingEnabled: boolean = true;
|
||||
|
||||
const indexShiftAmount: number = 5;
|
||||
describe('Variant #1: correct code evaluation for single-line code', () => {
|
||||
describe('Variant #1: index shift amount is `0`', () => {
|
||||
const index: string = '0x0';
|
||||
const key: string = 'key';
|
||||
|
||||
const expectedDecodedValue: string = 'test1';
|
||||
const indexShiftAmount: number = 0;
|
||||
|
||||
let decodedValue: string;
|
||||
const expectedDecodedValue: string = 'test1';
|
||||
|
||||
before(() => {
|
||||
const atobPolyfill = format(AtobTemplate(), {
|
||||
atobFunctionName
|
||||
let decodedValue: string;
|
||||
|
||||
before(async() => {
|
||||
const stringArrayTemplate = format(StringArrayTemplate(), {
|
||||
stringArrayName,
|
||||
stringArrayFunctionName,
|
||||
stringArrayStorageItems: `'${cryptUtilsSwappedAlphabet.btoa(cryptUtilsSwappedAlphabet.rc4('test1', key))}'`
|
||||
});
|
||||
const atobPolyfill = format(AtobTemplate(selfDefendingEnabled), {
|
||||
atobFunctionName
|
||||
});
|
||||
const rc4Polyfill = format(Rc4Template(), {
|
||||
atobFunctionName,
|
||||
rc4FunctionName
|
||||
});
|
||||
const rc4decodeCodeHelperTemplate: string = format(
|
||||
StringArrayRC4DecodeTemplate(randomGenerator),
|
||||
{
|
||||
atobPolyfill,
|
||||
rc4Polyfill,
|
||||
rc4FunctionName,
|
||||
selfDefendingCode: '',
|
||||
stringArrayCacheName,
|
||||
stringArrayCallsWrapperName
|
||||
}
|
||||
);
|
||||
const stringArrayCallsWrapperTemplate: string = await minimizeCode(
|
||||
format(StringArrayCallsWrapperTemplate(), {
|
||||
decodeCodeHelperTemplate: rc4decodeCodeHelperTemplate,
|
||||
indexShiftAmount,
|
||||
stringArrayCacheName,
|
||||
stringArrayCallsWrapperName,
|
||||
stringArrayFunctionName
|
||||
})
|
||||
);
|
||||
|
||||
console.log(stringArrayCallsWrapperTemplate);
|
||||
|
||||
decodedValue = Function(`
|
||||
${stringArrayTemplate}
|
||||
|
||||
${stringArrayCallsWrapperTemplate}
|
||||
|
||||
return ${stringArrayCallsWrapperName}('${index}', '${key}');
|
||||
`)();
|
||||
});
|
||||
|
||||
it('should correctly return decoded value', () => {
|
||||
assert.deepEqual(decodedValue, expectedDecodedValue);
|
||||
});
|
||||
});
|
||||
const rc4Polyfill = format(Rc4Template(), {
|
||||
atobFunctionName,
|
||||
rc4FunctionName
|
||||
});
|
||||
const rc4decodeCodeHelperTemplate: string = format(
|
||||
StringArrayRC4DecodeTemplate(randomGenerator),
|
||||
{
|
||||
atobPolyfill,
|
||||
rc4Polyfill,
|
||||
rc4FunctionName,
|
||||
selfDefendingCode: '',
|
||||
stringArrayCacheName,
|
||||
stringArrayCallsWrapperName
|
||||
}
|
||||
);
|
||||
const stringArrayCallsWrapperTemplate: string = format(StringArrayCallsWrapperTemplate(), {
|
||||
decodeCodeHelperTemplate: rc4decodeCodeHelperTemplate,
|
||||
indexShiftAmount,
|
||||
stringArrayCacheName,
|
||||
stringArrayCallsWrapperName,
|
||||
stringArrayName
|
||||
});
|
||||
|
||||
decodedValue = Function(`
|
||||
var ${stringArrayName} = ['${cryptUtilsSwappedAlphabet.btoa(cryptUtilsSwappedAlphabet.rc4('test1', key))}'];
|
||||
|
||||
${stringArrayCallsWrapperTemplate}
|
||||
|
||||
return ${stringArrayCallsWrapperName}('${index}', '${key}');
|
||||
`)();
|
||||
});
|
||||
|
||||
it('should correctly return decoded value', () => {
|
||||
assert.deepEqual(decodedValue, expectedDecodedValue);
|
||||
describe('Variant #2: invalid code evaluation for multi-line code', () => {
|
||||
describe('Variant #1: index shift amount is `0`', () => {
|
||||
const index: string = '0x0';
|
||||
const key: string = 'key';
|
||||
|
||||
const indexShiftAmount: number = 0;
|
||||
|
||||
const expectedDecodedValue: string = 'test\u001c';
|
||||
|
||||
let decodedValue: string;
|
||||
|
||||
before(() => {
|
||||
const stringArrayTemplate = format(StringArrayTemplate(), {
|
||||
stringArrayName,
|
||||
stringArrayFunctionName,
|
||||
stringArrayStorageItems: `'${cryptUtilsSwappedAlphabet.btoa(cryptUtilsSwappedAlphabet.rc4('test1', key))}'`
|
||||
});
|
||||
const atobPolyfill = format(AtobTemplate(selfDefendingEnabled), {
|
||||
atobFunctionName
|
||||
});
|
||||
const rc4Polyfill = format(Rc4Template(), {
|
||||
atobFunctionName,
|
||||
rc4FunctionName
|
||||
});
|
||||
const rc4decodeCodeHelperTemplate: string = format(
|
||||
StringArrayRC4DecodeTemplate(randomGenerator),
|
||||
{
|
||||
atobPolyfill,
|
||||
rc4Polyfill,
|
||||
rc4FunctionName,
|
||||
selfDefendingCode: '',
|
||||
stringArrayCacheName,
|
||||
stringArrayCallsWrapperName
|
||||
}
|
||||
);
|
||||
const stringArrayCallsWrapperTemplate: string = format(StringArrayCallsWrapperTemplate(), {
|
||||
decodeCodeHelperTemplate: rc4decodeCodeHelperTemplate,
|
||||
indexShiftAmount,
|
||||
stringArrayCacheName,
|
||||
stringArrayCallsWrapperName,
|
||||
stringArrayFunctionName
|
||||
});
|
||||
|
||||
decodedValue = Function(`
|
||||
${stringArrayTemplate}
|
||||
|
||||
${stringArrayCallsWrapperTemplate}
|
||||
|
||||
return ${stringArrayCallsWrapperName}('${index}', '${key}');
|
||||
`)();
|
||||
});
|
||||
|
||||
it('should correctly return decoded value', () => {
|
||||
assert.deepEqual(decodedValue, expectedDecodedValue);
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
+4
-3
@@ -7,13 +7,14 @@ import { IObfuscationResult } from '../../../../../../src/interfaces/source-code
|
||||
import { NO_ADDITIONAL_NODES_PRESET } from '../../../../../../src/options/presets/NoCustomNodes';
|
||||
|
||||
import { JavaScriptObfuscator } from '../../../../../../src/JavaScriptObfuscatorFacade';
|
||||
import { getStringArrayRegExp } from '../../../../../helpers/get-string-array-regexp';
|
||||
import { readFileAsString } from '../../../../../helpers/readFileAsString';
|
||||
|
||||
describe('StringArrayTemplate', () => {
|
||||
describe('Prevailing kind of variables', () => {
|
||||
describe('`var` kind', () => {
|
||||
let obfuscatedCode: string,
|
||||
stringArrayRegExp: RegExp = /var (_0x(\w){4}) *= *\['.*'];/;
|
||||
stringArrayRegExp: RegExp = getStringArrayRegExp(['foo'], {kind: 'var'});
|
||||
|
||||
beforeEach(() => {
|
||||
const code: string = readFileAsString(__dirname + '/fixtures/prevailing-kind-of-variables-var.js');
|
||||
@@ -40,7 +41,7 @@ describe('StringArrayTemplate', () => {
|
||||
|
||||
describe('`const` kind', () => {
|
||||
let obfuscatedCode: string,
|
||||
stringArrayRegExp: RegExp = /const (_0x(\w){4}) *= *\['.*'];/;
|
||||
stringArrayRegExp: RegExp = getStringArrayRegExp(['foo'], {kind: 'const'});
|
||||
|
||||
beforeEach(() => {
|
||||
const code: string = readFileAsString(__dirname + '/fixtures/prevailing-kind-of-variables-const.js');
|
||||
@@ -67,7 +68,7 @@ describe('StringArrayTemplate', () => {
|
||||
|
||||
describe('`let` kind', () => {
|
||||
let obfuscatedCode: string,
|
||||
stringArrayRegExp: RegExp = /const (_0x(\w){4}) *= *\['.*'];/;
|
||||
stringArrayRegExp: RegExp = getStringArrayRegExp(['foo'], {kind: 'const'});
|
||||
|
||||
beforeEach(() => {
|
||||
const code: string = readFileAsString(__dirname + '/fixtures/prevailing-kind-of-variables-let.js');
|
||||
|
||||
+74
-23
@@ -4,8 +4,9 @@ import { IdentifierNamesGenerator } from '../../../../../src/enums/generators/id
|
||||
|
||||
import { NO_ADDITIONAL_NODES_PRESET } from '../../../../../src/options/presets/NoCustomNodes';
|
||||
|
||||
import { readFileAsString } from '../../../../helpers/readFileAsString';
|
||||
import { getRegExpMatch } from '../../../../helpers/getRegExpMatch';
|
||||
import { getStringArrayRegExp } from '../../../../helpers/get-string-array-regexp';
|
||||
import { readFileAsString } from '../../../../helpers/readFileAsString';
|
||||
|
||||
import { JavaScriptObfuscator } from '../../../../../src/JavaScriptObfuscatorFacade';
|
||||
|
||||
@@ -13,10 +14,19 @@ describe('DictionaryIdentifierNamesGenerator', () => {
|
||||
describe('generateWithPrefix', () => {
|
||||
describe('Variant #1: should not generate same name for string array as existing name in code', () => {
|
||||
describe('Variant #1: `renameGlobals` option is disabled', () => {
|
||||
const stringArrayStorageRegExp: RegExp = /const a[cABC] *= *\['_aa', *'_ab'];/;
|
||||
const variableDeclarationIdentifierNameRegExp1: RegExp = /const aa *= *a[cABC]\(0x0\);/;
|
||||
const variableDeclarationIdentifierNameRegExp2: RegExp = /const ab *= *a[cABC]\(0x1\);/;
|
||||
const stringArrayStorageRegExp: RegExp = getStringArrayRegExp(
|
||||
['_aa', '_ab'],
|
||||
{
|
||||
name: '\\w*',
|
||||
kind: 'const'
|
||||
}
|
||||
);
|
||||
const variableDeclarationIdentifierNameRegExp1: RegExp = /const (\w*) *= *\w*\(0x0\);/;
|
||||
const variableDeclarationIdentifierNameRegExp2: RegExp = /const (\w*) *= *\w*\(0x1\);/;
|
||||
|
||||
let stringArrayName: string = '';
|
||||
let variableDeclarationIdentifierName1: string = '';
|
||||
let variableDeclarationIdentifierName2: string = '';
|
||||
let obfuscatedCode: string;
|
||||
|
||||
before(() => {
|
||||
@@ -34,26 +44,45 @@ describe('DictionaryIdentifierNamesGenerator', () => {
|
||||
stringArrayThreshold: 1
|
||||
}
|
||||
).getObfuscatedCode();
|
||||
|
||||
stringArrayName = getRegExpMatch(obfuscatedCode, stringArrayStorageRegExp);
|
||||
variableDeclarationIdentifierName1 = getRegExpMatch(
|
||||
obfuscatedCode,
|
||||
variableDeclarationIdentifierNameRegExp1
|
||||
);
|
||||
variableDeclarationIdentifierName2 = getRegExpMatch(
|
||||
obfuscatedCode,
|
||||
variableDeclarationIdentifierNameRegExp2
|
||||
);
|
||||
});
|
||||
|
||||
it('Match #1: should generate correct identifier for string array', () => {
|
||||
it('Should generate correct identifier for string array', () => {
|
||||
assert.match(obfuscatedCode, stringArrayStorageRegExp);
|
||||
});
|
||||
|
||||
it('Match #2: should keep identifier name for existing variable declaration', () => {
|
||||
assert.match(obfuscatedCode, variableDeclarationIdentifierNameRegExp1);
|
||||
it('Should keep identifier name for existing variable declaration #1', () => {
|
||||
assert.notEqual(stringArrayName, variableDeclarationIdentifierName1);
|
||||
});
|
||||
|
||||
it('Match #3: should keep identifier name for existing variable declaration', () => {
|
||||
assert.match(obfuscatedCode, variableDeclarationIdentifierNameRegExp2);
|
||||
it('Should keep identifier name for existing variable declaration #2', () => {
|
||||
assert.notEqual(stringArrayName, variableDeclarationIdentifierName2);
|
||||
});
|
||||
});
|
||||
|
||||
describe('Variant #2: `renameGlobals` option is enabled', () => {
|
||||
const stringArrayStorageRegExp: RegExp = /const a[cABC] *= *\['_aa', *'_ab'];/;
|
||||
const lastVariableDeclarationIdentifierNameRegExp1: RegExp = /const a[cABC] *= *a[cABC]\(0x0\);/;
|
||||
const lastVariableDeclarationIdentifierNameRegExp2: RegExp = /const a[cABC] *= *a[cABC]\(0x1\);/;
|
||||
const stringArrayStorageRegExp: RegExp = getStringArrayRegExp(
|
||||
['_aa', '_ab'],
|
||||
{
|
||||
name: '\\w*',
|
||||
kind: 'const'
|
||||
}
|
||||
);
|
||||
const variableDeclarationIdentifierNameRegExp1: RegExp = /const (\w*) *= *\w*\(0x0\);/;
|
||||
const variableDeclarationIdentifierNameRegExp2: RegExp = /const (\w*) *= *\w*\(0x1\);/;
|
||||
|
||||
let stringArrayName: string = '';
|
||||
let variableDeclarationIdentifierName1: string = '';
|
||||
let variableDeclarationIdentifierName2: string = '';
|
||||
let obfuscatedCode: string;
|
||||
|
||||
before(() => {
|
||||
@@ -64,7 +93,7 @@ describe('DictionaryIdentifierNamesGenerator', () => {
|
||||
{
|
||||
...NO_ADDITIONAL_NODES_PRESET,
|
||||
identifierNamesGenerator: IdentifierNamesGenerator.DictionaryIdentifierNamesGenerator,
|
||||
identifiersDictionary: ['a', 'b', 'c'],
|
||||
identifiersDictionary: ['a', 'b', 'c', 'd'],
|
||||
identifiersPrefix: 'a',
|
||||
renameGlobals: true,
|
||||
transformObjectKeys: true,
|
||||
@@ -72,18 +101,28 @@ describe('DictionaryIdentifierNamesGenerator', () => {
|
||||
stringArrayThreshold: 1
|
||||
}
|
||||
).getObfuscatedCode();
|
||||
|
||||
stringArrayName = getRegExpMatch(obfuscatedCode, stringArrayStorageRegExp);
|
||||
variableDeclarationIdentifierName1 = getRegExpMatch(
|
||||
obfuscatedCode,
|
||||
variableDeclarationIdentifierNameRegExp1
|
||||
);
|
||||
variableDeclarationIdentifierName2 = getRegExpMatch(
|
||||
obfuscatedCode,
|
||||
variableDeclarationIdentifierNameRegExp2
|
||||
);
|
||||
});
|
||||
|
||||
it('Match #1: should generate correct identifier for string array', () => {
|
||||
it('Should generate correct identifier for string array', () => {
|
||||
assert.match(obfuscatedCode, stringArrayStorageRegExp);
|
||||
});
|
||||
|
||||
it('Match #2: should keep identifier name for existing variable declaration', () => {
|
||||
assert.match(obfuscatedCode, lastVariableDeclarationIdentifierNameRegExp1);
|
||||
it('Should keep identifier name for existing variable declaration #1', () => {
|
||||
assert.notEqual(stringArrayName, variableDeclarationIdentifierName1);
|
||||
});
|
||||
|
||||
it('Match #3: should keep identifier name for existing variable declaration', () => {
|
||||
assert.match(obfuscatedCode, lastVariableDeclarationIdentifierNameRegExp2);
|
||||
it('Should keep identifier name for existing variable declaration #2', () => {
|
||||
assert.notEqual(stringArrayName, variableDeclarationIdentifierName2);
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -91,11 +130,17 @@ describe('DictionaryIdentifierNamesGenerator', () => {
|
||||
describe('Variant #2: should not generate same prefixed name for identifier in code as prefixed name of string array', function () {
|
||||
this.timeout(10000);
|
||||
|
||||
const samplesCount: number = 20;
|
||||
const samplesCount: number = 30;
|
||||
|
||||
describe('Variant #1: `renameGlobals` option is disabled', () => {
|
||||
const stringArrayStorageRegExp: RegExp = /const ([abAB]{1,3}) *= *\['first', *'abc'];/;
|
||||
const variableDeclarationIdentifierNameRegExp: RegExp = /const ([abAB]{1,3}){1,2} *= *[abAB]{1,3}\(0x0\);/;
|
||||
const stringArrayStorageRegExp: RegExp = getStringArrayRegExp(
|
||||
['first', 'abc'],
|
||||
{
|
||||
name: '\\w*',
|
||||
kind: 'const'
|
||||
}
|
||||
);
|
||||
const variableDeclarationIdentifierNameRegExp: RegExp = /const (\w*) *= *\w*\(0x0\);/;
|
||||
|
||||
let isIdentifiersAreConflicted: boolean = false;
|
||||
|
||||
@@ -133,8 +178,14 @@ describe('DictionaryIdentifierNamesGenerator', () => {
|
||||
});
|
||||
|
||||
describe('Variant #2: `renameGlobals` option is enabled', () => {
|
||||
const stringArrayStorageRegExp: RegExp = /const ([abAB]{1,3}) *= *\['first', *'abc'];/;
|
||||
const variableDeclarationIdentifierNameRegExp: RegExp = /const ([abAB]{1,3}){1,2} *= *[abAB]{1,3}\(0x0\);/;
|
||||
const stringArrayStorageRegExp: RegExp = getStringArrayRegExp(
|
||||
['first', 'abc'],
|
||||
{
|
||||
name: '\\w*',
|
||||
kind: 'const'
|
||||
}
|
||||
);
|
||||
const variableDeclarationIdentifierNameRegExp: RegExp = /const (\w*) *= *\w*\(0x0\);/;
|
||||
|
||||
let isIdentifiersAreConflicted: boolean = false;
|
||||
|
||||
|
||||
-1
@@ -1,5 +1,4 @@
|
||||
function foo () {
|
||||
const testA = 'first';
|
||||
const testB = 'abc';
|
||||
const testC = 'abc';
|
||||
}
|
||||
+25
-6
@@ -4,6 +4,7 @@ import { IdentifierNamesGenerator } from '../../../../../src/enums/generators/id
|
||||
|
||||
import { NO_ADDITIONAL_NODES_PRESET } from '../../../../../src/options/presets/NoCustomNodes';
|
||||
|
||||
import { getStringArrayRegExp } from '../../../../helpers/get-string-array-regexp';
|
||||
import { readFileAsString } from '../../../../helpers/readFileAsString';
|
||||
|
||||
import { JavaScriptObfuscator } from '../../../../../src/JavaScriptObfuscatorFacade';
|
||||
@@ -12,7 +13,10 @@ describe('MangledIdentifierNamesGenerator', () => {
|
||||
describe('generateWithPrefix', () => {
|
||||
describe('Variant #1: should not generate same name for string array as existing name in code', () => {
|
||||
describe('Variant #1: `renameGlobals` option is disabled', () => {
|
||||
const stringArrayStorageRegExp: RegExp = /const ab *= *\['abc'];/;
|
||||
const stringArrayStorageRegExp: RegExp = getStringArrayRegExp(['abc'], {
|
||||
kind: 'const',
|
||||
name: 'ab'
|
||||
});
|
||||
const lastVariableDeclarationIdentifierNameRegExp: RegExp = /const aa *= *ac\(0x0\);/;
|
||||
|
||||
let obfuscatedCode: string;
|
||||
@@ -43,7 +47,10 @@ describe('MangledIdentifierNamesGenerator', () => {
|
||||
});
|
||||
|
||||
describe('Variant #2: `renameGlobals` option is enabled', () => {
|
||||
const stringArrayStorageRegExp: RegExp = /const ab *= *\['abc'];/;
|
||||
const stringArrayStorageRegExp: RegExp = getStringArrayRegExp(['abc'], {
|
||||
kind: 'const',
|
||||
name: 'ab'
|
||||
});
|
||||
const lastVariableDeclarationIdentifierNameRegExp: RegExp = /const aB *= *ac\(0x0\);/;
|
||||
|
||||
let obfuscatedCode: string;
|
||||
@@ -77,7 +84,10 @@ describe('MangledIdentifierNamesGenerator', () => {
|
||||
|
||||
describe('Variant #2: should not generate same prefixed name for identifier in code as prefixed name of string array', () => {
|
||||
describe('Variant #1: `renameGlobals` option is disabled', () => {
|
||||
const stringArrayStorageRegExp: RegExp = /const aa *= *\['abc', *'last'];/;
|
||||
const stringArrayStorageRegExp: RegExp = getStringArrayRegExp(['abc', 'last'], {
|
||||
kind: 'const',
|
||||
name: 'aa'
|
||||
});
|
||||
const functionDeclarationIdentifierNameRegExp: RegExp = /function foo *\(\) *{/;
|
||||
const lastVariableDeclarationIdentifierNameRegExp: RegExp = /const ac *= *ab\(0x1\);/;
|
||||
|
||||
@@ -113,7 +123,10 @@ describe('MangledIdentifierNamesGenerator', () => {
|
||||
});
|
||||
|
||||
describe('Variant #2: `renameGlobals` option is enabled', () => {
|
||||
const stringArrayStorageRegExp: RegExp = /const aa *= *\['abc', *'last'];/;
|
||||
const stringArrayStorageRegExp: RegExp = getStringArrayRegExp(['abc', 'last'], {
|
||||
kind: 'const',
|
||||
name: 'aa'
|
||||
});
|
||||
const functionDeclarationIdentifierNameRegExp: RegExp = /function ac *\(\) *{/;
|
||||
const lastVariableDeclarationIdentifierNameRegExp: RegExp = /const ad *= *ab\(0x1\);/;
|
||||
|
||||
@@ -221,7 +234,10 @@ describe('MangledIdentifierNamesGenerator', () => {
|
||||
|
||||
describe('Variant #2: Should generate different names set for different lexical scopes when string array is enabled', () => {
|
||||
describe('Variant #1: `renameGlobals` option is disabled', () => {
|
||||
const stringArrayIdentifierRegExp: RegExp = /var a *= *\['abc'];/;
|
||||
const stringArrayIdentifierRegExp: RegExp = getStringArrayRegExp(['abc'], {
|
||||
kind: 'var',
|
||||
name: 'a'
|
||||
});
|
||||
const variableIdentifierRegExp: RegExp = /var foo *= *b\(0x0\);/;
|
||||
const functionDeclarationRegExp1: RegExp = /function bar *\(c, *d\) *{}/;
|
||||
const functionDeclarationRegExp2: RegExp = /function baz *\(c, *d\) *{}/;
|
||||
@@ -260,7 +276,10 @@ describe('MangledIdentifierNamesGenerator', () => {
|
||||
});
|
||||
|
||||
describe('Variant #2: `renameGlobals` option is enabled', () => {
|
||||
const stringArrayIdentifierRegExp: RegExp = /var a *= *\['abc'];/;
|
||||
const stringArrayIdentifierRegExp: RegExp = getStringArrayRegExp(['abc'], {
|
||||
kind: 'var',
|
||||
name: 'a'
|
||||
});
|
||||
const variableIdentifierRegExp: RegExp = /var c *= *b\(0x0\);/;
|
||||
const functionDeclarationRegExp1: RegExp = /function d *\(f, *g\) *{}/;
|
||||
const functionDeclarationRegExp2: RegExp = /function e *\(f, *g\) *{}/;
|
||||
|
||||
@@ -27,6 +27,7 @@ import { OptionsPreset } from '../../../src/enums/options/presets/OptionsPreset'
|
||||
|
||||
import { buildLargeCode } from '../../helpers/buildLargeCode';
|
||||
import { getRegExpMatch } from '../../helpers/getRegExpMatch';
|
||||
import { getStringArrayRegExp } from '../../helpers/get-string-array-regexp';
|
||||
import { readFileAsString } from '../../helpers/readFileAsString';
|
||||
|
||||
describe('JavaScriptObfuscator', () => {
|
||||
@@ -444,7 +445,12 @@ describe('JavaScriptObfuscator', () => {
|
||||
});
|
||||
|
||||
describe('Variant #4: with `stringArray`, `renameGlobals` and `identifiersPrefix` options', () => {
|
||||
const stringArrayRegExp: RegExp = /^var foo_0x(\w){4} *= *\['abc'\];/;
|
||||
const stringArrayRegExp: RegExp = new RegExp(
|
||||
'function foo_0x([a-f0-9]){4} *\\(\\) *{' +
|
||||
'var _0x([a-f0-9]){4,6} *= *\\[\'abc\'];.*' +
|
||||
'return foo_0x([a-f0-9]){4}\\(\\); *' +
|
||||
'}'
|
||||
);
|
||||
const stringArrayCallRegExp: RegExp = /var foo_0x(\w){4,6} *= *foo_0x(\w){4}\(0x0\);$/;
|
||||
|
||||
let obfuscatedCode: string;
|
||||
@@ -536,7 +542,7 @@ describe('JavaScriptObfuscator', () => {
|
||||
});
|
||||
|
||||
describe('latin literal variable value', () => {
|
||||
const stringArrayLatinRegExp: RegExp = /^var _0x(\w){4} *= *\['abc'\];/;
|
||||
const stringArrayLatinRegExp: RegExp = getStringArrayRegExp(['abc']);
|
||||
const stringArrayCallRegExp: RegExp = /var test *= *_0x(\w){4}\(0x0\);$/;
|
||||
|
||||
let obfuscatedCode: string;
|
||||
@@ -564,7 +570,12 @@ describe('JavaScriptObfuscator', () => {
|
||||
});
|
||||
|
||||
describe('cyrillic literal variable value', () => {
|
||||
const stringArrayCyrillicRegExp: RegExp = /^var _0x(\w){4} *= *\['абц'\];/;
|
||||
const stringArrayCyrillicRegExp: RegExp = new RegExp(
|
||||
'function _0x(\\w){4} *\\(\\) *{' +
|
||||
'var _0x([a-f0-9]){4,6} *= *\\[\'абц\'];.*' +
|
||||
'return _0x(\\w){4}\\(\\); *' +
|
||||
'}'
|
||||
);
|
||||
const stringArrayCallRegExp: RegExp = /var test *= *_0x(\w){4}\(0x0\);$/;
|
||||
|
||||
let obfuscatedCode: string;
|
||||
@@ -689,7 +700,12 @@ describe('JavaScriptObfuscator', () => {
|
||||
const code1: string = readFileAsString(__dirname + '/fixtures/simple-input-cyrillic.js');
|
||||
const code2: string = readFileAsString(__dirname + '/fixtures/simple-input-2.js');
|
||||
|
||||
const regExp: RegExp = /var (_0x(\w){4}) *= *\['.*'\];/;
|
||||
const regExp: RegExp = new RegExp(
|
||||
'function _0x(\\w){4} *\\(\\) *{' +
|
||||
'var _0x([a-f0-9]){4,6} *= *\\[\'.*\'];.*' +
|
||||
'return _0x(\\w){4}\\(\\); *' +
|
||||
'}'
|
||||
);
|
||||
|
||||
let match1: string,
|
||||
match2: string;
|
||||
|
||||
+5
-4
@@ -2,6 +2,7 @@ import { assert } from 'chai';
|
||||
|
||||
import { NO_ADDITIONAL_NODES_PRESET } from '../../../../../src/options/presets/NoCustomNodes';
|
||||
|
||||
import { getStringArrayRegExp } from '../../../../helpers/get-string-array-regexp';
|
||||
import { readFileAsString } from '../../../../helpers/readFileAsString';
|
||||
|
||||
import { JavaScriptObfuscator } from '../../../../../src/JavaScriptObfuscatorFacade';
|
||||
@@ -31,7 +32,7 @@ describe('ClassFieldTransformer', () => {
|
||||
});
|
||||
|
||||
describe('Variant #2: `stringArray` option is enabled', () => {
|
||||
const stringArrayRegExp: RegExp = /var _0x([a-f0-9]){4} *= *\['property', *'bar'\];/;
|
||||
const stringArrayRegExp: RegExp = getStringArrayRegExp(['property', 'bar']);
|
||||
const stringArrayCallRegExp: RegExp = /\[_0x([a-f0-9]){4}\(0x1\)\]\(\)\{\}/;
|
||||
|
||||
let obfuscatedCode: string;
|
||||
@@ -103,7 +104,7 @@ describe('ClassFieldTransformer', () => {
|
||||
});
|
||||
|
||||
describe('Variant #2: `stringArray` option is enabled', () => {
|
||||
const stringArrayRegExp: RegExp = /var _0x([a-f0-9]){4} *= *\['property', *'constructor', *'bar'];/;
|
||||
const stringArrayRegExp: RegExp = getStringArrayRegExp(['property', 'constructor', 'bar']);
|
||||
const stringArrayCallRegExp: RegExp = /\[_0x([a-f0-9]){4}\(0x2\)\]\(\)\{\}/;
|
||||
|
||||
let obfuscatedCode: string;
|
||||
@@ -203,7 +204,7 @@ describe('ClassFieldTransformer', () => {
|
||||
});
|
||||
|
||||
describe('Variant #2: `stringArray` option is enabled', () => {
|
||||
const stringArrayRegExp: RegExp = /var _0x([a-f0-9]){4} *= *\['property', *'bar'\];/;
|
||||
const stringArrayRegExp: RegExp = getStringArrayRegExp(['property', 'bar']);
|
||||
const stringArrayCallRegExp: RegExp = /\[_0x([a-f0-9]){4}\(0x0\)\] *= *0x1;/;
|
||||
|
||||
let obfuscatedCode: string;
|
||||
@@ -254,7 +255,7 @@ describe('ClassFieldTransformer', () => {
|
||||
});
|
||||
|
||||
describe('Variant #2: `stringArray` option is enabled', () => {
|
||||
const stringArrayRegExp: RegExp = /var _0x([a-f0-9]){4} *= *\['property', *'constructor', *'bar'];/;
|
||||
const stringArrayRegExp: RegExp = getStringArrayRegExp(['property', 'constructor', 'bar']);
|
||||
const stringArrayCallRegExp: RegExp = /\[_0x([a-f0-9]){4}\(0x0\)\] *= *0x1;/;
|
||||
|
||||
let obfuscatedCode: string;
|
||||
|
||||
+3
-2
@@ -2,6 +2,7 @@ import { assert } from 'chai';
|
||||
|
||||
import { NO_ADDITIONAL_NODES_PRESET } from '../../../../../src/options/presets/NoCustomNodes';
|
||||
|
||||
import { getStringArrayRegExp } from '../../../../helpers/get-string-array-regexp';
|
||||
import { readFileAsString } from '../../../../helpers/readFileAsString';
|
||||
|
||||
import { JavaScriptObfuscator } from '../../../../../src/JavaScriptObfuscatorFacade';
|
||||
@@ -30,7 +31,7 @@ describe('MemberExpressionTransformer', () => {
|
||||
});
|
||||
|
||||
describe('`stringArray` option is enabled', () => {
|
||||
const stringArrayRegExp: RegExp = /var _0x([a-f0-9]){4} *= *\['log'\];/;
|
||||
const stringArrayRegExp: RegExp = getStringArrayRegExp(['log']);
|
||||
const stringArrayCallRegExp: RegExp = /var test *= *console\[_0x([a-f0-9]){4}\(0x0\)\];/;
|
||||
|
||||
let obfuscatedCode: string;
|
||||
@@ -60,7 +61,7 @@ describe('MemberExpressionTransformer', () => {
|
||||
|
||||
describe('transformation of member expression node with square brackets', () => {
|
||||
describe('Variant #1: square brackets literal ', () => {
|
||||
const stringArrayRegExp: RegExp = /var _0x([a-f0-9]){4} *= *\['log'\];/;
|
||||
const stringArrayRegExp: RegExp = getStringArrayRegExp(['log']);
|
||||
const stringArrayCallRegExp: RegExp = /var test *= *console\[_0x([a-f0-9]){4}\(0x0\)\];/;
|
||||
|
||||
let obfuscatedCode: string;
|
||||
|
||||
+11
-4
@@ -2,6 +2,7 @@ import { assert } from 'chai';
|
||||
|
||||
import { NO_ADDITIONAL_NODES_PRESET } from '../../../../../src/options/presets/NoCustomNodes';
|
||||
|
||||
import { getStringArrayRegExp } from '../../../../helpers/get-string-array-regexp';
|
||||
import { readFileAsString } from '../../../../helpers/readFileAsString';
|
||||
|
||||
import { JavaScriptObfuscator } from '../../../../../src/JavaScriptObfuscatorFacade';
|
||||
@@ -11,7 +12,10 @@ describe('DirectivePlacementTransformer', function () {
|
||||
|
||||
describe('Variant #1: program scope', () => {
|
||||
describe('Variant #1: directive at the top of program scope', () => {
|
||||
const directiveRegExp: RegExp = /^'use strict'; *var _0x([a-f0-9]){4} *= *\['test'];/;
|
||||
const directiveRegExp: RegExp = new RegExp(
|
||||
'^\'use strict\';.*' +
|
||||
getStringArrayRegExp(['test']).source
|
||||
);
|
||||
|
||||
let obfuscatedCode: string;
|
||||
|
||||
@@ -34,9 +38,8 @@ describe('DirectivePlacementTransformer', function () {
|
||||
});
|
||||
|
||||
describe('Variant #2: directive-like string literal at the middle of program scope', () => {
|
||||
const stringArrayStorageRegExp: RegExp = getStringArrayRegExp(['test', 'use\\\\x20strict']);
|
||||
const directiveRegExp: RegExp = new RegExp(
|
||||
'^var _0x([a-f0-9]){4} *= *\\[\'test\', *\'use\\\\x20strict\']; *' +
|
||||
'.*?' +
|
||||
'var test *= *_0x([a-f0-9]){4}\\(0x0\\);.*' +
|
||||
'_0x([a-f0-9]){4}\\(0x1\\);'
|
||||
);
|
||||
@@ -56,7 +59,11 @@ describe('DirectivePlacementTransformer', function () {
|
||||
).getObfuscatedCode();
|
||||
});
|
||||
|
||||
it('should keep directive-like string literal at the middle of program scope', () => {
|
||||
it('should add directive-like string literal to the string array', () => {
|
||||
assert.match(obfuscatedCode, stringArrayStorageRegExp);
|
||||
});
|
||||
|
||||
it('should add call to the directive-like string literal from the string array', () => {
|
||||
assert.match(obfuscatedCode, directiveRegExp);
|
||||
});
|
||||
});
|
||||
|
||||
+2
-1
@@ -5,6 +5,7 @@ import { NO_ADDITIONAL_NODES_PRESET } from '../../../../../src/options/presets/N
|
||||
import { IdentifierNamesGenerator } from '../../../../../src/enums/generators/identifier-names-generators/IdentifierNamesGenerator';
|
||||
import { StringArrayIndexesType } from '../../../../../src/enums/node-transformers/string-array-transformers/StringArrayIndexesType';
|
||||
|
||||
import { getStringArrayRegExp } from '../../../../helpers/get-string-array-regexp';
|
||||
import { readFileAsString } from '../../../../helpers/readFileAsString';
|
||||
|
||||
import { JavaScriptObfuscator } from '../../../../../src/JavaScriptObfuscatorFacade';
|
||||
@@ -57,7 +58,7 @@ describe('EscapeSequenceTransformer', function () {
|
||||
});
|
||||
|
||||
describe('Variant #3: `unicodeEscapeSequence` and `stringArray` options are enabled', () => {
|
||||
const stringArrayRegExp: RegExp = /^var _0x([a-f0-9]){4} *= *\['\\x74\\x65\\x73\\x74'\];/;
|
||||
const stringArrayRegExp: RegExp = getStringArrayRegExp(['\\\\x74\\\\x65\\\\x73\\\\x74']);
|
||||
const stringArrayCallRegExp: RegExp = /var test *= *_0x([a-f0-9]){4}\('\\x30\\x78\\x30'\);/;
|
||||
|
||||
let obfuscatedCode: string;
|
||||
|
||||
+5
-1
@@ -5,6 +5,7 @@ import { NO_ADDITIONAL_NODES_PRESET } from '../../../../../src/options/presets/N
|
||||
import { readFileAsString } from '../../../../helpers/readFileAsString';
|
||||
|
||||
import { JavaScriptObfuscator } from '../../../../../src/JavaScriptObfuscatorFacade';
|
||||
import { getStringArrayRegExp } from '../../../../helpers/get-string-array-regexp';
|
||||
|
||||
describe('CommentsTransformer', () => {
|
||||
const lineSeparatorEscaped: string = '\\r?\\n';
|
||||
@@ -142,7 +143,10 @@ describe('CommentsTransformer', () => {
|
||||
|
||||
describe('Variant #7: simple comment with preserved words and additional code helper is inserted', () => {
|
||||
describe('Variant #1: `stringArray` code helper', () => {
|
||||
const regExp: RegExp = /^\/\/ *@license *test *comment *\n*var _0x([a-f0-9]){4} *= *\['abc'];/;
|
||||
const regExp: RegExp = new RegExp(
|
||||
'^\\/\\/ *@license *test *comment *\\n*.*' +
|
||||
getStringArrayRegExp(['abc']).source
|
||||
);
|
||||
|
||||
let obfuscatedCode: string;
|
||||
|
||||
|
||||
+4
-3
@@ -4,10 +4,11 @@ import { NO_ADDITIONAL_NODES_PRESET } from '../../../../../src/options/presets/N
|
||||
|
||||
import { StringArrayIndexesType } from '../../../../../src/enums/node-transformers/string-array-transformers/StringArrayIndexesType';
|
||||
|
||||
import { getRegExpMatch } from '../../../../helpers/getRegExpMatch';
|
||||
import { getStringArrayRegExp } from '../../../../helpers/get-string-array-regexp';
|
||||
import { readFileAsString } from '../../../../helpers/readFileAsString';
|
||||
|
||||
import { JavaScriptObfuscator } from '../../../../../src/JavaScriptObfuscatorFacade';
|
||||
import { getRegExpMatch } from '../../../../helpers/getRegExpMatch';
|
||||
|
||||
describe('EvalCallExpressionTransformer', () => {
|
||||
describe('Variant #1: identifier reference', () => {
|
||||
@@ -95,7 +96,7 @@ describe('EvalCallExpressionTransformer', () => {
|
||||
|
||||
describe('Variant #4: string array calls wrapper call', () => {
|
||||
describe('Variant #1: hexadecimal number indexes type', () => {
|
||||
const stringArrayRegExp: RegExp = /var _0x([a-f0-9]){4} *= *\['log', *'bar'];/;
|
||||
const stringArrayRegExp: RegExp = getStringArrayRegExp(['log', 'bar']);
|
||||
const stringArrayCallsWrapperRegExp: RegExp = /eval *\('console\[_0x([a-f0-9]){4,6}\(0\)]\(_0x([a-f0-9]){4,6}\(1\)\);'\);/;
|
||||
|
||||
let obfuscatedCode: string;
|
||||
@@ -126,7 +127,7 @@ describe('EvalCallExpressionTransformer', () => {
|
||||
});
|
||||
|
||||
describe('Variant #1: hexadecimal numeric string indexes type', () => {
|
||||
const stringArrayRegExp: RegExp = /var _0x([a-f0-9]){4} *= *\['log', *'bar'];/;
|
||||
const stringArrayRegExp: RegExp = getStringArrayRegExp(['log', 'bar']);
|
||||
const stringArrayCallsWrapperRegExp: RegExp = /eval *\('console\[_0x([a-f0-9]){4,6}\(\\'0x0\\'\)]\(_0x([a-f0-9]){4,6}\(\\'0x1\\'\)\);'\);/;
|
||||
|
||||
let obfuscatedCode: string;
|
||||
|
||||
+2
-1
@@ -4,13 +4,14 @@ import { JavaScriptObfuscator } from '../../../../../../src/JavaScriptObfuscator
|
||||
|
||||
import { NO_ADDITIONAL_NODES_PRESET } from '../../../../../../src/options/presets/NoCustomNodes';
|
||||
|
||||
import { getStringArrayRegExp } from '../../../../../helpers/get-string-array-regexp';
|
||||
import { readFileAsString } from '../../../../../helpers/readFileAsString';
|
||||
|
||||
describe('BlackListObfuscatingGuard', () => {
|
||||
describe('check', () => {
|
||||
describe('`\'use strict\';` operator', () => {
|
||||
const useStrictOperatorRegExp: RegExp = /'use *strict';/;
|
||||
const stringArrayLatinRegExp: RegExp = /var _0x(\w){4} *= *\['abc'\];/;
|
||||
const stringArrayLatinRegExp: RegExp = getStringArrayRegExp(['abc']);
|
||||
const stringArrayCallRegExp: RegExp = /var test *= *_0x(\w){4}\(0x0\);$/;
|
||||
|
||||
let obfuscatedCode: string;
|
||||
|
||||
+8
-8
@@ -10,9 +10,9 @@ describe('ConditionalCommentObfuscatingGuard', () => {
|
||||
describe('check', () => {
|
||||
describe('Variant #1: `disable` conditional comment', () => {
|
||||
const disableConditionalCommentRegExp: RegExp = /\/\/ *javascript-obfuscator:disable/;
|
||||
const obfuscatedVariableDeclarationRegExp: RegExp = /var _0x([a-f0-9]){4,6} *= *0x1;/;
|
||||
const obfuscatedVariableDeclarationRegExp: RegExp = /var _0x([a-f0-9]){5,6} *= *0x1;/;
|
||||
const ignoredVariableDeclarationRegExp: RegExp = /var bar *= *2;/;
|
||||
const consoleLogRegExp: RegExp = /console.log\(_0x([a-f0-9]){4,6}\);/;
|
||||
const consoleLogRegExp: RegExp = /console.log\(_0x([a-f0-9]){5,6}\);/;
|
||||
|
||||
let obfuscatedCode: string;
|
||||
|
||||
@@ -47,8 +47,8 @@ describe('ConditionalCommentObfuscatingGuard', () => {
|
||||
describe('Variant #2: `disable` and `enable` conditional comments #1', () => {
|
||||
const disableConditionalCommentRegExp: RegExp = /\/\/ *javascript-obfuscator:disable/;
|
||||
const enableConditionalCommentRegExp: RegExp = /\/\/ *javascript-obfuscator:enable/;
|
||||
const obfuscatedVariableDeclaration1RegExp: RegExp = /var _0x([a-f0-9]){4,6} *= *0x1;/;
|
||||
const obfuscatedVariableDeclaration2RegExp: RegExp = /var _0x([a-f0-9]){4,6} *= *0x3;/;
|
||||
const obfuscatedVariableDeclaration1RegExp: RegExp = /var _0x([a-f0-9]){5,6} *= *0x1;/;
|
||||
const obfuscatedVariableDeclaration2RegExp: RegExp = /var _0x([a-f0-9]){5,6} *= *0x3;/;
|
||||
const ignoredVariableDeclarationRegExp: RegExp = /var bar *= *2;/;
|
||||
|
||||
let obfuscatedCode: string;
|
||||
@@ -87,7 +87,7 @@ describe('ConditionalCommentObfuscatingGuard', () => {
|
||||
|
||||
describe('Variant #3: `disable` and `enable` conditional comments #2', () => {
|
||||
const ignoredVariableDeclarationRegExp: RegExp = /var foo *= *1;/;
|
||||
const obfuscatedVariableDeclarationRegExp: RegExp = /var _0x([a-f0-9]){4,6} *= *0x2;/;
|
||||
const obfuscatedVariableDeclarationRegExp: RegExp = /var _0x([a-f0-9]){5,6} *= *0x2;/;
|
||||
|
||||
let obfuscatedCode: string;
|
||||
|
||||
@@ -139,13 +139,13 @@ describe('ConditionalCommentObfuscatingGuard', () => {
|
||||
});
|
||||
|
||||
describe('Variant #5: `disable` and `enable` conditional comments with dead code injection', () => {
|
||||
const obfuscatedFunctionExpressionRegExp: RegExp = /var _0x([a-f0-9]){4,6} *= *function *\(_0x([a-f0-9]){4,6}, *_0x([a-f0-9]){4,6}, *_0x([a-f0-9]){4,6}\) *{/g;
|
||||
const obfuscatedFunctionExpressionRegExp: RegExp = /var _0x([a-f0-9]){5,6} *= *function *\(_0x([a-f0-9]){5,6}, *_0x([a-f0-9]){5,6}, *_0x([a-f0-9]){5,6}\) *{/g;
|
||||
const expectedObfuscatedFunctionExpressionLength: number = 3;
|
||||
|
||||
const ignoredFunctionExpression1RegExp: RegExp = /var bar *= *function *\(a, *b, *c\) *{/;
|
||||
const ignoredFunctionExpression2RegExp: RegExp = /var baz *= *function *\(a, *b, *c\) *{/;
|
||||
|
||||
const obfuscatedFunctionCallRegExp: RegExp = /_0x([a-f0-9]){4,6}\( *\);/g;
|
||||
const obfuscatedFunctionCallRegExp: RegExp = /_0x([a-f0-9]){5,6}\( *\);/g;
|
||||
const expectedObfuscatedFunctionCallsLength: number = 3;
|
||||
|
||||
const ignoredFunctionCall1RegExp: RegExp = /bar\( *\);/;
|
||||
@@ -209,7 +209,7 @@ describe('ConditionalCommentObfuscatingGuard', () => {
|
||||
});
|
||||
|
||||
describe('Variant #6: `disable` and `enable` conditional comments with control flow flattening', () => {
|
||||
const obfuscatedVariableDeclarationRegExp: RegExp = /var _0x([a-f0-9]){4,6} *= *_0x([a-f0-9]){4,6}\['[a-zA-Z0-9]{1,5}'];/;
|
||||
const obfuscatedVariableDeclarationRegExp: RegExp = /var _0x([a-f0-9]){5,6} *= *_0x([a-f0-9]){5,6}\['[a-zA-Z0-9]{1,5}'];/;
|
||||
const ignoredVariableDeclarationRegExp: RegExp = /var bar *= *'bar';/;
|
||||
|
||||
let obfuscatedCode: string;
|
||||
|
||||
+9
-2
@@ -2,6 +2,7 @@ import { assert } from 'chai';
|
||||
|
||||
import { NO_ADDITIONAL_NODES_PRESET } from '../../../../../src/options/presets/NoCustomNodes';
|
||||
|
||||
import { getStringArrayRegExp } from '../../../../helpers/get-string-array-regexp';
|
||||
import { readFileAsString } from '../../../../helpers/readFileAsString';
|
||||
import { stubNodeTransformers } from '../../../../helpers/stubNodeTransformers';
|
||||
|
||||
@@ -11,7 +12,10 @@ import { ObjectPatternPropertiesTransformer } from '../../../../../src/node-tran
|
||||
describe('VariablePreserveTransformer', () => {
|
||||
describe('Variant #1: string array storage name conflicts with identifier name', () => {
|
||||
describe('Variant #1: `renameGlobals` option is disabled', () => {
|
||||
const stringArrayStorageNameRegExp: RegExp = /const b *= *\['abc'];/;
|
||||
const stringArrayStorageNameRegExp: RegExp = getStringArrayRegExp(['abc'], {
|
||||
kind: 'const',
|
||||
name: 'b'
|
||||
});
|
||||
const identifierNameRegExp: RegExp = /const a *= *c\(0x0\);/;
|
||||
|
||||
let obfuscatedCode: string;
|
||||
@@ -40,7 +44,10 @@ describe('VariablePreserveTransformer', () => {
|
||||
});
|
||||
|
||||
describe('Variant #2: `renameGlobals` option is enabled', () => {
|
||||
const stringArrayStorageNameRegExp: RegExp = /const b *= *\['abc'];/;
|
||||
const stringArrayStorageNameRegExp: RegExp = getStringArrayRegExp(['abc'], {
|
||||
kind: 'const',
|
||||
name: 'b'
|
||||
});
|
||||
const identifierNameRegExp: RegExp = /const d *= *c\(0x0\);/;
|
||||
|
||||
let obfuscatedCode: string;
|
||||
|
||||
-11
@@ -651,11 +651,9 @@ describe('StringArrayScopeCallsWrapperTransformer', function () {
|
||||
'}';
|
||||
|
||||
const stringArrayScopeCallsWrapperRegExp1: RegExp = new RegExp(
|
||||
'const a *= *\\[.*?];.*?' +
|
||||
getStringArrayCallsWrapperMatch('f')
|
||||
);
|
||||
const stringArrayScopeCallsWrapperRegExp2: RegExp = new RegExp(
|
||||
'const a *= *\\[.*?];.*?' +
|
||||
'function test *\\( *\\) *{.*' +
|
||||
`${getStringArrayCallsWrapperMatch('g')}.*?` +
|
||||
'}'
|
||||
@@ -723,11 +721,9 @@ describe('StringArrayScopeCallsWrapperTransformer', function () {
|
||||
'}';
|
||||
|
||||
const stringArrayScopeCallsWrapperRegExp1: RegExp = new RegExp(
|
||||
'const a *= *\\[.*?];.*?' +
|
||||
getStringArrayCallsWrapperMatch('f')
|
||||
);
|
||||
const stringArrayScopeCallsWrapperRegExp2: RegExp = new RegExp(
|
||||
'const a *= *\\[.*?];.*?' +
|
||||
'function test *\\( *\\) *{.*' +
|
||||
`${getStringArrayCallsWrapperMatch('g')}.*?` +
|
||||
'}'
|
||||
@@ -791,13 +787,11 @@ describe('StringArrayScopeCallsWrapperTransformer', function () {
|
||||
|
||||
describe('Variant #2: correct chained calls', () => {
|
||||
const stringArrayScopeCallsWrapperRegExp1: RegExp = new RegExp(
|
||||
'const a *= *\\[.*?];.*?' +
|
||||
'function *f *\\(c, *d\\) *{' +
|
||||
`return b\\([cd] *-(?: -)?${hexadecimalIndexMatch}, *[cd]\\);` +
|
||||
'}.*'
|
||||
);
|
||||
const stringArrayScopeCallsWrapperRegExp2: RegExp = new RegExp(
|
||||
'const a *= *\\[.*?];.*?' +
|
||||
'function test *\\( *\\) *{.*' +
|
||||
'function *g *\\(c, *d\\) *{' +
|
||||
`return f\\(` +
|
||||
@@ -863,7 +857,6 @@ describe('StringArrayScopeCallsWrapperTransformer', function () {
|
||||
|
||||
describe('Variant #3: no wrappers on a root scope', () => {
|
||||
const stringArrayScopeCallsWrapperRegExp: RegExp = new RegExp(
|
||||
'const a *= *\\[.*?];.*' +
|
||||
'function test *\\( *\\) *{.*' +
|
||||
'function *f*\\(c, *d\\) *{' +
|
||||
`return b\\([cd] *-(?: -)?${hexadecimalIndexMatch}, *[cd]\\);` +
|
||||
@@ -1088,13 +1081,11 @@ describe('StringArrayScopeCallsWrapperTransformer', function () {
|
||||
.join(', *');
|
||||
|
||||
const stringArrayScopeCallsWrapperRegExp1: RegExp = new RegExp(
|
||||
'const a *= *\\[.*?];.*?' +
|
||||
'function *f *\\(c, *d, *e, *h, *i\\) *{' +
|
||||
`return b\\([cdehi] *-(?: -)?${hexadecimalIndexMatch}, *[cdehi]\\);` +
|
||||
'}.*'
|
||||
);
|
||||
const stringArrayScopeCallsWrapperRegExp2: RegExp = new RegExp(
|
||||
'const a *= *\\[.*?];.*?' +
|
||||
'function test *\\( *\\) *{.*' +
|
||||
'function *g *\\(c, *d, *e, *h, *i\\) *{' +
|
||||
`return f\\(` +
|
||||
@@ -1169,13 +1160,11 @@ describe('StringArrayScopeCallsWrapperTransformer', function () {
|
||||
.join(', *');
|
||||
|
||||
const stringArrayScopeCallsWrapperRegExp1: RegExp = new RegExp(
|
||||
'const a *= *\\[.*?];.*?' +
|
||||
'function *f *\\(c, *d, *e, *h, *i\\) *{' +
|
||||
`return b\\([cdehi] *-(?: -)?${hexadecimalIndexMatch}, *[cdehi]\\);` +
|
||||
'}.*'
|
||||
);
|
||||
const stringArrayScopeCallsWrapperRegExp2: RegExp = new RegExp(
|
||||
'const a *= *\\[.*?];.*?' +
|
||||
'function test *\\( *\\) *{.*' +
|
||||
'function *g *\\(c, *d, *e, *h, *i\\) *{' +
|
||||
`return f\\(` +
|
||||
|
||||
+13
-7
@@ -7,6 +7,7 @@ import { StringArrayWrappersType } from '../../../../../src/enums/node-transform
|
||||
|
||||
import { NO_ADDITIONAL_NODES_PRESET } from '../../../../../src/options/presets/NoCustomNodes';
|
||||
|
||||
import { getStringArrayRegExp } from '../../../../helpers/get-string-array-regexp';
|
||||
import { readFileAsString } from '../../../../helpers/readFileAsString';
|
||||
import { getRegExpMatch } from '../../../../helpers/getRegExpMatch';
|
||||
import { swapLettersCase } from '../../../../helpers/swapLettersCase';
|
||||
@@ -17,7 +18,7 @@ describe('StringArrayTransformer', function () {
|
||||
this.timeout(120000);
|
||||
|
||||
describe('Variant #1: default behaviour', () => {
|
||||
const stringArrayRegExp: RegExp = /^var _0x([a-f0-9]){4} *= *\['test'\];/;
|
||||
const stringArrayRegExp: RegExp = getStringArrayRegExp(['test']);
|
||||
const stringArrayCallRegExp: RegExp = /var test *= *_0x([a-f0-9]){4}\(0x0\);/;
|
||||
|
||||
let obfuscatedCode: string;
|
||||
@@ -355,7 +356,7 @@ describe('StringArrayTransformer', function () {
|
||||
});
|
||||
|
||||
describe('Variant #5: same literal node values', () => {
|
||||
const stringArrayRegExp: RegExp = /^var _0x([a-f0-9]){4} *= *\['test'\];/;
|
||||
const stringArrayRegExp: RegExp = getStringArrayRegExp(['test']);
|
||||
const stringArrayCallRegExp: RegExp = /var test *= *_0x([a-f0-9]){4}\(0x0\);/;
|
||||
|
||||
let obfuscatedCode: string;
|
||||
@@ -406,7 +407,12 @@ describe('StringArrayTransformer', function () {
|
||||
});
|
||||
|
||||
describe('Variant #7: base64 encoding', () => {
|
||||
const stringArrayRegExp: RegExp = new RegExp(`^var _0x([a-f0-9]){4} *= *\\['${swapLettersCase('dGVzdA')}'];`);
|
||||
const stringArrayRegExp: RegExp = new RegExp(
|
||||
'function _0x([a-f0-9]){4} *\\(\\) *{' +
|
||||
`var _0x([a-f0-9]){4,6} *= *\\[\'${swapLettersCase('dGVzdA')}\'];.*` +
|
||||
'return _0x([a-f0-9]){4}\\(\\); *' +
|
||||
'}'
|
||||
);
|
||||
const stringArrayCallRegExp: RegExp = /var test *= *_0x([a-f0-9]){4}\(0x0\);/;
|
||||
|
||||
let obfuscatedCode: string;
|
||||
@@ -506,8 +512,8 @@ describe('StringArrayTransformer', function () {
|
||||
const expectedMatchesChance: number = 0.5;
|
||||
const expectedMatchesDelta: number = 0.15;
|
||||
|
||||
const noneEncodingRegExp: RegExp = /^var _0x([a-f0-9]){4} *= *\['test'\];/;
|
||||
const base64EncodingRegExp: RegExp = /^var _0x([a-f0-9]){4} *= *\['DgvZDa'\];/;
|
||||
const noneEncodingRegExp: RegExp = getStringArrayRegExp(['test']);
|
||||
const base64EncodingRegExp: RegExp = getStringArrayRegExp(['DgvZDa']);
|
||||
|
||||
let noneEncodingMatchesCount: number = 0;
|
||||
let base64EncodingMatchesCount: number = 0;
|
||||
@@ -1080,7 +1086,7 @@ describe('StringArrayTransformer', function () {
|
||||
|
||||
describe('Variant #16: object expression key literal', () => {
|
||||
describe('Variant #1: base key literal', () => {
|
||||
const stringArrayRegExp: RegExp = /^var _0x([a-f0-9]){4} *= *\['bar'];/;
|
||||
const stringArrayRegExp: RegExp = getStringArrayRegExp(['bar'])
|
||||
const objectExpressionRegExp: RegExp = /var test *= *{'foo' *: *_0x([a-f0-9]){4}\(0x0\)};/;
|
||||
|
||||
let obfuscatedCode: string;
|
||||
@@ -1108,7 +1114,7 @@ describe('StringArrayTransformer', function () {
|
||||
});
|
||||
|
||||
describe('Variant #2: computed key literal', () => {
|
||||
const stringArrayRegExp: RegExp = /^var _0x([a-f0-9]){4} *= *\['foo', *'bar'];/;
|
||||
const stringArrayRegExp: RegExp = getStringArrayRegExp(['foo', 'bar'])
|
||||
const objectExpressionRegExp: RegExp = /var test *= *{\[_0x([a-f0-9]){4}\(0x0\)] *: *_0x([a-f0-9]){4}\(0x1\)};/;
|
||||
|
||||
let obfuscatedCode: string;
|
||||
|
||||
+11
-10
@@ -2,6 +2,7 @@ import { assert } from 'chai';
|
||||
|
||||
import { NO_ADDITIONAL_NODES_PRESET } from '../../../../../src/options/presets/NoCustomNodes';
|
||||
|
||||
import { getStringArrayRegExp } from '../../../../helpers/get-string-array-regexp';
|
||||
import { readFileAsString } from '../../../../helpers/readFileAsString';
|
||||
|
||||
import { JavaScriptObfuscator } from '../../../../../src/JavaScriptObfuscatorFacade';
|
||||
@@ -15,7 +16,7 @@ describe('StringArrayStorage', () => {
|
||||
const delta: number = 0.1;
|
||||
const expectedVariantProbability: number = 1;
|
||||
|
||||
const stringArrayVariantRegExp: RegExp = /var _0x([a-f0-9]){4} *= *\[(?:'.*?', *)?'test'(?:, *'.*?')?];/g;
|
||||
const stringArrayVariantRegExp: RegExp = /var.*= *\[(?:'.*?', *)?'test'(?:, *'.*?')?];.*/;
|
||||
const literalNodeVariantRegExp: RegExp = /var test *= *_0x([a-f0-9]){4}\(0x.\);/g;
|
||||
|
||||
let stringArrayVariantProbability: number,
|
||||
@@ -74,8 +75,8 @@ describe('StringArrayStorage', () => {
|
||||
const literalNodeVariantsCount: number = 1;
|
||||
|
||||
const stringArrayVariantRegExps: RegExp[] = [
|
||||
/var _0x([a-f0-9]){4} *= *\['foo', *'bar', *'baz'(?:, *'.*?')+];/g,
|
||||
/var _0x([a-f0-9]){4} *= *\[(?:'.*?', *)+'foo', *'bar', *'baz'];/g
|
||||
/var.*= *\['foo', *'bar', *'baz'(?:, *'.*?')+];.*/,
|
||||
/var.*= *\[(?:'.*?', *)+'foo', *'bar', *'baz'];.*/,
|
||||
];
|
||||
const literalNodeVariantRegExps: RegExp[] = [
|
||||
new RegExp(
|
||||
@@ -155,7 +156,7 @@ describe('StringArrayStorage', () => {
|
||||
const delta: number = 0.1;
|
||||
const expectedVariantProbability: number = 1;
|
||||
|
||||
const stringArrayVariantRegExp1: RegExp = /var _0x([a-f0-9]){4} *= *\['test'];/g;
|
||||
const stringArrayVariantRegExp1: RegExp = getStringArrayRegExp(['test']);
|
||||
const literalNodeVariant1RegExp: RegExp = /var test *= *_0x([a-f0-9]){4}\(0x0\);/g;
|
||||
|
||||
let stringArrayVariant1Probability: number,
|
||||
@@ -212,12 +213,12 @@ describe('StringArrayStorage', () => {
|
||||
const variantsCount: number = 6;
|
||||
|
||||
const stringArrayVariantRegExps: RegExp[] = [
|
||||
/var _0x([a-f0-9]){4} *= *\['foo', *'bar', *'baz'];/g,
|
||||
/var _0x([a-f0-9]){4} *= *\['foo', *'baz', *'bar'];/g,
|
||||
/var _0x([a-f0-9]){4} *= *\['bar', *'foo', *'baz'];/g,
|
||||
/var _0x([a-f0-9]){4} *= *\['bar', *'baz', *'foo'];/g,
|
||||
/var _0x([a-f0-9]){4} *= *\['baz', *'foo', *'bar'];/g,
|
||||
/var _0x([a-f0-9]){4} *= *\['baz', *'bar', *'foo'];/g
|
||||
getStringArrayRegExp(['foo', 'bar', 'baz']),
|
||||
getStringArrayRegExp(['foo', 'baz', 'bar']),
|
||||
getStringArrayRegExp(['bar', 'foo', 'baz']),
|
||||
getStringArrayRegExp(['bar', 'baz', 'foo']),
|
||||
getStringArrayRegExp(['baz', 'foo', 'bar']),
|
||||
getStringArrayRegExp(['baz', 'bar', 'foo'])
|
||||
];
|
||||
|
||||
const literalNodeVariantRegExps: RegExp[] = [
|
||||
|
||||
@@ -0,0 +1,28 @@
|
||||
const defaultOptions = {
|
||||
name: '_0x([a-f0-9]){4}',
|
||||
kind: 'var'
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns string array RegExp
|
||||
*
|
||||
* @returns {RegExp}
|
||||
*/
|
||||
export function getStringArrayRegExp(
|
||||
stringArrayItems: string[],
|
||||
options: Partial<typeof defaultOptions> = {}
|
||||
): RegExp {
|
||||
const mergedOptions = {
|
||||
...defaultOptions,
|
||||
...options
|
||||
};
|
||||
|
||||
const {name, kind} = mergedOptions;
|
||||
|
||||
return new RegExp(
|
||||
`function (${name}) *\\(\\) *{` +
|
||||
`${kind}.*= *\\[${stringArrayItems.map((item: string) => `\'${item}\'`).join(',')}];.*` +
|
||||
`return ${name}\\(\\); *` +
|
||||
'}'
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
import {minify} from 'terser';
|
||||
|
||||
/**
|
||||
* Minimizes code
|
||||
*
|
||||
* @param {string} code
|
||||
* @returns {string}
|
||||
*/
|
||||
export async function minimizeCode (code: string): Promise<string> {
|
||||
const result = await minify(code);
|
||||
|
||||
return result.code ?? '';
|
||||
}
|
||||
@@ -4458,6 +4458,15 @@ terser@^5.7.0:
|
||||
source-map "~0.7.2"
|
||||
source-map-support "~0.5.19"
|
||||
|
||||
terser@^5.7.1:
|
||||
version "5.7.1"
|
||||
resolved "https://registry.yarnpkg.com/terser/-/terser-5.7.1.tgz#2dc7a61009b66bb638305cb2a824763b116bf784"
|
||||
integrity sha512-b3e+d5JbHAe/JSjwsC3Zn55wsBIM7AsHLjKxT31kGCldgbpFePaFo+PiddtO6uwRZWRw7sPXmAN8dTW61xmnSg==
|
||||
dependencies:
|
||||
commander "^2.20.0"
|
||||
source-map "~0.7.2"
|
||||
source-map-support "~0.5.19"
|
||||
|
||||
test-exclude@^6.0.0:
|
||||
version "6.0.0"
|
||||
resolved "https://registry.npmjs.org/test-exclude/-/test-exclude-6.0.0.tgz"
|
||||
|
||||
Reference in New Issue
Block a user