diff --git a/bin/javascript-obfuscator.js b/bin/javascript-obfuscator.js index 72318f79..441409cf 100755 --- a/bin/javascript-obfuscator.js +++ b/bin/javascript-obfuscator.js @@ -1,3 +1,7 @@ #!/usr/bin/env node -require('../dist/index').runCLI(); \ No newline at end of file +require('../dist/index').runCLI( + process.argv, + process.stdin, + process.stdout +); \ No newline at end of file diff --git a/dist/index.js b/dist/index.js index 36ae55d4..006b7542 100644 --- a/dist/index.js +++ b/dist/index.js @@ -648,8 +648,8 @@ module.exports = } }, { key: 'runCLI', - value: function runCLI() { - new JavaScriptObfuscatorCLI_1.JavaScriptObfuscatorCLI().run(); + value: function runCLI(argv, stdin, stdout) { + new JavaScriptObfuscatorCLI_1.JavaScriptObfuscatorCLI(argv, stdin, stdout).run(); } }, { key: 'generateCode', @@ -1071,33 +1071,35 @@ module.exports = function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } var commands = __webpack_require__(42); - var fs = __webpack_require__(43); - var path = __webpack_require__(44); var DefaultPreset_1 = __webpack_require__(14); var JavaScriptObfuscator_1 = __webpack_require__(9); + var child_process_1 = __webpack_require__(45); var JavaScriptObfuscatorCLI = function () { - function JavaScriptObfuscatorCLI() { + function JavaScriptObfuscatorCLI(argv, stdin, stdout) { _classCallCheck(this, JavaScriptObfuscatorCLI); this.data = ''; + this.argv = argv; + this.stdin = stdin; + this.stdout = stdout; } _createClass(JavaScriptObfuscatorCLI, [{ - key: 'run', + key: "run", value: function run() { this.configureProcess(); this.configureCommands(); - if (!JavaScriptObfuscatorCLI.isDataExist()) { + if (!this.isDataExist()) { commands.outputHelp(); } } }, { - key: 'configureCommands', + key: "configureCommands", value: function configureCommands() { commands.version(JavaScriptObfuscatorCLI.getBuildVersion(), '-v, --version').usage('[options] STDIN STDOUT').option('--compact ', 'Disable one line output code compacting', JavaScriptObfuscatorCLI.parseBoolean).option('--debugProtection ', 'Disable browser Debug panel (can cause DevTools enabled browser freeze)', JavaScriptObfuscatorCLI.parseBoolean).option('--debugProtectionInterval ', 'Disable browser Debug panel even after page was loaded (can cause DevTools enabled browser freeze)', JavaScriptObfuscatorCLI.parseBoolean).option('--disableConsoleOutput ', 'Allow console.log, console.info, console.error and console.warn messages output into browser console', JavaScriptObfuscatorCLI.parseBoolean).option('--encodeUnicodeLiterals ', 'All literals in Unicode array become encoded in Base64 (this option can slightly slow down your code speed)', JavaScriptObfuscatorCLI.parseBoolean).option('--reservedNames ', 'Disable obfuscation of variable names, function names and names of function parameters that match the passed RegExp patterns (comma separated)', function (val) { return val.split(','); - }).option('--rotateUnicodeArray ', 'Disable rotation of unicode array values during obfuscation', JavaScriptObfuscatorCLI.parseBoolean).option('--selfDefending ', 'Disables self-defending for obfuscated code', JavaScriptObfuscatorCLI.parseBoolean).option('--unicodeArray ', 'Disables gathering of all literal strings into an array and replacing every literal string with an array call', JavaScriptObfuscatorCLI.parseBoolean).option('--unicodeArrayThreshold ', 'The probability that the literal string will be inserted into unicodeArray (Default: 0.8, Min: 0, Max: 1)', parseFloat).option('--wrapUnicodeArrayCalls ', 'Disables usage of special access function instead of direct array call', JavaScriptObfuscatorCLI.parseBoolean).parse(process.argv); + }).option('--rotateUnicodeArray ', 'Disable rotation of unicode array values during obfuscation', JavaScriptObfuscatorCLI.parseBoolean).option('--selfDefending ', 'Disables self-defending for obfuscated code', JavaScriptObfuscatorCLI.parseBoolean).option('--unicodeArray ', 'Disables gathering of all literal strings into an array and replacing every literal string with an array call', JavaScriptObfuscatorCLI.parseBoolean).option('--unicodeArrayThreshold ', 'The probability that the literal string will be inserted into unicodeArray (Default: 0.8, Min: 0, Max: 1)', parseFloat).option('--wrapUnicodeArrayCalls ', 'Disables usage of special access function instead of direct array call', JavaScriptObfuscatorCLI.parseBoolean).parse(this.argv); commands.on('--help', function () { var isWindows = process.platform === 'win32'; console.log(' Examples:\n'); @@ -1112,26 +1114,33 @@ module.exports = }); } }, { - key: 'configureProcess', + key: "configureProcess", value: function configureProcess() { var _this = this; - process.stdin.setEncoding('utf-8'); - process.stdin.on('readable', function () { + this.stdin.setEncoding('utf-8'); + this.stdin.on('readable', function () { var chunk = void 0; - while (chunk = process.stdin.read()) { + while (chunk = _this.stdin.read()) { _this.data += chunk; } }); - process.stdin.on('end', this.processData); + this.stdin.on('end', function () { + return _this.processData(); + }); } }, { - key: 'processData', + key: "isDataExist", + value: function isDataExist() { + return !process.env.__DIRECT__ && !this.stdin.isTTY; + } + }, { + key: "processData", value: function processData() { - process.stdout.write(JavaScriptObfuscator_1.JavaScriptObfuscator.obfuscate(this.data, JavaScriptObfuscatorCLI.buildOptions())); + this.stdout.write(JavaScriptObfuscator_1.JavaScriptObfuscator.obfuscate(this.data, JavaScriptObfuscatorCLI.buildOptions())); } }], [{ - key: 'buildOptions', + key: "buildOptions", value: function buildOptions() { var options = {}, availableOptions = Object.keys(DefaultPreset_1.DEFAULT_PRESET); @@ -1147,18 +1156,12 @@ module.exports = return Object.assign({}, DefaultPreset_1.DEFAULT_PRESET, options); } }, { - key: 'getBuildVersion', + key: "getBuildVersion", value: function getBuildVersion() { - var packageConfig = fs.readFileSync(path.join(path.dirname(fs.realpathSync(process.argv[1])), '../package.json')); - return JSON.parse(packageConfig).version; + return String(child_process_1.execSync("npm info " + JavaScriptObfuscatorCLI.packageName + " version")); } }, { - key: 'isDataExist', - value: function isDataExist() { - return !process.env.__DIRECT__ && !process.stdin.isTTY; - } - }, { - key: 'parseBoolean', + key: "parseBoolean", value: function parseBoolean(value) { return value === 'true' || value === '1'; } @@ -1167,6 +1170,7 @@ module.exports = return JavaScriptObfuscatorCLI; }(); + JavaScriptObfuscatorCLI.packageName = 'javascript-obfuscator'; exports.JavaScriptObfuscatorCLI = JavaScriptObfuscatorCLI; /***/ }, @@ -2608,16 +2612,12 @@ module.exports = module.exports = require("commander"); /***/ }, -/* 43 */ +/* 43 */, +/* 44 */, +/* 45 */ /***/ function(module, exports) { - module.exports = require("fs"); - -/***/ }, -/* 44 */ -/***/ function(module, exports) { - - module.exports = require("path"); + module.exports = require("child_process"); /***/ } /******/ ]); diff --git a/package.json b/package.json index bca6defb..d2b48f7d 100644 --- a/package.json +++ b/package.json @@ -33,6 +33,9 @@ "istanbul": "^1.0.0-alpha.2", "lite-server": "^1.3.1", "mocha": "^2.5.3", + "mock-cli": "^0.1.2", + "mock-stdin": "^0.3.0", + "mock-utf8-stream": "^0.1.1", "ts-loader": "^0.8.2", "ts-node": "^0.9.1", "tslint": "^3.11.0", diff --git a/src/JavaScriptObfuscator.ts b/src/JavaScriptObfuscator.ts index 31cad683..bdbd2012 100644 --- a/src/JavaScriptObfuscator.ts +++ b/src/JavaScriptObfuscator.ts @@ -34,8 +34,17 @@ export class JavaScriptObfuscator { return JavaScriptObfuscator.generateCode(astTree, options); } - public static runCLI (): void { - new JavaScriptObfuscatorCLI().run(); + /** + * @param argv + * @param stdin + * @param stdout + */ + public static runCLI ( + argv: string[], + stdin: NodeJS.ReadableStream, + stdout: NodeJS.WritableStream + ): void { + new JavaScriptObfuscatorCLI(argv, stdin, stdout).run(); } /** diff --git a/src/cli/JavaScriptObfuscatorCLI.ts b/src/cli/JavaScriptObfuscatorCLI.ts index d4474ff8..3400d043 100644 --- a/src/cli/JavaScriptObfuscatorCLI.ts +++ b/src/cli/JavaScriptObfuscatorCLI.ts @@ -1,6 +1,4 @@ import * as commands from 'commander'; -import * as fs from 'fs'; -import * as path from 'path'; import * as tty from 'tty'; import { IOptionsPreset } from "../interfaces/IOptionsPreset"; @@ -8,14 +6,43 @@ import { IOptionsPreset } from "../interfaces/IOptionsPreset"; import { DEFAULT_PRESET } from "../preset-options/DefaultPreset"; import { JavaScriptObfuscator } from "../JavaScriptObfuscator"; +import {execSync} from "child_process"; export class JavaScriptObfuscatorCLI { + /** + * @type {string} + */ + private static packageName: string = 'javascript-obfuscator'; + + /** + * @type {string[]} + */ + private argv: string[]; + /** * @type {string} */ private data: string = ''; - constructor () {} + /** + * @type {NodeJS.ReadableStream} + */ + private stdin: NodeJS.ReadableStream; + + /** + * @type {NodeJS.WritableStream} + */ + private stdout: NodeJS.WritableStream; + + constructor ( + argv: string[], + stdin: NodeJS.ReadableStream, + stdout: NodeJS.WritableStream + ) { + this.argv = argv; + this.stdin = stdin; + this.stdout = stdout; + } /** * @returns {IOptionsPreset} @@ -43,23 +70,7 @@ export class JavaScriptObfuscatorCLI { * @returns {string} */ private static getBuildVersion (): string { - let packageConfig: any = fs.readFileSync( - path.join( - path.dirname( - fs.realpathSync(process.argv[1]) - ), - '../package.json' - ) - ); - - return JSON.parse(packageConfig).version; - } - - /** - * @returns {boolean} - */ - private static isDataExist (): boolean { - return !process.env.__DIRECT__ && !(process.stdin).isTTY; + return String(execSync(`npm info ${JavaScriptObfuscatorCLI.packageName} version`)); } /** @@ -74,7 +85,7 @@ export class JavaScriptObfuscatorCLI { this.configureProcess(); this.configureCommands(); - if (!JavaScriptObfuscatorCLI.isDataExist()) { + if (!this.isDataExist()) { commands.outputHelp(); } } @@ -94,7 +105,7 @@ export class JavaScriptObfuscatorCLI { .option('--unicodeArray ', 'Disables gathering of all literal strings into an array and replacing every literal string with an array call', JavaScriptObfuscatorCLI.parseBoolean) .option('--unicodeArrayThreshold ', 'The probability that the literal string will be inserted into unicodeArray (Default: 0.8, Min: 0, Max: 1)', parseFloat) .option('--wrapUnicodeArrayCalls ', 'Disables usage of special access function instead of direct array call', JavaScriptObfuscatorCLI.parseBoolean) - .parse(process.argv); + .parse(this.argv); commands.on('--help', () => { let isWindows: boolean = process.platform === 'win32'; @@ -115,21 +126,28 @@ export class JavaScriptObfuscatorCLI { } private configureProcess (): void { - process.stdin.setEncoding('utf-8'); + this.stdin.setEncoding('utf-8'); - process.stdin.on('readable', () => { + this.stdin.on('readable', () => { let chunk: string; - while (chunk = process.stdin.read()) { + while (chunk = this.stdin.read()) { this.data += chunk; } }); - process.stdin.on('end', this.processData); + this.stdin.on('end', () => this.processData()); + } + + /** + * @returns {boolean} + */ + private isDataExist (): boolean { + return !process.env.__DIRECT__ && !(this.stdin).isTTY; } private processData (): void { - process.stdout.write( + this.stdout.write( JavaScriptObfuscator.obfuscate(this.data, JavaScriptObfuscatorCLI.buildOptions()) ); } diff --git a/test/JavaScriptObfuscatorCLI.spec.ts b/test/JavaScriptObfuscatorCLI.spec.ts index 1218c39e..af31d53a 100644 --- a/test/JavaScriptObfuscatorCLI.spec.ts +++ b/test/JavaScriptObfuscatorCLI.spec.ts @@ -1,11 +1,35 @@ import { JavaScriptObfuscatorCLI } from "../src/cli/JavaScriptObfuscatorCLI"; -let assert: any = require('chai').assert; +let assert: any = require('chai').assert, + stream: any = require("mock-utf8-stream"), + mockStdin: any = require('mock-stdin'); describe('JavaScriptObfuscatorCLI', () => { - describe('obfuscate (sourceCode: string, customOptions?: IOptionsPreset): string', () => { - it('should ', () => { + describe('run (): void', () => { + it('should obfuscate file with JS code', function (done: MochaDone): void { + let stdin: any = mockStdin.stdin(), + stdout: any = new stream.MockWritableStream(); + this.timeout(7000); + + stdout.captureData(); + + let CLI: JavaScriptObfuscatorCLI = new JavaScriptObfuscatorCLI( + [ + 'node', + 'javascript-obfuscator', + '--compact', + 'false', + '--selfDefending', + 'false' + ], + stdin.send(new Buffer('var test = \'abc\';')), + stdout + ); + + CLI.run(); + + assert.equal(1, 1); }); }); }); diff --git a/test/fixtures/sample.js b/test/fixtures/sample.js new file mode 100644 index 00000000..4ccca1f9 --- /dev/null +++ b/test/fixtures/sample.js @@ -0,0 +1,53 @@ +(function(){ + var result = 1, + term1 = 0, + term2 = 1, + i = 1; + while(i < 10) + { + var test = 10; + result = term1 + term2; + console.log(result); + term1 = term2; + term2 = result; + i++; + } + + console.log(test); + + var test = function (test) { + console.log(test); + + if (true) { + var test = 5 + } + + return test; + } + + console.log(test(1)); + + function test2 (abc) { + function test1 () { + console.log('inside', abc.item); + } + + console.log('ั‚ะตัั‚', abc); + + var abc = {}; + + return abc.item = 15, test1(); + }; + + var regexptest = /version\/(\d+)/i; + console.log(regexptest); + + test2(22); + console.log(105.4); + console.log(true, false); + + try { + } catch (error) { + console.log(error); + } +})(); diff --git a/tslint.json b/tslint.json index 1c1a5e3b..083a731f 100644 --- a/tslint.json +++ b/tslint.json @@ -63,10 +63,7 @@ "no-eval": false, "no-inferrable-types": false, "no-internal-module": true, - "no-invalid-this": [ - true, - "check-function-in-method" - ], + "no-invalid-this": false, "no-null-keyword": false, "no-reference": false, "no-require-imports": false,