mirror of
https://github.com/javascript-obfuscator/javascript-obfuscator
synced 2026-08-09 12:42:29 +00:00
* Fixed identifier names generations for mangled and dictionary identifier names generators
* Fixed combination of `identifierNamesGenerator: dictionary` and `debugProtection` options * `seed` option now accepts `string` and `number` values
This commit is contained in:
@@ -1,5 +1,11 @@
|
||||
Change Log
|
||||
|
||||
v0.20.1
|
||||
---
|
||||
* Fixed identifier names generations for `mangled` and `dictionary` identifier names generators
|
||||
* Fixed combination of `identifierNamesGenerator: dictionary` and `debugProtection` options
|
||||
* `seed` option now accepts `string` and `number` values
|
||||
|
||||
v0.20.0
|
||||
---
|
||||
* **Breaking:** dropped support of Node 8 because of end of maintenance support
|
||||
|
||||
@@ -343,7 +343,7 @@ Following options are available for the JS Obfuscator:
|
||||
--reserved-names '<list>' (comma separated)
|
||||
--reserved-strings '<list>' (comma separated)
|
||||
--rotate-string-array <boolean>
|
||||
--seed <number>
|
||||
--seed <string|number>
|
||||
--self-defending <boolean>
|
||||
--source-map <boolean>
|
||||
--source-map-base-url <string>
|
||||
@@ -673,7 +673,7 @@ Shift the `stringArray` array by a fixed and random (generated at the code obfus
|
||||
This option is recommended if your original source code isn't small, as the helper function can attract attention.
|
||||
|
||||
### `seed`
|
||||
Type: `number` Default: `0`
|
||||
Type: `string|number` Default: `0`
|
||||
|
||||
This option sets seed for random generator. This is useful for creating repeatable results.
|
||||
|
||||
|
||||
Vendored
+4
-4
File diff suppressed because one or more lines are too long
Vendored
+1
-11671
File diff suppressed because one or more lines are too long
Vendored
+1
-11080
File diff suppressed because one or more lines are too long
+1
-1
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "javascript-obfuscator",
|
||||
"version": "0.20.0",
|
||||
"version": "0.20.1",
|
||||
"description": "JavaScript obfuscator",
|
||||
"keywords": [
|
||||
"obfuscator",
|
||||
|
||||
@@ -127,7 +127,7 @@ export class JavaScriptObfuscator implements IJavaScriptObfuscator {
|
||||
const timeStart: number = Date.now();
|
||||
this.logger.info(LoggingMessage.Version, process.env.VERSION);
|
||||
this.logger.info(LoggingMessage.ObfuscationStarted);
|
||||
this.logger.info(LoggingMessage.RandomGeneratorSeed, this.randomGenerator.getSeed());
|
||||
this.logger.info(LoggingMessage.RandomGeneratorSeed, this.randomGenerator.getInputSeed());
|
||||
|
||||
// parse AST tree
|
||||
const astTree: ESTree.Program = this.parseCode(sourceCode);
|
||||
|
||||
@@ -287,7 +287,7 @@ export class JavaScriptObfuscatorCLI implements IInitializable {
|
||||
BooleanSanitizer
|
||||
)
|
||||
.option(
|
||||
'--seed <number>',
|
||||
'--seed <string|number>',
|
||||
'Sets seed for random generator. This is useful for creating repeatable results.',
|
||||
parseFloat
|
||||
)
|
||||
|
||||
@@ -28,7 +28,7 @@ export const generatorsModule: interfaces.ContainerModule = new ContainerModule(
|
||||
.whenTargetNamed(IdentifierNamesGenerator.MangledIdentifierNamesGenerator);
|
||||
|
||||
// identifier name generator factory
|
||||
function identifierNameGeneratorFactory () {
|
||||
function identifierNameGeneratorFactory (): (context: interfaces.Context) => (options: IOptions) => IIdentifierNamesGenerator {
|
||||
let cachedIdentifierNamesGenerator: IIdentifierNamesGenerator | null = null;
|
||||
|
||||
return (context: interfaces.Context): (options: IOptions) => IIdentifierNamesGenerator => (options: IOptions) => {
|
||||
@@ -66,7 +66,7 @@ export const generatorsModule: interfaces.ContainerModule = new ContainerModule(
|
||||
cachedIdentifierNamesGenerator = identifierNamesGenerator;
|
||||
|
||||
return identifierNamesGenerator;
|
||||
}
|
||||
};
|
||||
}
|
||||
bind<IIdentifierNamesGenerator>(ServiceIdentifiers.Factory__IIdentifierNamesGenerator)
|
||||
.toFactory<IIdentifierNamesGenerator>(identifierNameGeneratorFactory());
|
||||
|
||||
@@ -101,7 +101,7 @@ export class StringArrayCallsWrapper extends AbstractCustomNode {
|
||||
...NO_ADDITIONAL_NODES_PRESET,
|
||||
identifierNamesGenerator: this.options.identifierNamesGenerator,
|
||||
identifiersDictionary: this.options.identifiersDictionary,
|
||||
seed: this.options.seed
|
||||
seed: this.randomGenerator.getRawSeed()
|
||||
}
|
||||
).getObfuscatedCode();
|
||||
}
|
||||
|
||||
@@ -108,7 +108,7 @@ export class StringArrayRotateFunctionNode extends AbstractCustomNode {
|
||||
...NO_ADDITIONAL_NODES_PRESET,
|
||||
identifierNamesGenerator: this.options.identifierNamesGenerator,
|
||||
identifiersDictionary: this.options.identifiersDictionary,
|
||||
seed: this.options.seed
|
||||
seed: this.randomGenerator.getRawSeed()
|
||||
}
|
||||
).getObfuscatedCode();
|
||||
}
|
||||
|
||||
Vendored
+1
-1
@@ -23,7 +23,7 @@ export interface IOptions {
|
||||
readonly reservedNames: string[];
|
||||
readonly reservedStrings: string[];
|
||||
readonly rotateStringArray: boolean;
|
||||
readonly seed: number;
|
||||
readonly seed: string | number;
|
||||
readonly selfDefending: boolean;
|
||||
readonly sourceMap: boolean;
|
||||
readonly sourceMapBaseUrl: string;
|
||||
|
||||
+7
-2
@@ -26,7 +26,12 @@ export interface IRandomGenerator {
|
||||
getRandomString (length: number, pool?: string): string;
|
||||
|
||||
/**
|
||||
* @returns {number}
|
||||
* @returns {string}
|
||||
*/
|
||||
getSeed (): number;
|
||||
getInputSeed (): string;
|
||||
|
||||
/**
|
||||
* @returns {string}
|
||||
*/
|
||||
getRawSeed (): string;
|
||||
}
|
||||
|
||||
@@ -176,10 +176,9 @@ export class Options implements IOptions {
|
||||
public readonly rotateStringArray!: boolean;
|
||||
|
||||
/**
|
||||
* @type {number}
|
||||
* @type {string | number}
|
||||
*/
|
||||
@IsNumber()
|
||||
public readonly seed!: number;
|
||||
public readonly seed!: string | number;
|
||||
|
||||
/**
|
||||
* @type {boolean}
|
||||
|
||||
@@ -10,6 +10,7 @@ import { DeadCodeInjectionRule } from './normalizer-rules/DeadCodeInjectionRule'
|
||||
import { DeadCodeInjectionThresholdRule } from './normalizer-rules/DeadCodeInjectionThresholdRule';
|
||||
import { DomainLockRule } from './normalizer-rules/DomainLockRule';
|
||||
import { InputFileNameRule } from './normalizer-rules/InputFileNameRule';
|
||||
import { SeedRule } from './normalizer-rules/SeedRule';
|
||||
import { SelfDefendingRule } from './normalizer-rules/SelfDefendingRule';
|
||||
import { SourceMapBaseUrlRule } from './normalizer-rules/SourceMapBaseUrlRule';
|
||||
import { SourceMapFileNameRule } from './normalizer-rules/SourceMapFileNameRule';
|
||||
@@ -29,6 +30,7 @@ export class OptionsNormalizer implements IOptionsNormalizer {
|
||||
DeadCodeInjectionThresholdRule,
|
||||
DomainLockRule,
|
||||
InputFileNameRule,
|
||||
SeedRule,
|
||||
SelfDefendingRule,
|
||||
SourceMapBaseUrlRule,
|
||||
SourceMapFileNameRule,
|
||||
|
||||
@@ -0,0 +1,25 @@
|
||||
import { TOptionsNormalizerRule } from '../../types/options/TOptionsNormalizerRule';
|
||||
|
||||
import { IOptions } from '../../interfaces/options/IOptions';
|
||||
|
||||
/**
|
||||
* @param {IOptions} options
|
||||
* @returns {IOptions}
|
||||
*/
|
||||
export const SeedRule: TOptionsNormalizerRule = (options: IOptions): IOptions => {
|
||||
if (options.seed) {
|
||||
return {
|
||||
...options,
|
||||
seed: options.seed
|
||||
};
|
||||
}
|
||||
|
||||
const getRandomInteger: (min: number, max: number) => number = (min: number, max: number) => {
|
||||
return Math.floor(Math.random() * (max - min + 1) + min);
|
||||
};
|
||||
|
||||
return {
|
||||
...options,
|
||||
seed: getRandomInteger(0, 999_999_999)
|
||||
};
|
||||
};
|
||||
@@ -50,10 +50,6 @@ export class StringArrayStorage extends ArrayStorage <string> {
|
||||
public initialize (): void {
|
||||
super.initialize();
|
||||
|
||||
if (!this.options.stringArray) {
|
||||
return;
|
||||
}
|
||||
|
||||
const baseStringArrayName: string = this.identifierNamesGenerator
|
||||
.generate(StringArrayStorage.stringArrayNameLength);
|
||||
const baseStringArrayCallsWrapperName: string = this.identifierNamesGenerator
|
||||
|
||||
+1
-1
@@ -6,7 +6,7 @@ export function DebugProtectionFunctionCallTemplate (): string {
|
||||
(function () {
|
||||
{singleNodeCallControllerFunctionName}(this, function () {
|
||||
var regExp1 = new RegExp('function *\\\\( *\\\\)');
|
||||
var regExp2 = new RegExp('\\\\+\\\\+ *\\(?:_0x(?:[a-f0-9]){4,6}|(?:\\\\b|\\\\d)[a-z0-9]{1,4}(?:\\\\b|\\\\d)\\)', 'i');
|
||||
var regExp2 = new RegExp('\\\\+\\\\+ *\\(?:[a-zA-Z_$][0-9a-zA-Z_$]*\\)', 'i');
|
||||
|
||||
var result = {debugProtectionFunctionName}('init');
|
||||
|
||||
|
||||
@@ -29,12 +29,6 @@ export class RandomGenerator implements IRandomGenerator, IInitializable {
|
||||
@initializable()
|
||||
private randomGenerator!: Chance.Chance;
|
||||
|
||||
/**
|
||||
* @type {number}
|
||||
*/
|
||||
@initializable()
|
||||
private seed!: number;
|
||||
|
||||
/**
|
||||
* @type {ISourceCode}
|
||||
*/
|
||||
@@ -54,24 +48,7 @@ export class RandomGenerator implements IRandomGenerator, IInitializable {
|
||||
|
||||
@postConstruct()
|
||||
public initialize (): void {
|
||||
const getRandomInteger: (min: number, max: number) => number = (min: number, max: number) => {
|
||||
return Math.floor(Math.random() * (max - min + 1) + min);
|
||||
};
|
||||
|
||||
/**
|
||||
* We need to add numbers from md5 hash of source code to input seed to prevent same String Array name
|
||||
* for different bundles with same seed
|
||||
*
|
||||
* @returns {number}
|
||||
*/
|
||||
const getSeed: () => number = (): number => {
|
||||
const md5Hash: string = md5(this.sourceCode.getSourceCode());
|
||||
|
||||
return this.seed + Number(md5Hash.replace(/\D/g, ''));
|
||||
};
|
||||
|
||||
this.seed = this.options.seed !== 0 ? this.options.seed : getRandomInteger(0, 999_999_999);
|
||||
this.randomGenerator = new Chance(getSeed());
|
||||
this.randomGenerator = new Chance(this.getRawSeed());
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -110,9 +87,28 @@ export class RandomGenerator implements IRandomGenerator, IInitializable {
|
||||
}
|
||||
|
||||
/**
|
||||
* @returns {string}
|
||||
*/
|
||||
public getInputSeed (): string {
|
||||
return this.options.seed.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* We need to add numbers from md5 hash of source code to input seed to prevent same String Array name
|
||||
* for different bundles with same seed
|
||||
*
|
||||
* @returns {number}
|
||||
*/
|
||||
public getSeed (): number {
|
||||
return this.seed;
|
||||
public getRawSeed (): string {
|
||||
const inputSeed: string = this.getInputSeed();
|
||||
const inputSeedParts: string[] = `${inputSeed}`.split('|');
|
||||
|
||||
if (inputSeedParts.length > 1) {
|
||||
return inputSeed;
|
||||
}
|
||||
|
||||
const sourceCodeMD5Hash: string = md5(this.sourceCode.getSourceCode());
|
||||
|
||||
return `${inputSeed}|${sourceCodeMD5Hash}`;
|
||||
}
|
||||
}
|
||||
|
||||
+31
-3
@@ -14,10 +14,38 @@ import { IdentifierNamesGenerator } from '../../src/enums/generators/identifier-
|
||||
`,
|
||||
{
|
||||
compact: false,
|
||||
renameGlobals: true,
|
||||
identifierNamesGenerator: IdentifierNamesGenerator.HexadecimalIdentifierNamesGenerator,
|
||||
selfDefending: false,
|
||||
disableConsoleOutput: false,
|
||||
debugProtection: false,
|
||||
debugProtectionInterval: false,
|
||||
splitStrings: true,
|
||||
splitStringsChunkLength: 5,
|
||||
splitStringsChunkLengthEnabled: true,
|
||||
stringArray: true,
|
||||
rotateStringArray: false
|
||||
rotateStringArray: false,
|
||||
rotateStringArrayEnabled: true,
|
||||
stringArrayThreshold: 1,
|
||||
stringArrayThresholdEnabled: true,
|
||||
stringArrayEncoding: false,
|
||||
stringArrayEncodingEnabled: true,
|
||||
sourceMap: false,
|
||||
sourceMapBaseUrl: "",
|
||||
sourceMapFileName: "",
|
||||
sourceMapSeparate: false,
|
||||
domainLock: [],
|
||||
reservedNames: [],
|
||||
reservedStrings: [],
|
||||
seed: 0,
|
||||
controlFlowFlatteningThreshold: 1,
|
||||
controlFlowFlattening: true,
|
||||
deadCodeInjectionThreshold: 1,
|
||||
deadCodeInjection: true,
|
||||
unicodeEscapeSequence: false,
|
||||
renameGlobals: true,
|
||||
identifierNamesGenerator: IdentifierNamesGenerator.DictionaryIdentifierNamesGenerator,
|
||||
identifiersDictionary: ["foo", "bar", "baz", "bark", "hawk", "fooz", "moscow", "chikago"],
|
||||
identifiersPrefix: "",
|
||||
transformObjectKeys: true
|
||||
}
|
||||
).getObfuscatedCode();
|
||||
|
||||
|
||||
@@ -570,7 +570,7 @@ describe('JavaScriptObfuscator', () => {
|
||||
});
|
||||
|
||||
describe('dictionary identifier names generator', () => {
|
||||
const regExp: RegExp = /var *[ab] *= *0x1; *var *[ab] *= *0x2; *var *[AB] *= *0x3;/;
|
||||
const regExp: RegExp = /var *[abc] *= *0x1; *var *[ABC] *= *0x2; *var *[ABC] *= *0x3;/;
|
||||
|
||||
let obfuscatedCode: string;
|
||||
|
||||
@@ -582,7 +582,7 @@ describe('JavaScriptObfuscator', () => {
|
||||
{
|
||||
...NO_ADDITIONAL_NODES_PRESET,
|
||||
identifierNamesGenerator: IdentifierNamesGenerator.DictionaryIdentifierNamesGenerator,
|
||||
identifiersDictionary: ['a', 'b']
|
||||
identifiersDictionary: ['a', 'b', 'c']
|
||||
}
|
||||
).getObfuscatedCode();
|
||||
});
|
||||
@@ -667,7 +667,7 @@ describe('JavaScriptObfuscator', () => {
|
||||
});
|
||||
});
|
||||
|
||||
describe('Identifier names collision between base code and appended custom nodes', () => {
|
||||
describe('Identifier names collision between base code and appended string array nodes', () => {
|
||||
const samplesCount: number = 30;
|
||||
|
||||
let areCollisionsExists: boolean = false;
|
||||
|
||||
+2
-2
@@ -121,8 +121,8 @@ describe('ClassDeclarationTransformer', () => {
|
||||
});
|
||||
|
||||
describe('Variant #3: already renamed identifiers shouldn\'t be renamed twice', () => {
|
||||
const classDeclarationRegExp: RegExp = /class *b *{/;
|
||||
const variableDeclarationsRegExp: RegExp = /let *c, *d, *e, *f;/;
|
||||
const classDeclarationRegExp: RegExp = /class *d *{/;
|
||||
const variableDeclarationsRegExp: RegExp = /let *e, *f, *g, *h;/;
|
||||
|
||||
let obfuscatedCode: string;
|
||||
|
||||
|
||||
+2
-2
@@ -145,8 +145,8 @@ describe('FunctionDeclarationTransformer', () => {
|
||||
|
||||
describe('Variant #5: already renamed identifiers shouldn\'t be renamed twice', () => {
|
||||
describe('Variant #1', () => {
|
||||
const functionDeclarationRegExp: RegExp = /function *b\(\) *{/;
|
||||
const variableDeclarationsRegExp: RegExp = /let *c, *d, *e, *f;/;
|
||||
const functionDeclarationRegExp: RegExp = /function *d\(\) *{/;
|
||||
const variableDeclarationsRegExp: RegExp = /let *e, *f, *g, *h;/;
|
||||
|
||||
let obfuscatedCode: string;
|
||||
|
||||
|
||||
+9
-9
@@ -426,11 +426,11 @@ describe('VariableDeclarationTransformer', () => {
|
||||
|
||||
describe('Variant #13: already renamed identifiers shouldn\'t be renamed twice', () => {
|
||||
describe('Variant #1', () => {
|
||||
const variableDeclarationRegExp: RegExp = /var *b *= *0x1;/;
|
||||
const functionDeclarationRegExp1: RegExp = /function *c *\(\) *{}/;
|
||||
const functionDeclarationRegExp2: RegExp = /function *d *\(\) *{}/;
|
||||
const functionDeclarationRegExp3: RegExp = /function *e *\(\) *{}/;
|
||||
const functionDeclarationRegExp4: RegExp = /function *f *\(\) *{}/;
|
||||
const variableDeclarationRegExp: RegExp = /var *d *= *0x1;/;
|
||||
const functionDeclarationRegExp1: RegExp = /function *e *\(\) *{}/;
|
||||
const functionDeclarationRegExp2: RegExp = /function *f *\(\) *{}/;
|
||||
const functionDeclarationRegExp3: RegExp = /function *g *\(\) *{}/;
|
||||
const functionDeclarationRegExp4: RegExp = /function *h *\(\) *{}/;
|
||||
|
||||
let obfuscatedCode: string;
|
||||
|
||||
@@ -468,10 +468,10 @@ describe('VariableDeclarationTransformer', () => {
|
||||
});
|
||||
|
||||
describe('Variant #2', () => {
|
||||
const variableDeclarationRegExp1: RegExp = /var *b *= *0x1;/;
|
||||
const variableDeclarationRegExp2: RegExp = /var *c;/;
|
||||
const functionDeclarationRegExp: RegExp = /function *d *\(\) *{/;
|
||||
const variableDeclarationRegExp3: RegExp = /var *d *= *function *\(\) *{}/;
|
||||
const variableDeclarationRegExp1: RegExp = /var *d *= *0x1;/;
|
||||
const variableDeclarationRegExp2: RegExp = /var *e;/;
|
||||
const functionDeclarationRegExp: RegExp = /function *f *\(\) *{/;
|
||||
const variableDeclarationRegExp3: RegExp = /var *f *= *function *\(\) *{}/;
|
||||
|
||||
let obfuscatedCode: string;
|
||||
|
||||
|
||||
@@ -33,6 +33,13 @@ function getNormalizedOptions (optionsPreset: TInputOptions): TInputOptions {
|
||||
return <TInputOptions>optionsNormalizer.normalize(options);
|
||||
}
|
||||
|
||||
function getDefaultOptions(): TInputOptions {
|
||||
return {
|
||||
...DEFAULT_PRESET,
|
||||
seed: 1 // set `seed` to the fixed value, to prevent a new seed for the each case
|
||||
};
|
||||
}
|
||||
|
||||
describe('OptionsNormalizer', () => {
|
||||
describe('normalize', () => {
|
||||
let optionsPreset: TInputOptions,
|
||||
@@ -41,13 +48,13 @@ describe('OptionsNormalizer', () => {
|
||||
describe('controlFlowFlatteningThresholdRule', () => {
|
||||
before(() => {
|
||||
optionsPreset = getNormalizedOptions({
|
||||
...DEFAULT_PRESET,
|
||||
...getDefaultOptions(),
|
||||
controlFlowFlattening: true,
|
||||
controlFlowFlatteningThreshold: 0
|
||||
});
|
||||
|
||||
expectedOptionsPreset = {
|
||||
...DEFAULT_PRESET,
|
||||
...getDefaultOptions(),
|
||||
controlFlowFlattening: false,
|
||||
controlFlowFlatteningThreshold: 0
|
||||
};
|
||||
@@ -61,7 +68,7 @@ describe('OptionsNormalizer', () => {
|
||||
describe('deadCodeInjectionRule', () => {
|
||||
before(() => {
|
||||
optionsPreset = getNormalizedOptions({
|
||||
...DEFAULT_PRESET,
|
||||
...getDefaultOptions(),
|
||||
deadCodeInjection: true,
|
||||
deadCodeInjectionThreshold: 0.4,
|
||||
stringArray: false,
|
||||
@@ -69,7 +76,7 @@ describe('OptionsNormalizer', () => {
|
||||
});
|
||||
|
||||
expectedOptionsPreset = {
|
||||
...DEFAULT_PRESET,
|
||||
...getDefaultOptions(),
|
||||
deadCodeInjection: true,
|
||||
deadCodeInjectionThreshold: 0.4,
|
||||
stringArray: true,
|
||||
@@ -86,7 +93,7 @@ describe('OptionsNormalizer', () => {
|
||||
describe('`stringArrayThreshold` option is empty', () => {
|
||||
before(() => {
|
||||
optionsPreset = getNormalizedOptions({
|
||||
...DEFAULT_PRESET,
|
||||
...getDefaultOptions(),
|
||||
deadCodeInjection: true,
|
||||
deadCodeInjectionThreshold: 0.4,
|
||||
stringArray: false,
|
||||
@@ -94,7 +101,7 @@ describe('OptionsNormalizer', () => {
|
||||
});
|
||||
|
||||
expectedOptionsPreset = {
|
||||
...DEFAULT_PRESET,
|
||||
...getDefaultOptions(),
|
||||
deadCodeInjection: true,
|
||||
deadCodeInjectionThreshold: 0.4,
|
||||
stringArray: true,
|
||||
@@ -110,7 +117,7 @@ describe('OptionsNormalizer', () => {
|
||||
describe('`stringArrayThreshold` option is not empty', () => {
|
||||
before(() => {
|
||||
optionsPreset = getNormalizedOptions({
|
||||
...DEFAULT_PRESET,
|
||||
...getDefaultOptions(),
|
||||
deadCodeInjection: true,
|
||||
deadCodeInjectionThreshold: 0.4,
|
||||
stringArray: false,
|
||||
@@ -118,7 +125,7 @@ describe('OptionsNormalizer', () => {
|
||||
});
|
||||
|
||||
expectedOptionsPreset = {
|
||||
...DEFAULT_PRESET,
|
||||
...getDefaultOptions(),
|
||||
deadCodeInjection: true,
|
||||
deadCodeInjectionThreshold: 0.4,
|
||||
stringArray: true,
|
||||
@@ -135,13 +142,13 @@ describe('OptionsNormalizer', () => {
|
||||
describe('deadCodeInjectionThresholdRule', () => {
|
||||
before(() => {
|
||||
optionsPreset = getNormalizedOptions({
|
||||
...DEFAULT_PRESET,
|
||||
...getDefaultOptions(),
|
||||
deadCodeInjection: true,
|
||||
deadCodeInjectionThreshold: 0
|
||||
});
|
||||
|
||||
expectedOptionsPreset = {
|
||||
...DEFAULT_PRESET,
|
||||
...getDefaultOptions(),
|
||||
deadCodeInjection: false,
|
||||
deadCodeInjectionThreshold: 0
|
||||
};
|
||||
@@ -155,7 +162,7 @@ describe('OptionsNormalizer', () => {
|
||||
describe('domainLockRule', () => {
|
||||
before(() => {
|
||||
optionsPreset = getNormalizedOptions({
|
||||
...DEFAULT_PRESET,
|
||||
...getDefaultOptions(),
|
||||
domainLock: [
|
||||
'//localhost:9000',
|
||||
'https://google.ru/abc?cde=fgh'
|
||||
@@ -163,7 +170,7 @@ describe('OptionsNormalizer', () => {
|
||||
});
|
||||
|
||||
expectedOptionsPreset = {
|
||||
...DEFAULT_PRESET,
|
||||
...getDefaultOptions(),
|
||||
domainLock: [
|
||||
'localhost',
|
||||
'google.ru'
|
||||
@@ -180,12 +187,12 @@ describe('OptionsNormalizer', () => {
|
||||
describe('Variant #1: extension isn\'t set', () => {
|
||||
before(() => {
|
||||
optionsPreset = getNormalizedOptions({
|
||||
...DEFAULT_PRESET,
|
||||
...getDefaultOptions(),
|
||||
inputFileName: 'foo'
|
||||
});
|
||||
|
||||
expectedOptionsPreset = {
|
||||
...DEFAULT_PRESET,
|
||||
...getDefaultOptions(),
|
||||
inputFileName: 'foo.js'
|
||||
};
|
||||
});
|
||||
@@ -198,12 +205,12 @@ describe('OptionsNormalizer', () => {
|
||||
describe('Variant #2: extension is set', () => {
|
||||
before(() => {
|
||||
optionsPreset = getNormalizedOptions({
|
||||
...DEFAULT_PRESET,
|
||||
...getDefaultOptions(),
|
||||
inputFileName: 'foo.js'
|
||||
});
|
||||
|
||||
expectedOptionsPreset = {
|
||||
...DEFAULT_PRESET,
|
||||
...getDefaultOptions(),
|
||||
inputFileName: 'foo.js'
|
||||
};
|
||||
});
|
||||
@@ -216,12 +223,12 @@ describe('OptionsNormalizer', () => {
|
||||
describe('Variant #3: extension in set with `.map` postfix', () => {
|
||||
before(() => {
|
||||
optionsPreset = getNormalizedOptions({
|
||||
...DEFAULT_PRESET,
|
||||
...getDefaultOptions(),
|
||||
inputFileName: 'foo.map.js'
|
||||
});
|
||||
|
||||
expectedOptionsPreset = {
|
||||
...DEFAULT_PRESET,
|
||||
...getDefaultOptions(),
|
||||
inputFileName: 'foo.map.js'
|
||||
};
|
||||
});
|
||||
@@ -234,12 +241,12 @@ describe('OptionsNormalizer', () => {
|
||||
describe('Variant #4: no file name', () => {
|
||||
before(() => {
|
||||
optionsPreset = getNormalizedOptions({
|
||||
...DEFAULT_PRESET,
|
||||
...getDefaultOptions(),
|
||||
inputFileName: ''
|
||||
});
|
||||
|
||||
expectedOptionsPreset = {
|
||||
...DEFAULT_PRESET,
|
||||
...getDefaultOptions(),
|
||||
inputFileName: ''
|
||||
};
|
||||
});
|
||||
@@ -250,16 +257,72 @@ describe('OptionsNormalizer', () => {
|
||||
});
|
||||
});
|
||||
|
||||
describe('seedRule', () => {
|
||||
describe('Variant #1: seed value is string', () => {
|
||||
before(() => {
|
||||
optionsPreset = getNormalizedOptions({
|
||||
...getDefaultOptions(),
|
||||
seed: 'abc'
|
||||
});
|
||||
|
||||
expectedOptionsPreset = {
|
||||
...getDefaultOptions(),
|
||||
seed: 'abc'
|
||||
};
|
||||
});
|
||||
|
||||
it('should not normalize options preset', () => {
|
||||
assert.deepEqual(optionsPreset, expectedOptionsPreset);
|
||||
});
|
||||
});
|
||||
|
||||
describe('Variant #2: seed value is number', () => {
|
||||
before(() => {
|
||||
optionsPreset = getNormalizedOptions({
|
||||
...getDefaultOptions(),
|
||||
seed: 123
|
||||
});
|
||||
|
||||
expectedOptionsPreset = {
|
||||
...getDefaultOptions(),
|
||||
seed: 123
|
||||
};
|
||||
});
|
||||
|
||||
it('should normalize options preset', () => {
|
||||
assert.deepEqual(optionsPreset, expectedOptionsPreset);
|
||||
});
|
||||
});
|
||||
|
||||
describe('Variant #3: seed value is `0``', () => {
|
||||
let seedValue: number;
|
||||
|
||||
before(() => {
|
||||
optionsPreset = getNormalizedOptions({
|
||||
...getDefaultOptions(),
|
||||
seed: 0
|
||||
});
|
||||
|
||||
seedValue = Number(optionsPreset.seed);
|
||||
});
|
||||
|
||||
it('should normalize seed value', () => {
|
||||
assert.isAtLeast(seedValue, 0);
|
||||
assert.isBelow(seedValue, 999_999_999);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('selfDefendingRule', () => {
|
||||
before(() => {
|
||||
optionsPreset = getNormalizedOptions({
|
||||
...DEFAULT_PRESET,
|
||||
...getDefaultOptions(),
|
||||
selfDefending: true,
|
||||
compact: false
|
||||
});
|
||||
|
||||
expectedOptionsPreset = {
|
||||
...DEFAULT_PRESET,
|
||||
...getDefaultOptions(),
|
||||
selfDefending: true,
|
||||
compact: true
|
||||
};
|
||||
@@ -274,12 +337,12 @@ describe('OptionsNormalizer', () => {
|
||||
describe('Variant #1: only source map base url', () => {
|
||||
before(() => {
|
||||
optionsPreset = getNormalizedOptions({
|
||||
...DEFAULT_PRESET,
|
||||
...getDefaultOptions(),
|
||||
sourceMapBaseUrl: 'http://localhost:9000',
|
||||
});
|
||||
|
||||
expectedOptionsPreset = {
|
||||
...DEFAULT_PRESET,
|
||||
...getDefaultOptions(),
|
||||
sourceMapBaseUrl: ''
|
||||
};
|
||||
});
|
||||
@@ -292,13 +355,13 @@ describe('OptionsNormalizer', () => {
|
||||
describe('Variant #2: source map base url with source map file name', () => {
|
||||
before(() => {
|
||||
optionsPreset = getNormalizedOptions({
|
||||
...DEFAULT_PRESET,
|
||||
...getDefaultOptions(),
|
||||
sourceMapBaseUrl: 'http://localhost:9000',
|
||||
sourceMapFileName: '/outputSourceMapName.map'
|
||||
});
|
||||
|
||||
expectedOptionsPreset = {
|
||||
...DEFAULT_PRESET,
|
||||
...getDefaultOptions(),
|
||||
sourceMapBaseUrl: 'http://localhost:9000/',
|
||||
sourceMapFileName: 'outputSourceMapName.js.map'
|
||||
};
|
||||
@@ -313,13 +376,13 @@ describe('OptionsNormalizer', () => {
|
||||
describe('sourceMapFileNameRule', () => {
|
||||
before(() => {
|
||||
optionsPreset = getNormalizedOptions({
|
||||
...DEFAULT_PRESET,
|
||||
...getDefaultOptions(),
|
||||
sourceMapBaseUrl: 'http://localhost:9000',
|
||||
sourceMapFileName: '//outputSourceMapName'
|
||||
});
|
||||
|
||||
expectedOptionsPreset = {
|
||||
...DEFAULT_PRESET,
|
||||
...getDefaultOptions(),
|
||||
sourceMapBaseUrl: 'http://localhost:9000/',
|
||||
sourceMapFileName: 'outputSourceMapName.js.map'
|
||||
};
|
||||
@@ -334,13 +397,13 @@ describe('OptionsNormalizer', () => {
|
||||
describe('`splitStringsChunkLengthRule` value is float number', () => {
|
||||
before(() => {
|
||||
optionsPreset = getNormalizedOptions({
|
||||
...DEFAULT_PRESET,
|
||||
...getDefaultOptions(),
|
||||
splitStrings: true,
|
||||
splitStringsChunkLength: 5.6
|
||||
});
|
||||
|
||||
expectedOptionsPreset = {
|
||||
...DEFAULT_PRESET,
|
||||
...getDefaultOptions(),
|
||||
splitStrings: true,
|
||||
splitStringsChunkLength: 5
|
||||
};
|
||||
@@ -355,7 +418,7 @@ describe('OptionsNormalizer', () => {
|
||||
describe('stringArrayRule', () => {
|
||||
before(() => {
|
||||
optionsPreset = getNormalizedOptions({
|
||||
...DEFAULT_PRESET,
|
||||
...getDefaultOptions(),
|
||||
stringArray: false,
|
||||
stringArrayEncoding: StringArrayEncoding.Rc4,
|
||||
stringArrayThreshold: 0.5,
|
||||
@@ -363,7 +426,7 @@ describe('OptionsNormalizer', () => {
|
||||
});
|
||||
|
||||
expectedOptionsPreset = {
|
||||
...DEFAULT_PRESET,
|
||||
...getDefaultOptions(),
|
||||
stringArray: false,
|
||||
stringArrayEncoding: false,
|
||||
stringArrayThreshold: 0,
|
||||
@@ -379,12 +442,12 @@ describe('OptionsNormalizer', () => {
|
||||
describe('stringArrayEncodingRule', () => {
|
||||
before(() => {
|
||||
optionsPreset = getNormalizedOptions({
|
||||
...DEFAULT_PRESET,
|
||||
...getDefaultOptions(),
|
||||
stringArrayEncoding: true
|
||||
});
|
||||
|
||||
expectedOptionsPreset = {
|
||||
...DEFAULT_PRESET,
|
||||
...getDefaultOptions(),
|
||||
stringArrayEncoding: StringArrayEncoding.Base64
|
||||
};
|
||||
});
|
||||
@@ -397,14 +460,14 @@ describe('OptionsNormalizer', () => {
|
||||
describe('stringArrayThresholdRule', () => {
|
||||
before(() => {
|
||||
optionsPreset = getNormalizedOptions({
|
||||
...DEFAULT_PRESET,
|
||||
...getDefaultOptions(),
|
||||
rotateStringArray: true,
|
||||
stringArray: true,
|
||||
stringArrayThreshold: 0
|
||||
});
|
||||
|
||||
expectedOptionsPreset = {
|
||||
...DEFAULT_PRESET,
|
||||
...getDefaultOptions(),
|
||||
rotateStringArray: false,
|
||||
stringArray: false,
|
||||
stringArrayThreshold: 0
|
||||
|
||||
+77
-39
@@ -5,6 +5,7 @@ import { readFileAsString } from '../../../helpers/readFileAsString';
|
||||
|
||||
import { NO_ADDITIONAL_NODES_PRESET } from '../../../../src/options/presets/NoCustomNodes';
|
||||
|
||||
import { IdentifierNamesGenerator } from '../../../../src/enums/generators/identifier-names-generators/IdentifierNamesGenerator';
|
||||
import { ObfuscationTarget } from '../../../../src/enums/ObfuscationTarget';
|
||||
|
||||
import { JavaScriptObfuscator } from '../../../../src/JavaScriptObfuscatorFacade';
|
||||
@@ -29,41 +30,7 @@ function spawnThread(inputCallback: Function, threadCallback: Function, timeoutC
|
||||
}
|
||||
|
||||
describe('DebugProtectionFunctionCallTemplate', () => {
|
||||
describe('Variant #1: correctly obfuscated code`', () => {
|
||||
const expectedEvaluationResult: number = 1;
|
||||
|
||||
let obfuscatedCode: string,
|
||||
evaluationResult: number = 0;
|
||||
|
||||
beforeEach((done) => {
|
||||
const code: string = readFileAsString(__dirname + '/fixtures/input.js');
|
||||
|
||||
obfuscatedCode = JavaScriptObfuscator.obfuscate(
|
||||
code,
|
||||
{
|
||||
...NO_ADDITIONAL_NODES_PRESET,
|
||||
debugProtection: true
|
||||
}
|
||||
).getObfuscatedCode();
|
||||
|
||||
spawnThread(
|
||||
() => obfuscatedCode,
|
||||
(response: number) => {
|
||||
evaluationResult = response;
|
||||
done();
|
||||
},
|
||||
() => {
|
||||
done();
|
||||
}
|
||||
);
|
||||
});
|
||||
|
||||
it('should correctly evaluate code with enabled debug protection', () => {
|
||||
assert.equal(evaluationResult, expectedEvaluationResult);
|
||||
});
|
||||
});
|
||||
|
||||
describe('Variant #2: correctly obfuscated code with enabled `mangle` option', () => {
|
||||
describe('Variant #1: correctly obfuscate code with `HexadecimalIdentifierNamesGenerator``', () => {
|
||||
const expectedEvaluationResult: number = 1;
|
||||
|
||||
let obfuscatedCode: string,
|
||||
@@ -77,7 +44,7 @@ describe('DebugProtectionFunctionCallTemplate', () => {
|
||||
{
|
||||
...NO_ADDITIONAL_NODES_PRESET,
|
||||
debugProtection: true,
|
||||
mangle: true
|
||||
identifierNamesGenerator: IdentifierNamesGenerator.HexadecimalIdentifierNamesGenerator
|
||||
}
|
||||
).getObfuscatedCode();
|
||||
|
||||
@@ -98,7 +65,78 @@ describe('DebugProtectionFunctionCallTemplate', () => {
|
||||
});
|
||||
});
|
||||
|
||||
describe('Variant #3: correctly obfuscated code with target `extension`', () => {
|
||||
describe('Variant #2: correctly obfuscate code with `MangledIdentifierNamesGenerator` option', () => {
|
||||
const expectedEvaluationResult: number = 1;
|
||||
|
||||
let obfuscatedCode: string,
|
||||
evaluationResult: number = 0;
|
||||
|
||||
beforeEach((done) => {
|
||||
const code: string = readFileAsString(__dirname + '/fixtures/input.js');
|
||||
|
||||
obfuscatedCode = JavaScriptObfuscator.obfuscate(
|
||||
code,
|
||||
{
|
||||
...NO_ADDITIONAL_NODES_PRESET,
|
||||
debugProtection: true,
|
||||
identifierNamesGenerator: IdentifierNamesGenerator.MangledIdentifierNamesGenerator
|
||||
}
|
||||
).getObfuscatedCode();
|
||||
|
||||
spawnThread(
|
||||
() => obfuscatedCode,
|
||||
(response: number) => {
|
||||
evaluationResult = response;
|
||||
done();
|
||||
},
|
||||
() => {
|
||||
done();
|
||||
}
|
||||
);
|
||||
});
|
||||
|
||||
it('should correctly evaluate code with enabled debug protection', () => {
|
||||
assert.equal(evaluationResult, expectedEvaluationResult);
|
||||
});
|
||||
});
|
||||
|
||||
describe('Variant #3: correctly obfuscate code with `DictionaryIdentifierNamesGenerator` option', () => {
|
||||
const expectedEvaluationResult: number = 1;
|
||||
|
||||
let obfuscatedCode: string,
|
||||
evaluationResult: number = 0;
|
||||
|
||||
beforeEach((done) => {
|
||||
const code: string = readFileAsString(__dirname + '/fixtures/input.js');
|
||||
|
||||
obfuscatedCode = JavaScriptObfuscator.obfuscate(
|
||||
code,
|
||||
{
|
||||
...NO_ADDITIONAL_NODES_PRESET,
|
||||
debugProtection: true,
|
||||
identifierNamesGenerator: IdentifierNamesGenerator.DictionaryIdentifierNamesGenerator,
|
||||
identifiersDictionary: ['foo', 'bar', 'baz', 'bark', 'hawk', 'eagle']
|
||||
}
|
||||
).getObfuscatedCode();
|
||||
|
||||
spawnThread(
|
||||
() => obfuscatedCode,
|
||||
(response: number) => {
|
||||
evaluationResult = response;
|
||||
done();
|
||||
},
|
||||
() => {
|
||||
done();
|
||||
}
|
||||
);
|
||||
});
|
||||
|
||||
it('should correctly evaluate code with enabled debug protection', () => {
|
||||
assert.equal(evaluationResult, expectedEvaluationResult);
|
||||
});
|
||||
});
|
||||
|
||||
describe('Variant #4: correctly obfuscated code with target `BrowserNoEval`', () => {
|
||||
const expectedEvaluationResult: number = 1;
|
||||
|
||||
let obfuscatedCode: string,
|
||||
@@ -133,7 +171,7 @@ describe('DebugProtectionFunctionCallTemplate', () => {
|
||||
});
|
||||
});
|
||||
|
||||
describe('Variant #4: obfuscated code with removed debug protection code', () => {
|
||||
describe('Variant #5: obfuscated code with removed debug protection code', () => {
|
||||
const expectedEvaluationResult: number = 0;
|
||||
|
||||
let obfuscatedCode: string,
|
||||
@@ -168,7 +206,7 @@ describe('DebugProtectionFunctionCallTemplate', () => {
|
||||
});
|
||||
});
|
||||
|
||||
describe('Variant #5: single call of debug protection code', () => {
|
||||
describe('Variant #6: single call of debug protection code', () => {
|
||||
const expectedEvaluationResult: number = 1;
|
||||
|
||||
let obfuscatedCode: string,
|
||||
|
||||
Reference in New Issue
Block a user