mirror of
https://github.com/javascript-obfuscator/javascript-obfuscator
synced 2026-08-09 12:42:29 +00:00
0.28.0 release
Support of BigInt
This commit is contained in:
+2
-1
@@ -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
|
||||
|
||||
Vendored
+4
-4
File diff suppressed because one or more lines are too long
Vendored
+1
-1
File diff suppressed because one or more lines are too long
Vendored
+1
-1
File diff suppressed because one or more lines are too long
+1
-1
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "javascript-obfuscator",
|
||||
"version": "0.27.4",
|
||||
"version": "0.28.0",
|
||||
"description": "JavaScript obfuscator",
|
||||
"keywords": [
|
||||
"obfuscator",
|
||||
|
||||
+1
-1
@@ -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);
|
||||
|
||||
+5
-6
@@ -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);
|
||||
|
||||
+1
-2
@@ -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}
|
||||
|
||||
@@ -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
@@ -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;
|
||||
}
|
||||
+23
@@ -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\+\)\/;$/;
|
||||
|
||||
|
||||
+1
@@ -0,0 +1 @@
|
||||
var test = 10n;
|
||||
+41
-16
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user