Mixed string array encoding prototype

This commit is contained in:
sanex
2020-08-30 12:50:49 +03:00
parent 8c91a254be
commit 752fa6baa2
34 changed files with 236 additions and 144 deletions
+4
View File
@@ -1,5 +1,9 @@
Change Log
v2.0.0
---
* **Breaking change:** `stringArrayEncoding` option now accepts array of encodings. Each string will randomly encoded with available encoding.
v1.12.0
---
* **New option:** `optionsPreset` allows to set options preset
+5 -5
View File
File diff suppressed because one or more lines are too long
+1 -1
View File
File diff suppressed because one or more lines are too long
+1 -1
View File
File diff suppressed because one or more lines are too long
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "javascript-obfuscator",
"version": "1.12.0",
"version": "2.0.0",
"description": "JavaScript obfuscator",
"keywords": [
"obfuscator",
+3 -3
View File
@@ -337,10 +337,10 @@ export class JavaScriptObfuscatorCLI implements IInitializable {
BooleanSanitizer
)
.option(
'--string-array-encoding <string|boolean>',
'--string-array-encoding <list> (comma separated, without whitespaces)',
'Encodes all strings in strings array using base64 or rc4 (this option can slow down your code speed. ' +
'Values: true, false, base64, rc4. ' +
'Default: false',
'Values: none, base64, rc4. ' +
'Default: none',
StringArrayEncodingSanitizer
)
.option(
@@ -3,21 +3,24 @@ import { TStringArrayEncoding } from '../../types/options/TStringArrayEncoding';
import { StringArrayEncoding } from '../../enums/StringArrayEncoding';
import { ArraySanitizer } from './ArraySanitizer';
/**
* @param {string} value
* @returns {TStringArrayEncoding}
* @returns {TStringArrayEncoding[]}
*/
export const StringArrayEncodingSanitizer: TCLISanitizer <TStringArrayEncoding> = (value: string): TStringArrayEncoding => {
switch (value) {
case 'true':
case '1':
case StringArrayEncoding.Base64:
return true;
export const StringArrayEncodingSanitizer: TCLISanitizer <TStringArrayEncoding[]> = (value: string): TStringArrayEncoding[] => {
const valuesAsArray: TStringArrayEncoding[] = <TStringArrayEncoding[]>ArraySanitizer(value);
case StringArrayEncoding.Rc4:
return StringArrayEncoding.Rc4;
const isCorrectStringArrayEncodings: boolean = valuesAsArray.every((item: TStringArrayEncoding) =>
Object
.values(StringArrayEncoding)
.includes(item)
);
default:
return false;
if (!isCorrectStringArrayEncodings) {
throw new ReferenceError('Invalid value of `--string-array-encoding` option');
}
return valuesAsArray;
};
@@ -3,6 +3,7 @@ import { ServiceIdentifiers } from '../../container/ServiceIdentifiers';
import { TIdentifierNamesGeneratorFactory } from '../../types/container/generators/TIdentifierNamesGeneratorFactory';
import { TStatement } from '../../types/node/TStatement';
import { TStringArrayEncoding } from '../../types/options/TStringArrayEncoding';
import { ICustomCodeHelperFormatter } from '../../interfaces/custom-code-helpers/ICustomCodeHelperFormatter';
import { ICustomCodeHelperObfuscator } from '../../interfaces/custom-code-helpers/ICustomCodeHelperObfuscator';
@@ -44,6 +45,12 @@ export class StringArrayCallsWrapperCodeHelper extends AbstractCustomCodeHelper
@initializable()
private stringArrayCallsWrapperName!: string;
/**
* @type {TStringArrayEncoding}
*/
@initializable()
private stringArrayEncoding!: TStringArrayEncoding;
/**
* @type {IEscapeSequenceEncoder}
*/
@@ -80,15 +87,18 @@ export class StringArrayCallsWrapperCodeHelper extends AbstractCustomCodeHelper
/**
* @param {string} stringArrayName
* @param {string} stringArrayCallsWrapperName
* @param {TStringArrayEncoding} stringArrayEncoding
* @param {string} atobFunctionName
*/
public initialize (
stringArrayName: string,
stringArrayCallsWrapperName: string,
stringArrayEncoding: TStringArrayEncoding,
atobFunctionName: string
): void {
this.stringArrayName = stringArrayName;
this.stringArrayCallsWrapperName = stringArrayCallsWrapperName;
this.stringArrayEncoding = stringArrayEncoding;
this.atobFunctionName = atobFunctionName;
}
@@ -147,7 +157,7 @@ export class StringArrayCallsWrapperCodeHelper extends AbstractCustomCodeHelper
);
}
switch (this.options.stringArrayEncoding) {
switch (this.stringArrayEncoding) {
case StringArrayEncoding.Rc4:
decodeStringArrayTemplate = this.customCodeHelperFormatter.formatTemplate(
StringArrayRC4DecodeTemplate(this.randomGenerator),
@@ -85,12 +85,14 @@ export class StringArrayCodeHelperGroup extends AbstractCustomCodeHelperGroup {
);
// stringArrayCallsWrapper helper nodes append
this.appendCustomNodeIfExist(
CustomCodeHelper.StringArrayCallsWrapper,
(customCodeHelper: ICustomCodeHelper<TInitialData<StringArrayCallsWrapperCodeHelper>>) => {
NodeAppender.insertAtIndex(nodeWithStatements, customCodeHelper.getNode(), 1);
}
);
for (const stringArrayEncoding of this.options.stringArrayEncoding) {
this.appendCustomNodeIfExist(
<any>`${CustomCodeHelper.StringArrayCallsWrapper}-${stringArrayEncoding}`,
(customCodeHelper: ICustomCodeHelper<TInitialData<StringArrayCallsWrapperCodeHelper>>) => {
NodeAppender.insertAtIndex(nodeWithStatements, customCodeHelper.getNode(), 1);
}
);
}
// stringArrayRotateFunction helper nodes append
this.appendCustomNodeIfExist(
@@ -108,24 +110,44 @@ export class StringArrayCodeHelperGroup extends AbstractCustomCodeHelperGroup {
return;
}
/**
* Stage 1: String Array code helper
*/
const stringArrayCodeHelper: ICustomCodeHelper<TInitialData<StringArrayCodeHelper>> =
this.customCodeHelperFactory(CustomCodeHelper.StringArray);
const stringArrayCallsWrapperCodeHelper: ICustomCodeHelper<TInitialData<StringArrayCallsWrapperCodeHelper>> =
this.customCodeHelperFactory(CustomCodeHelper.StringArrayCallsWrapper);
const stringArrayRotateFunctionCodeHelper: ICustomCodeHelper<TInitialData<StringArrayRotateFunctionCodeHelper>> =
this.customCodeHelperFactory(CustomCodeHelper.StringArrayRotateFunction);
const stringArrayName: string = this.stringArrayStorage.getStorageName();
const stringArrayCallsWrapperName: string = this.stringArrayStorage.getStorageCallsWrapperName();
const stringArrayRotationAmount: number = this.stringArrayStorage.getRotationAmount();
const atobFunctionName: string = this.randomGenerator.getRandomString(6);
stringArrayCodeHelper.initialize(this.stringArrayStorage, stringArrayName);
stringArrayCallsWrapperCodeHelper.initialize(stringArrayName, stringArrayCallsWrapperName, atobFunctionName);
stringArrayRotateFunctionCodeHelper.initialize(stringArrayName, stringArrayRotationAmount);
this.customCodeHelpers.set(CustomCodeHelper.StringArray, stringArrayCodeHelper);
this.customCodeHelpers.set(CustomCodeHelper.StringArrayCallsWrapper, stringArrayCallsWrapperCodeHelper);
/**
* Stage 2: String Array calls wrapper code helper
*/
const atobFunctionName: string = this.randomGenerator.getRandomString(6);
for (const stringArrayEncoding of this.options.stringArrayEncoding) {
const stringArrayCallsWrapperCodeHelper: ICustomCodeHelper<TInitialData<StringArrayCallsWrapperCodeHelper>> =
this.customCodeHelperFactory(CustomCodeHelper.StringArrayCallsWrapper);
const stringArrayCallsWrapperName: string = this.stringArrayStorage.getStorageCallsWrapperName(stringArrayEncoding);
stringArrayCallsWrapperCodeHelper.initialize(
stringArrayName,
stringArrayCallsWrapperName,
stringArrayEncoding,
atobFunctionName
);
this.customCodeHelpers.set(<any>`${CustomCodeHelper.StringArrayCallsWrapper}-${stringArrayEncoding}`, stringArrayCallsWrapperCodeHelper);
}
/**
* Stage 3: String Array rotate function
*/
const stringArrayRotateFunctionCodeHelper: ICustomCodeHelper<TInitialData<StringArrayRotateFunctionCodeHelper>> =
this.customCodeHelperFactory(CustomCodeHelper.StringArrayRotateFunction);
const stringArrayRotationAmount: number = this.stringArrayStorage.getRotationAmount();
stringArrayRotateFunctionCodeHelper.initialize(stringArrayName, stringArrayRotationAmount);
if (this.options.rotateStringArray) {
this.customCodeHelpers.set(CustomCodeHelper.StringArrayRotateFunction, stringArrayRotateFunctionCodeHelper);
+2
View File
@@ -1,9 +1,11 @@
import { MakeEnum } from '@gradecam/tsenum';
export const StringArrayEncoding: Readonly<{
None: 'none';
Base64: 'base64';
Rc4: 'rc4';
}> = MakeEnum({
None: 'none',
Base64: 'base64',
Rc4: 'rc4'
});
+3
View File
@@ -1,4 +1,7 @@
import { TStringArrayEncoding } from '../types/options/TStringArrayEncoding';
export interface IEncodedValue {
encoding: TStringArrayEncoding | null;
encodedValue: string;
decodeKey: string | null;
}
+1 -1
View File
@@ -40,7 +40,7 @@ export interface IOptions {
readonly splitStrings: boolean;
readonly splitStringsChunkLength: number;
readonly stringArray: boolean;
readonly stringArrayEncoding: TStringArrayEncoding;
readonly stringArrayEncoding: TStringArrayEncoding[];
readonly stringArrayThreshold: number;
readonly target: TypeFromEnum<typeof ObfuscationTarget>;
readonly transformObjectKeys: boolean;
@@ -1,6 +1,7 @@
import { IStringArrayStorageItemData } from './IStringArrayStorageItem';
import { TStringArrayEncoding } from '../../../types/options/TStringArrayEncoding';
import { IMapStorage } from '../IMapStorage';
import { IStringArrayStorageItemData } from './IStringArrayStorageItem';
export interface IStringArrayStorage extends IMapStorage <string, IStringArrayStorageItemData> {
/**
@@ -14,9 +15,10 @@ export interface IStringArrayStorage extends IMapStorage <string, IStringArraySt
getStorageName (): string;
/**
* @param {TStringArrayEncoding | null} stringArrayEncoding
* @returns {string}
*/
getStorageCallsWrapperName (): string;
getStorageCallsWrapperName (stringArrayEncoding: TStringArrayEncoding | null): string;
rotateStorage (): void;
@@ -152,7 +152,8 @@ export class StringArrayTransformer extends AbstractNodeTransformer {
const stringArrayStorageItemData: IStringArrayStorageItemData | undefined = this.stringArrayStorageAnalyzer
.getItemDataForLiteralNode(literalNode);
const cacheKey: string = `${literalValue}-${Boolean(stringArrayStorageItemData)}`;
const useCachedValue: boolean = this.nodesCache.has(cacheKey) && this.options.stringArrayEncoding !== StringArrayEncoding.Rc4;
const useCachedValue: boolean = this.nodesCache.has(cacheKey)
&& stringArrayStorageItemData?.encoding !== StringArrayEncoding.Rc4;
if (useCachedValue) {
return <ESTree.Node>this.nodesCache.get(cacheKey);
@@ -182,7 +183,7 @@ export class StringArrayTransformer extends AbstractNodeTransformer {
* @returns {Node}
*/
private getStringArrayCallNode (stringArrayStorageItemData: IStringArrayStorageItemData): ESTree.Node {
const { index, decodeKey } = stringArrayStorageItemData;
const { index, encoding, decodeKey } = stringArrayStorageItemData;
const hexadecimalIndex: string = NumberUtils.toHex(index);
const callExpressionArgs: (ESTree.Expression | ESTree.SpreadElement)[] = [
@@ -194,7 +195,7 @@ export class StringArrayTransformer extends AbstractNodeTransformer {
}
const stringArrayIdentifierNode: ESTree.Identifier = NodeFactory.identifierNode(
this.stringArrayStorage.getStorageCallsWrapperName()
this.stringArrayStorage.getStorageCallsWrapperName(encoding)
);
return NodeFactory.callExpressionNode(
+7 -4
View File
@@ -30,7 +30,6 @@ import { IdentifierNamesGenerator } from '../enums/generators/identifier-names-g
import { ObfuscationTarget } from '../enums/ObfuscationTarget';
import { OptionsPreset } from '../enums/options/presets/OptionsPreset';
import { SourceMapMode } from '../enums/source-map/SourceMapMode';
import { StringArrayEncoding } from '../enums/StringArrayEncoding';
import { DEFAULT_PRESET } from './presets/Default';
import { LOW_OBFUSCATION_PRESET } from './presets/LowObfuscation';
@@ -289,10 +288,14 @@ export class Options implements IOptions {
public readonly stringArray!: boolean;
/**
* @type {TStringArrayEncoding}
* @type {TStringArrayEncoding[]}
*/
@IsIn([true, false, StringArrayEncoding.Base64, StringArrayEncoding.Rc4])
public readonly stringArrayEncoding!: TStringArrayEncoding;
@IsArray()
@ArrayUnique()
@IsString({
each: true
})
public readonly stringArrayEncoding!: TStringArrayEncoding[];
/**
* @type {number}
@@ -9,12 +9,14 @@ import { StringArrayEncoding } from '../../enums/StringArrayEncoding';
* @returns {IOptions}
*/
export const StringArrayEncodingRule: TOptionsNormalizerRule = (options: IOptions): IOptions => {
if (options.stringArrayEncoding === true) {
if (!options.stringArrayEncoding.length) {
options = {
...options,
stringArrayEncoding: StringArrayEncoding.Base64
stringArrayEncoding: [
StringArrayEncoding.None
]
};
}
return options;
};
@@ -2,6 +2,8 @@ import { TOptionsNormalizerRule } from '../../types/options/TOptionsNormalizerRu
import { IOptions } from '../../interfaces/options/IOptions';
import { StringArrayEncoding } from '../../enums/StringArrayEncoding';
/**
* @param {IOptions} options
* @returns {IOptions}
@@ -13,7 +15,9 @@ export const StringArrayRule: TOptionsNormalizerRule = (options: IOptions): IOpt
rotateStringArray: false,
shuffleStringArray: false,
stringArray: false,
stringArrayEncoding: false,
stringArrayEncoding: [
StringArrayEncoding.None
],
stringArrayThreshold: 0
};
}
@@ -2,6 +2,8 @@ import { TOptionsNormalizerRule } from '../../types/options/TOptionsNormalizerRu
import { IOptions } from '../../interfaces/options/IOptions';
import { StringArrayEncoding } from '../../enums/StringArrayEncoding';
/**
* @param {IOptions} options
* @returns {IOptions}
@@ -12,7 +14,9 @@ export const StringArrayThresholdRule: TOptionsNormalizerRule = (options: IOptio
...options,
rotateStringArray: false,
stringArray: false,
stringArrayEncoding: false,
stringArrayEncoding: [
StringArrayEncoding.None
],
stringArrayThreshold: 0
};
}
+4 -1
View File
@@ -4,6 +4,7 @@ import { IdentifierNamesGenerator } from '../../enums/generators/identifier-name
import { ObfuscationTarget } from '../../enums/ObfuscationTarget';
import { OptionsPreset } from '../../enums/options/presets/OptionsPreset';
import { SourceMapMode } from '../../enums/source-map/SourceMapMode';
import { StringArrayEncoding } from '../../enums/StringArrayEncoding';
export const DEFAULT_PRESET: TInputOptions = Object.freeze({
compact: true,
@@ -40,7 +41,9 @@ export const DEFAULT_PRESET: TInputOptions = Object.freeze({
splitStrings: false,
splitStringsChunkLength: 10,
stringArray: true,
stringArrayEncoding: false,
stringArrayEncoding: [
StringArrayEncoding.None
],
stringArrayThreshold: 0.75,
target: ObfuscationTarget.Browser,
transformObjectKeys: false,
+3 -1
View File
@@ -13,6 +13,8 @@ export const HIGH_OBFUSCATION_PRESET: TInputOptions = Object.freeze({
debugProtectionInterval: true,
optionsPreset: OptionsPreset.HighObfuscation,
splitStringsChunkLength: 5,
stringArrayEncoding: StringArrayEncoding.Rc4,
stringArrayEncoding: [
StringArrayEncoding.Rc4
],
stringArrayThreshold: 1
});
+3 -1
View File
@@ -13,6 +13,8 @@ export const MEDIUM_OBFUSCATION_PRESET: TInputOptions = Object.freeze({
optionsPreset: OptionsPreset.MediumObfuscation,
splitStrings: true,
splitStringsChunkLength: 10,
stringArrayEncoding: StringArrayEncoding.Base64,
stringArrayEncoding: [
StringArrayEncoding.Base64
],
transformObjectKeys: true
});
+4 -1
View File
@@ -3,6 +3,7 @@ import { TInputOptions } from '../../types/options/TInputOptions';
import { IdentifierNamesGenerator } from '../../enums/generators/identifier-names-generators/IdentifierNamesGenerator';
import { ObfuscationTarget } from '../../enums/ObfuscationTarget';
import { SourceMapMode } from '../../enums/source-map/SourceMapMode';
import { StringArrayEncoding } from '../../enums/StringArrayEncoding';
export const NO_ADDITIONAL_NODES_PRESET: TInputOptions = Object.freeze({
compact: true,
@@ -37,7 +38,9 @@ export const NO_ADDITIONAL_NODES_PRESET: TInputOptions = Object.freeze({
splitStrings: false,
splitStringsChunkLength: 0,
stringArray: false,
stringArrayEncoding: false,
stringArrayEncoding: [
StringArrayEncoding.None
],
stringArrayThreshold: 0,
target: ObfuscationTarget.Browser,
transformObjectKeys: false,
+31 -13
View File
@@ -1,6 +1,8 @@
import { inject, injectable, postConstruct } from 'inversify';
import { ServiceIdentifiers } from '../../container/ServiceIdentifiers';
import { TStringArrayEncoding } from '../../types/options/TStringArrayEncoding';
import { TIdentifierNamesGeneratorFactory } from '../../types/container/generators/TIdentifierNamesGeneratorFactory';
import { IIdentifierNamesGenerator } from '../../interfaces/generators/identifier-names-generators/IIdentifierNamesGenerator';
@@ -85,9 +87,9 @@ export class StringArrayStorage extends MapStorage <string, IStringArrayStorageI
private stringArrayStorageName!: string;
/**
* @type {string}
* @type {Map<TStringArrayEncoding | null, string>}
*/
private stringArrayStorageCallsWrapperName!: string;
private readonly stringArrayStorageCallsWrapperNamesMap: Map<TStringArrayEncoding | null, string> = new Map();
/**
* @param {TIdentifierNamesGeneratorFactory} identifierNamesGeneratorFactory
@@ -136,7 +138,6 @@ export class StringArrayStorage extends MapStorage <string, IStringArrayStorageI
/**
* @param {string} value
* @returns {IStringArrayStorageItemData}
*/
public get (value: string): IStringArrayStorageItemData {
return this.getOrSetIfDoesNotExist(value);
@@ -169,15 +170,25 @@ export class StringArrayStorage extends MapStorage <string, IStringArrayStorageI
}
/**
* @param {TStringArrayEncoding | null} stringArrayEncoding
* @returns {string}
*/
public getStorageCallsWrapperName (): string {
if (!this.stringArrayStorageCallsWrapperName) {
this.stringArrayStorageCallsWrapperName = this.identifierNamesGenerator
.generateForGlobalScope(StringArrayStorage.stringArrayNameLength);
public getStorageCallsWrapperName (stringArrayEncoding: TStringArrayEncoding | null): string {
const storageCallsWrapperName: string | null = this.stringArrayStorageCallsWrapperNamesMap.get(stringArrayEncoding) ?? null;
if (storageCallsWrapperName) {
return storageCallsWrapperName;
}
return this.stringArrayStorageCallsWrapperName;
const newStorageCallsWrapperName: string = this.identifierNamesGenerator
.generateForGlobalScope(StringArrayStorage.stringArrayNameLength);
this.stringArrayStorageCallsWrapperNamesMap.set(
stringArrayEncoding,
newStorageCallsWrapperName
);
return newStorageCallsWrapperName;
}
public rotateStorage (): void {
@@ -234,7 +245,7 @@ export class StringArrayStorage extends MapStorage <string, IStringArrayStorageI
* @returns {IStringArrayStorageItemData}
*/
private getOrSetIfDoesNotExist (value: string): IStringArrayStorageItemData {
const { encodedValue, decodeKey }: IEncodedValue = this.getEncodedValue(value);
const { encodedValue, encoding, decodeKey }: IEncodedValue = this.getEncodedValue(value);
const storedStringArrayStorageItemData: IStringArrayStorageItemData | undefined = this.storage.get(encodedValue);
if (storedStringArrayStorageItemData) {
@@ -243,6 +254,7 @@ export class StringArrayStorage extends MapStorage <string, IStringArrayStorageI
const stringArrayStorageItemData: IStringArrayStorageItemData = {
encodedValue,
encoding,
decodeKey,
value,
index: this.getLength()
@@ -258,7 +270,13 @@ export class StringArrayStorage extends MapStorage <string, IStringArrayStorageI
* @returns {IEncodedValue}
*/
private getEncodedValue (value: string): IEncodedValue {
switch (this.options.stringArrayEncoding) {
const encoding: TStringArrayEncoding | null = this.options.stringArrayEncoding.length
? this.randomGenerator
.getRandomGenerator()
.pickone(this.options.stringArrayEncoding)
: null;
switch (encoding) {
/**
* For rc4 there is a possible chance of a collision between encoded values that were received from
* different source values with different keys
@@ -293,21 +311,21 @@ export class StringArrayStorage extends MapStorage <string, IStringArrayStorageI
return this.getEncodedValue(value);
}
return { encodedValue, decodeKey };
return { encodedValue, encoding, decodeKey };
}
case StringArrayEncoding.Base64: {
const decodeKey: null = null;
const encodedValue: string = this.cryptUtilsSwappedAlphabet.btoa(value);
return { encodedValue, decodeKey };
return { encodedValue, encoding, decodeKey };
}
default: {
const decodeKey: null = null;
const encodedValue: string = value;
return { encodedValue, decodeKey };
return { encodedValue, encoding, decodeKey };
}
}
}
+1 -1
View File
@@ -2,4 +2,4 @@ import { TypeFromEnum } from '@gradecam/tsenum';
import { StringArrayEncoding } from '../../enums/StringArrayEncoding';
export type TStringArrayEncoding = boolean | TypeFromEnum<typeof StringArrayEncoding>;
export type TStringArrayEncoding = TypeFromEnum<typeof StringArrayEncoding>;
+14 -9
View File
@@ -1,5 +1,7 @@
'use strict';
import { StringArrayEncoding } from '../../src/enums/StringArrayEncoding';
import { NO_ADDITIONAL_NODES_PRESET } from '../../src/options/presets/NoCustomNodes';
(function () {
@@ -7,20 +9,23 @@ import { NO_ADDITIONAL_NODES_PRESET } from '../../src/options/presets/NoCustomNo
let obfuscatedCode: string = JavaScriptObfuscator.obfuscate(
`
function func () {
var obj = {foo: 'bar'};
console.log(obj.foo);
}
var string1 = 'foo';
var string2 = 'bar';
var string3 = 'baz';
var string4 = 'bark';
func();
console.log(string1, string2, string3, string4);
`,
{
...NO_ADDITIONAL_NODES_PRESET,
compact: false,
transformObjectKeys: true,
controlFlowFlattening: true,
controlFlowFlatteningThreshold: 1
stringArray: true,
stringArrayThreshold: 1,
stringArrayEncoding: [
StringArrayEncoding.Rc4,
StringArrayEncoding.Base64,
StringArrayEncoding.None
]
}
).getObfuscatedCode();
@@ -72,7 +72,7 @@ describe('StringArrayCallsWrapperCodeHelper', () => {
identifierNamesGenerator: IdentifierNamesGenerator.MangledIdentifierNamesGenerator,
stringArray: true,
stringArrayThreshold: 1,
stringArrayEncoding: StringArrayEncoding.Base64
stringArrayEncoding: [StringArrayEncoding.Base64]
}
).getObfuscatedCode();
});
@@ -841,7 +841,7 @@ describe('JavaScriptObfuscator', () => {
renameProperties: true,
rotateStringArray: true,
stringArray: true,
stringArrayEncoding: StringArrayEncoding.Rc4,
stringArrayEncoding: [StringArrayEncoding.Rc4],
stringArrayThreshold: 1,
transformObjectKeys: true,
unicodeEscapeSequence: false
@@ -932,7 +932,7 @@ describe('JavaScriptObfuscator', () => {
{
...NO_ADDITIONAL_NODES_PRESET,
...baseParams,
stringArrayEncoding: StringArrayEncoding.Rc4
stringArrayEncoding: [StringArrayEncoding.Rc4]
}
).getObfuscatedCode();
@@ -955,7 +955,7 @@ describe('JavaScriptObfuscator', () => {
{
...NO_ADDITIONAL_NODES_PRESET,
...baseParams,
stringArrayEncoding: StringArrayEncoding.Rc4
stringArrayEncoding: [StringArrayEncoding.Rc4]
}
).getObfuscatedCode();
@@ -977,7 +977,7 @@ describe('JavaScriptObfuscator', () => {
{
...NO_ADDITIONAL_NODES_PRESET,
...baseParams,
stringArrayEncoding: StringArrayEncoding.Rc4
stringArrayEncoding: [StringArrayEncoding.Rc4]
}
).getObfuscatedCode();
});
@@ -1000,7 +1000,7 @@ describe('JavaScriptObfuscator', () => {
{
...NO_ADDITIONAL_NODES_PRESET,
...baseParams,
stringArrayEncoding: StringArrayEncoding.Rc4
stringArrayEncoding: [StringArrayEncoding.Rc4]
}
).getObfuscatedCode();
@@ -1022,7 +1022,7 @@ describe('JavaScriptObfuscator', () => {
{
...NO_ADDITIONAL_NODES_PRESET,
...baseParams,
stringArrayEncoding: StringArrayEncoding.Base64
stringArrayEncoding: [StringArrayEncoding.Base64]
}
).getObfuscatedCode();
@@ -199,7 +199,7 @@ describe('StringArrayTransformer', () => {
{
...NO_ADDITIONAL_NODES_PRESET,
stringArray: true,
stringArrayEncoding: StringArrayEncoding.Base64,
stringArrayEncoding: [StringArrayEncoding.Base64],
stringArrayThreshold: 1
}
).getObfuscatedCode();
@@ -228,7 +228,7 @@ describe('StringArrayTransformer', () => {
{
...NO_ADDITIONAL_NODES_PRESET,
stringArray: true,
stringArrayEncoding: StringArrayEncoding.Rc4,
stringArrayEncoding: [StringArrayEncoding.Rc4],
stringArrayThreshold: 1
}
).getObfuscatedCode();
@@ -257,7 +257,7 @@ describe('StringArrayTransformer', () => {
...NO_ADDITIONAL_NODES_PRESET,
seed: 1, // set seed to prevent rare case when all encoded values are the same
stringArray: true,
stringArrayEncoding: StringArrayEncoding.Rc4,
stringArrayEncoding: [StringArrayEncoding.Rc4],
stringArrayThreshold: 1
}
).getObfuscatedCode();
@@ -543,7 +543,7 @@ describe('OptionsNormalizer', () => {
...getDefaultOptions(),
shuffleStringArray: true,
stringArray: false,
stringArrayEncoding: StringArrayEncoding.Rc4,
stringArrayEncoding: [StringArrayEncoding.Rc4],
stringArrayThreshold: 0.5,
rotateStringArray: true
});
@@ -552,7 +552,7 @@ describe('OptionsNormalizer', () => {
...getDefaultOptions(),
shuffleStringArray: false,
stringArray: false,
stringArrayEncoding: false,
stringArrayEncoding: [StringArrayEncoding.None],
stringArrayThreshold: 0,
rotateStringArray: false
};
@@ -567,12 +567,14 @@ describe('OptionsNormalizer', () => {
before(() => {
optionsPreset = getNormalizedOptions({
...getDefaultOptions(),
stringArrayEncoding: true
stringArrayEncoding: []
});
expectedOptionsPreset = {
...getDefaultOptions(),
stringArrayEncoding: StringArrayEncoding.Base64
stringArrayEncoding: [
StringArrayEncoding.None
]
};
});
@@ -2,6 +2,8 @@ import { assert } from 'chai';
import { readFileAsString } from '../helpers/readFileAsString';
import { StringArrayEncoding } from '../../src/enums/StringArrayEncoding';
import { JavaScriptObfuscator } from '../../src/JavaScriptObfuscatorFacade';
const heapValueToMB = (value: number) => Math.round(value / 1024 / 1024 * 100) / 100;
@@ -41,7 +43,7 @@ describe('JavaScriptObfuscator memory', function () {
splitStrings: true,
splitStringsChunkLength: 2,
stringArray: true,
stringArrayEncoding: 'base64',
stringArrayEncoding: [StringArrayEncoding.Base64],
stringArrayThreshold: 0.75,
transformObjectKeys: true,
unicodeEscapeSequence: false
@@ -34,7 +34,7 @@ describe('JavaScriptObfuscator runtime eval', function () {
splitStrings: true,
splitStringsChunkLength: 5,
stringArray: true,
stringArrayEncoding: StringArrayEncoding.Rc4,
stringArrayEncoding: [StringArrayEncoding.Rc4],
stringArrayThreshold: 1,
transformObjectKeys: true,
unicodeEscapeSequence: true
@@ -11,6 +11,8 @@ import { IInversifyContainerFacade } from '../../../../src/interfaces/container/
import { IStringArrayStorageAnalyzer } from '../../../../src/interfaces/analyzers/string-array-storage-analyzer/IStringArrayStorageAnalyzer';
import { IStringArrayStorageItemData } from '../../../../src/interfaces/storages/string-array-storage/IStringArrayStorageItem';
import { StringArrayEncoding } from '../../../../src/enums/StringArrayEncoding';
import { InversifyContainerFacade } from '../../../../src/container/InversifyContainerFacade';
import { NodeFactory } from '../../../../src/node/NodeFactory';
import { NodeMetadata } from '../../../../src/node/NodeMetadata';
@@ -34,12 +36,14 @@ describe('StringArrayStorageAnalyzer', () => {
const expectedStringArrayStorageItemData1: IStringArrayStorageItemData = {
encodedValue: 'foo',
encoding: StringArrayEncoding.None,
decodeKey: null,
index: 0,
value: 'foo'
};
const expectedStringArrayStorageItemData2: IStringArrayStorageItemData = {
encodedValue: 'bar',
encoding: StringArrayEncoding.None,
decodeKey: null,
index: 1,
value: 'bar'
@@ -85,6 +89,7 @@ describe('StringArrayStorageAnalyzer', () => {
const expectedStringArrayStorageItemData1: IStringArrayStorageItemData = {
encodedValue: 'foo',
encoding: StringArrayEncoding.None,
decodeKey: null,
index: 0,
value: 'foo'
@@ -124,6 +129,7 @@ describe('StringArrayStorageAnalyzer', () => {
const expectedStringArrayStorageItemData1: IStringArrayStorageItemData = {
encodedValue: 'foo',
encoding: StringArrayEncoding.None,
decodeKey: null,
index: 0,
value: 'foo'
@@ -163,6 +169,7 @@ describe('StringArrayStorageAnalyzer', () => {
const expectedStringArrayStorageItemData1: IStringArrayStorageItemData = {
encodedValue: 'foo',
encoding: StringArrayEncoding.None,
decodeKey: null,
index: 0,
value: 'foo'
@@ -213,6 +220,7 @@ describe('StringArrayStorageAnalyzer', () => {
const expectedStringArrayStorageItemData1: IStringArrayStorageItemData = {
encodedValue: 'foo',
encoding: StringArrayEncoding.None,
decodeKey: null,
index: 0,
value: 'foo'
@@ -330,6 +338,7 @@ describe('StringArrayStorageAnalyzer', () => {
const expectedStringArrayStorageItemData1: undefined = undefined;
const expectedStringArrayStorageItemData2: IStringArrayStorageItemData = {
encodedValue: 'bar',
encoding: StringArrayEncoding.None,
decodeKey: null,
index: 0,
value: 'bar'
@@ -9,76 +9,62 @@ import { StringArrayEncodingSanitizer } from '../../../../src/cli/sanitizers/Str
describe('StringArrayEncodingSanitizer', () => {
describe('Variant #1: string array encoding `base64`', () => {
const inputValue: string = 'base64';
const expectedValue: TStringArrayEncoding = true;
const expectedValue: TStringArrayEncoding[] = [StringArrayEncoding.Base64];
let value: TStringArrayEncoding;
let value: TStringArrayEncoding[];
before(() => {
value = StringArrayEncodingSanitizer(inputValue);
});
it('should sanitize value', () => {
assert.equal(value, expectedValue);
assert.deepEqual(value, expectedValue);
});
});
describe('Variant #2: string array encoding `true`', () => {
const inputValue: string = 'true';
const expectedValue: TStringArrayEncoding = true;
describe('Variant #2: string array encoding `base64, rc4`', () => {
const inputValue: string = 'base64,rc4';
const expectedValue: TStringArrayEncoding[] = [
StringArrayEncoding.Base64,
StringArrayEncoding.Rc4
];
let value: TStringArrayEncoding;
let value: TStringArrayEncoding[];
before(() => {
value = StringArrayEncodingSanitizer(inputValue);
});
it('should sanitize value', () => {
assert.equal(value, expectedValue);
assert.deepEqual(value, expectedValue);
});
});
describe('Variant #3: string array encoding `1`', () => {
const inputValue: string = '1';
const expectedValue: TStringArrayEncoding = true;
let value: TStringArrayEncoding;
before(() => {
value = StringArrayEncodingSanitizer(inputValue);
});
it('should sanitize value', () => {
assert.equal(value, expectedValue);
});
});
describe('Variant #4: string array encoding `rc4`', () => {
const inputValue: string = 'rc4';
const expectedValue: TStringArrayEncoding = StringArrayEncoding.Rc4;
let value: TStringArrayEncoding;
before(() => {
value = StringArrayEncodingSanitizer(inputValue);
});
it('should sanitize value', () => {
assert.equal(value, expectedValue);
});
});
describe('Variant #5: string array encoding `foo`', () => {
describe('Variant #3: string array encoding `foo`', () => {
const inputValue: string = 'foo';
const expectedValue: TStringArrayEncoding = false;
let value: TStringArrayEncoding;
let testFunc: () => TStringArrayEncoding[];
before(() => {
value = StringArrayEncodingSanitizer(inputValue);
testFunc = () => StringArrayEncodingSanitizer(inputValue);
});
it('should sanitize value', () => {
assert.equal(value, expectedValue);
it('should throw an error for invalid encoding', () => {
assert.throws(testFunc, 'Invalid value');
});
});
describe('Variant #4: string array encoding `base64,foo`', () => {
const inputValue: string = 'base64,foo';
let testFunc: () => TStringArrayEncoding[];
before(() => {
testFunc = () => StringArrayEncodingSanitizer(inputValue);
});
it('should throw an error for invalid encoding', () => {
assert.throws(testFunc, 'Invalid value');
});
});
});
@@ -54,7 +54,7 @@ describe('StringArrayStorage', () => {
before(() => {
const stringArrayStorage: IStringArrayStorage = getStorageInstance({
stringArrayEncoding: StringArrayEncoding.Rc4
stringArrayEncoding: [StringArrayEncoding.Rc4]
});
for (let i = 0; i < samplesCount; i++) {