Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ v5.4.0
* Fixed `reservedNames` not preserving class method and property names when `stringArray` or `deadCodeInjection` is enabled. Fixes https://github.com/javascript-obfuscator/javascript-obfuscator/issues/1279
* Fixed infinite loop / stack overflow when `reservedNames` patterns match all generated identifier names. Now throws a descriptive error instead. Fixes https://github.com/javascript-obfuscator/javascript-obfuscator/issues/1382
* Fixed `transformObjectKeys` changing evaluation order when object expression is inside a sequence expression with preceding side effects (e.g. `return aux(ys), { min }`). Fixes https://github.com/javascript-obfuscator/javascript-obfuscator/issues/1246
* Fixed CLI `--options-preset` not applying preset values for options not explicitly set via command line (e.g. `splitStrings` from `high-obfuscation` preset was ignored). Fixes https://github.com/javascript-obfuscator/javascript-obfuscator/issues/1236
* Replaced `mkdirp` dependency with native `fs.mkdirSync({ recursive: true })`. Fixes https://github.com/javascript-obfuscator/javascript-obfuscator/issues/1275. Thank you https://github.com/roli-lpci!
* Replaced `conf` dependency with custom implementation using `env-paths` and native `fs`

Expand Down
28 changes: 21 additions & 7 deletions src/cli/JavaScriptObfuscatorCLI.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import * as path from 'path';

import { TInputCLIOptions } from '../types/options/TInputCLIOptions';
import { TInputOptions } from '../types/options/TInputOptions';
import { TOptionsPreset } from '../types/options/TOptionsPreset';

import { IFileData } from '../interfaces/cli/IFileData';
import { IInitializable } from '../interfaces/IInitializable';
Expand All @@ -24,11 +25,10 @@ import { StringArrayEncoding } from '../enums/node-transformers/string-array-tra
import { StringArrayIndexesType } from '../enums/node-transformers/string-array-transformers/StringArrayIndexesType';
import { StringArrayWrappersType } from '../enums/node-transformers/string-array-transformers/StringArrayWrappersType';

import { DEFAULT_PRESET } from '../options/presets/Default';

import { ArraySanitizer } from './sanitizers/ArraySanitizer';
import { BooleanSanitizer } from './sanitizers/BooleanSanitizer';

import { Options } from '../options/Options';
import { CLIUtils } from './utils/CLIUtils';
import { IdentifierNamesCacheFileUtils } from './utils/IdentifierNamesCacheFileUtils';
import { JavaScriptObfuscator } from '../JavaScriptObfuscatorFacade';
Expand Down Expand Up @@ -112,33 +112,47 @@ export class JavaScriptObfuscatorCLI implements IInitializable {

/**
* @param {TInputCLIOptions} inputOptions
* @param {commander.Command} command
* @returns {TInputOptions}
*/
private static buildOptions(inputOptions: TInputCLIOptions): TInputOptions {
const inputCLIOptions: TInputOptions = JavaScriptObfuscatorCLI.filterOptions(inputOptions);
private static buildOptions(inputOptions: TInputCLIOptions, command: commander.Command): TInputOptions {
const inputCLIOptions: TInputOptions = JavaScriptObfuscatorCLI.filterOptions(inputOptions, command);
const configFilePath: string | undefined = inputOptions.config;
const configFileLocation: string = configFilePath ? path.resolve(configFilePath, '.') : '';
const configFileOptions: TInputOptions = configFileLocation ? CLIUtils.getUserConfig(configFileLocation) : {};

const presetName: TOptionsPreset =
inputCLIOptions.optionsPreset ?? configFileOptions.optionsPreset ?? OptionsPreset.Default;
const presetOptions: TInputOptions = Options.getOptionsByPreset(presetName);

return {
...DEFAULT_PRESET,
...presetOptions,
...configFileOptions,
...inputCLIOptions
};
}

/**
* Filters out options that were not explicitly set by the user.
* Commander.js sets default values for all options, which would
* override preset values. Only user-provided options should be kept.
*
* @param {TObject} options
* @param {commander.Command} command
* @returns {TInputOptions}
*/
private static filterOptions(options: TInputCLIOptions): TInputOptions {
private static filterOptions(options: TInputCLIOptions, command: commander.Command): TInputOptions {
const filteredOptions: TInputOptions = {};

Object.keys(options).forEach((option: keyof TInputCLIOptions) => {
if (options[option] === undefined) {
return;
}

if (command.getOptionValueSource(String(option)) === 'default') {
return;
}

filteredOptions[option] = options[option];
});

Expand All @@ -152,7 +166,7 @@ export class JavaScriptObfuscatorCLI implements IInitializable {
this.configureHelp();

this.inputPath = path.normalize(this.commands.args[0] || '');
this.inputCLIOptions = JavaScriptObfuscatorCLI.buildOptions(this.commands.opts());
this.inputCLIOptions = JavaScriptObfuscatorCLI.buildOptions(this.commands.opts(), this.commands);
this.sourceCodeFileUtils = new SourceCodeFileUtils(this.inputPath, this.inputCLIOptions);
this.obfuscatedCodeFileUtils = new ObfuscatedCodeFileUtils(this.inputPath, this.inputCLIOptions);
this.identifierNamesCacheFileUtils = new IdentifierNamesCacheFileUtils(
Expand Down
2 changes: 2 additions & 0 deletions test/fixtures/sample-long-string.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
var x = "This is a long string and it should really be split by the obfuscator";
console.log(x);
45 changes: 45 additions & 0 deletions test/functional-tests/cli/JavaScriptObfuscatorCLI.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1511,6 +1511,51 @@ describe('JavaScriptObfuscatorCLI', function (): void {
});
});

/**
* https://github.com/javascript-obfuscator/javascript-obfuscator/issues/1236
*/
describe('`--options-preset` should apply preset options that are not explicitly set via CLI', () => {
const longStringFixturePath: string = path.join(fixturesDirName, 'sample-long-string.js');

let obfuscatedCode: string;

before(async () => {
await JavaScriptObfuscatorCLI.obfuscate([
'node',
'javascript-obfuscator',
longStringFixturePath,
'--output',
outputFilePath,
'--options-preset',
'medium-obfuscation',
'--string-array',
'false',
'--dead-code-injection',
'false',
'--control-flow-flattening',
'false',
'--self-defending',
'false',
'--debug-protection',
'false',
'--disable-console-output',
'false',
'--seed',
'1'
]);

obfuscatedCode = fs.readFileSync(outputFilePath, 'utf8');
});

it('should apply `splitStrings` from preset without explicit `--split-strings` flag', () => {
assert.match(obfuscatedCode, /'.+'\s*\+\s*'.+'\s*\+\s*'.+'/);
});

after(() => {
fs.unlinkSync(outputFilePath);
});
});

after(() => {
rimraf.sync(outputDirName);
});
Expand Down
Loading