0.28.0 release

Support of BigInt
This commit is contained in:
sanex3339
2020-04-25 12:12:07 +03:00
parent 87bf2096cc
commit fb834c8de1
19 changed files with 164 additions and 52 deletions
+2 -1
View File
@@ -1,7 +1,8 @@
Change Log
v0.27.5
v0.28.0
---
* Added BigInt support. https://github.com/javascript-obfuscator/javascript-obfuscator/issues/588
* Fixed https://github.com/javascript-obfuscator/javascript-obfuscator/issues/554
v0.27.4
+4 -4
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": "0.27.4",
"version": "0.28.0",
"description": "JavaScript obfuscator",
"keywords": [
"obfuscator",
@@ -11,6 +11,6 @@ export function StringArrayRotateFunctionTemplate (): string {
};
{code}
})({stringArrayName}, 0x{stringArrayRotationAmount});
})({stringArrayName}, {stringArrayRotationAmount});
`;
}
@@ -37,12 +37,11 @@ export class HexadecimalIdentifierNamesGenerator extends AbstractIdentifierNames
const rangeMaxInteger: number = 99_999_999;
const randomInteger: number = this.randomGenerator.getRandomInteger(rangeMinInteger, rangeMaxInteger);
const hexadecimalNumber: string = NumberUtils.toHex(randomInteger);
const prefixLength: number = Utils.hexadecimalPrefix.length + 1;
const baseNameLength: number = nameLength
? nameLength - prefixLength
: HexadecimalIdentifierNamesGenerator.baseIdentifierNameLength;
const prefixLength: number = Utils.hexadecimalPrefix.length;
const baseNameLength: number = (nameLength ?? HexadecimalIdentifierNamesGenerator.baseIdentifierNameLength)
+ prefixLength;
const baseIdentifierName: string = hexadecimalNumber.substr(0, baseNameLength);
const identifierName: string = `_${Utils.hexadecimalPrefix}${baseIdentifierName}`;
const identifierName: string = `_${baseIdentifierName}`;
if (!this.isValidIdentifierName(identifierName)) {
return this.generateNext(nameLength);
@@ -118,6 +118,7 @@ export class LiteralTransformer extends AbstractNodeTransformer {
break;
case 'number':
case 'bigint':
newLiteralNode = this.literalObfuscatingReplacerFactory(
LiteralObfuscatingReplacer.NumberLiteralObfuscatingReplacer
).replace(literalNode);
@@ -8,7 +8,6 @@ import { IOptions } from '../../../../interfaces/options/IOptions';
import { AbstractObfuscatingReplacer } from '../AbstractObfuscatingReplacer';
import { NodeFactory } from '../../../../node/NodeFactory';
import { NumberUtils } from '../../../../utils/NumberUtils';
import { Utils } from '../../../../utils/Utils';
@injectable()
export class NumberLiteralObfuscatingReplacer extends AbstractObfuscatingReplacer {
@@ -33,8 +32,8 @@ export class NumberLiteralObfuscatingReplacer extends AbstractObfuscatingReplace
public replace (literalNode: ESTree.SimpleLiteral): ESTree.Node {
const literalValue: ESTree.SimpleLiteral['value'] = literalNode.value;
if (typeof literalValue !== 'number') {
throw new Error('`NumberLiteralObfuscatingReplacer` should accept only literals with `number` value');
if (typeof literalValue !== 'number' && typeof literalValue !== 'bigint') {
throw new Error('`NumberLiteralObfuscatingReplacer` should accept only literals with `number` and `bigint` value');
}
let rawValue: string;
@@ -42,10 +41,10 @@ export class NumberLiteralObfuscatingReplacer extends AbstractObfuscatingReplace
if (this.numberLiteralCache.has(literalValue)) {
rawValue = <string>this.numberLiteralCache.get(literalValue);
} else {
if (!NumberUtils.isCeil(literalValue)) {
rawValue = String(literalValue);
if (NumberUtils.isCeil(literalValue)) {
rawValue = NumberUtils.toHex(literalValue);
} else {
rawValue = `${Utils.hexadecimalPrefix}${NumberUtils.toHex(literalValue)}`;
rawValue = String(literalValue);
}
this.numberLiteralCache.set(literalValue, rawValue);
@@ -15,7 +15,6 @@ import { AbstractObfuscatingReplacer } from '../AbstractObfuscatingReplacer';
import { NodeMetadata } from '../../../../node/NodeMetadata';
import { NodeFactory } from '../../../../node/NodeFactory';
import { NumberUtils } from '../../../../utils/NumberUtils';
import { Utils } from '../../../../utils/Utils';
@injectable()
export class StringLiteralObfuscatingReplacer extends AbstractObfuscatingReplacer implements IInitializable {
@@ -129,7 +128,7 @@ export class StringLiteralObfuscatingReplacer extends AbstractObfuscatingReplace
private replaceWithStringArrayCallNode (stringArrayStorageItemData: IStringArrayStorageItemData): ESTree.Node {
const { index, decodeKey } = stringArrayStorageItemData;
const hexadecimalIndex: string = `${Utils.hexadecimalPrefix}${NumberUtils.toHex(index)}`;
const hexadecimalIndex: string = NumberUtils.toHex(index);
const callExpressionArgs: (ESTree.Expression | ESTree.SpreadElement)[] = [
StringLiteralObfuscatingReplacer.getHexadecimalLiteralNode(hexadecimalIndex)
];
@@ -42,7 +42,7 @@ export class StringArrayStorage extends MapStorage <string, IStringArrayStorageI
/**
* @type {number}
*/
private static readonly stringArrayNameLength: number = 7;
private static readonly stringArrayNameLength: number = 4;
/**
* @type {IArrayUtils}
+13 -5
View File
@@ -1,19 +1,27 @@
import { Utils } from './Utils';
export class NumberUtils {
/**
* @param {number} dec
* @param {number} number
* @returns {string}
*/
public static toHex (dec: number): string {
public static toHex (number: number | bigint): string {
const radix: number = 16;
return dec.toString(radix);
const basePart: string = typeof number === 'number'
? number.toString(radix)
: `${number.toString(radix)}n`;
return `${Utils.hexadecimalPrefix}${basePart}`;
}
/**
* @param {number} number
* @returns {boolean}
*/
public static isCeil (number: number): boolean {
return number % 1 === 0;
public static isCeil (number: number | bigint): boolean {
return typeof number === 'number'
? number % 1 === 0
: true;
}
}
+4 -4
View File
@@ -7,13 +7,13 @@ import { NO_ADDITIONAL_NODES_PRESET } from '../../src/options/presets/NoCustomNo
let obfuscatedCode: string = JavaScriptObfuscator.obfuscate(
`
var a, b;
({a, ...b} = {a: 1, b: 2, c: 3});
var foo = 'abc';
`,
{
...NO_ADDITIONAL_NODES_PRESET,
compact: false,
renameGlobals: true
renameGlobals: true,
stringArray: true,
stringArrayThreshold: 1
}
).getObfuscatedCode();
@@ -613,6 +613,27 @@ describe('JavaScriptObfuscator', () => {
});
});
describe('BigInt support', () => {
const regExp: RegExp = /return 0x20000000000001n *\+ *0xan *\+ *0xan;/;
let obfuscatedCode: string;
beforeEach(() => {
const code: string = readFileAsString(__dirname + '/fixtures/bigint-support.js');
obfuscatedCode = JavaScriptObfuscator.obfuscate(
code,
{
...NO_ADDITIONAL_NODES_PRESET
}
).getObfuscatedCode();
});
it('should support BigInt', () => {
assert.match(obfuscatedCode, regExp);
});
});
describe('mangled identifier names generator', () => {
const regExp: RegExp = /var c *= *0x1/;
@@ -0,0 +1,3 @@
function test() {
return 9007199254740993n + 10n + 0xan;
}
@@ -624,6 +624,29 @@ describe('LiteralTransformer', () => {
});
});
describe('transformation of literal node with bigint value', () => {
const regExp: RegExp = /^var test *= *0xan;$/;
let obfuscatedCode: string;
before(() => {
const code: string = readFileAsString(__dirname + '/fixtures/bigint-value.js');
obfuscatedCode = JavaScriptObfuscator.obfuscate(
code,
{
...NO_ADDITIONAL_NODES_PRESET,
stringArray: true,
stringArrayThreshold: 1
}
).getObfuscatedCode();
});
it('should transform literal node', () => {
assert.match(obfuscatedCode, regExp);
});
});
describe('RegExp literal', () => {
const regExp: RegExp = /^var regExp *= *\/\(\\d\+\)\/;$/;
@@ -13,30 +13,55 @@ import { InversifyContainerFacade } from '../../../../src/container/InversifyCon
describe('HexadecimalIdentifierNamesGenerator', () => {
describe('generateNext', () => {
let identifierNamesGenerator: IIdentifierNamesGenerator,
hexadecimalIdentifierName: string,
regExp: RegExp;
describe('Base', () => {
let identifierNamesGenerator: IIdentifierNamesGenerator,
hexadecimalIdentifierName: string,
regExp: RegExp;
before(() => {
const inversifyContainerFacade: IInversifyContainerFacade = new InversifyContainerFacade();
before(() => {
const inversifyContainerFacade: IInversifyContainerFacade = new InversifyContainerFacade();
inversifyContainerFacade.load('', '', {});
identifierNamesGenerator = inversifyContainerFacade.getNamed<IIdentifierNamesGenerator>(
ServiceIdentifiers.IIdentifierNamesGenerator,
IdentifierNamesGenerator.HexadecimalIdentifierNamesGenerator
);
inversifyContainerFacade.load('', '', {});
identifierNamesGenerator = inversifyContainerFacade.getNamed<IIdentifierNamesGenerator>(
ServiceIdentifiers.IIdentifierNamesGenerator,
IdentifierNamesGenerator.HexadecimalIdentifierNamesGenerator
);
hexadecimalIdentifierName = identifierNamesGenerator.generateNext();
regExp = /^_0x(\w){4,6}$/;
hexadecimalIdentifierName = identifierNamesGenerator.generateNext();
regExp = /^_0x(\w){6}$/;
});
it('should return hexadecimal name', () => {
assert.match(hexadecimalIdentifierName, regExp);
})
});
it('should return hexadecimal name', () => {
assert.match(hexadecimalIdentifierName, regExp);
})
describe('Custom length', () => {
let identifierNamesGenerator: IIdentifierNamesGenerator,
hexadecimalIdentifierName: string,
regExp: RegExp;
before(() => {
const inversifyContainerFacade: IInversifyContainerFacade = new InversifyContainerFacade();
inversifyContainerFacade.load('', '', {});
identifierNamesGenerator = inversifyContainerFacade.getNamed<IIdentifierNamesGenerator>(
ServiceIdentifiers.IIdentifierNamesGenerator,
IdentifierNamesGenerator.HexadecimalIdentifierNamesGenerator
);
hexadecimalIdentifierName = identifierNamesGenerator.generateNext(4);
regExp = /^_0x(\w){4}$/;
});
it('should return hexadecimal name', () => {
assert.match(hexadecimalIdentifierName, regExp);
})
});
});
describe('generateForGlobalScope', () => {
const regExp: RegExp = /^foo_0x(\w){4,6}$/;
const regExp: RegExp = /^foo_0x(\w){6}$/;
let identifierNamesGenerator: IIdentifierNamesGenerator,
hexadecimalIdentifierName: string;
+36 -4
View File
@@ -6,7 +6,7 @@ describe('NumberUtils', () => {
describe('toHex', () => {
describe('Variant #1: number `0`', () => {
const number: number = 0;
const expectedHexString = '0';
const expectedHexString = '0x0';
let hexString: string;
@@ -21,7 +21,7 @@ describe('NumberUtils', () => {
describe('Variant #2: number `10`', () => {
const number: number = 10;
const expectedHexString = 'a';
const expectedHexString = '0xa';
let hexString: string;
@@ -36,7 +36,7 @@ describe('NumberUtils', () => {
describe('Variant #3: number `17`', () => {
const number: number = 17;
const expectedHexString = '11';
const expectedHexString = '0x11';
let hexString: string;
@@ -51,7 +51,7 @@ describe('NumberUtils', () => {
describe('Variant #4: number `536870912`', () => {
const number: number = 536870912;
const expectedHexString = '20000000';
const expectedHexString = '0x20000000';
let hexString: string;
@@ -63,6 +63,22 @@ describe('NumberUtils', () => {
assert.equal(hexString, expectedHexString);
});
});
describe('Variant #5: bigint number `10n`', () => {
// @ts-ignore
const number: bigint = 10n;
const expectedHexString = '0xan';
let hexString: string;
before(() => {
hexString = NumberUtils.toHex(number);
});
it('should create a string with hexadecimal value from a given bigint number', () => {
assert.equal(hexString, expectedHexString);
});
});
});
describe('isCeil', () => {
@@ -95,5 +111,21 @@ describe('NumberUtils', () => {
assert.equal(result, expectedResult);
});
});
describe('bigint number', () => {
// @ts-ignore
const number: bigint = 10n;
const expectedResult: boolean = true;
let result: boolean;
before(() => {
result = NumberUtils.isCeil(number);
});
it('should return true', () => {
assert.equal(result, expectedResult);
});
});
});
});