Browse Source

Internal fields of `TIdentifierNamesCache` now are optional. Fixed option validation and added normalization.

sanex 4 years ago
parent
commit
c89ba21cba

File diff suppressed because it is too large
+ 0 - 0
dist/index.browser.js


File diff suppressed because it is too large
+ 0 - 0
dist/index.cli.js


File diff suppressed because it is too large
+ 0 - 0
dist/index.js


+ 2 - 0
src/options/OptionsNormalizer.ts

@@ -9,6 +9,7 @@ import { ControlFlowFlatteningThresholdRule } from './normalizer-rules/ControlFl
 import { DeadCodeInjectionRule } from './normalizer-rules/DeadCodeInjectionRule';
 import { DeadCodeInjectionThresholdRule } from './normalizer-rules/DeadCodeInjectionThresholdRule';
 import { DomainLockRule } from './normalizer-rules/DomainLockRule';
+import { IdentifierNamesCacheRule } from './normalizer-rules/IdentifierNamesCacheRule';
 import { InputFileNameRule } from './normalizer-rules/InputFileNameRule';
 import { SeedRule } from './normalizer-rules/SeedRule';
 import { SelfDefendingRule } from './normalizer-rules/SelfDefendingRule';
@@ -29,6 +30,7 @@ export class OptionsNormalizer implements IOptionsNormalizer {
         DeadCodeInjectionRule,
         DeadCodeInjectionThresholdRule,
         DomainLockRule,
+        IdentifierNamesCacheRule,
         InputFileNameRule,
         SeedRule,
         SelfDefendingRule,

+ 32 - 0
src/options/normalizer-rules/IdentifierNamesCacheRule.ts

@@ -0,0 +1,32 @@
+import { TOptionsNormalizerRule } from '../../types/options/TOptionsNormalizerRule';
+
+import { IOptions } from '../../interfaces/options/IOptions';
+
+/**
+ * @param {IOptions} options
+ * @returns {IOptions}
+ */
+export const IdentifierNamesCacheRule: TOptionsNormalizerRule = (options: IOptions): IOptions => {
+    let identifierNamesCache = options.identifierNamesCache;
+
+    if (identifierNamesCache && !identifierNamesCache.globalIdentifiers) {
+        identifierNamesCache = {
+            ...identifierNamesCache,
+            globalIdentifiers: {}
+        };
+    }
+
+    if (identifierNamesCache && !identifierNamesCache.propertyIdentifiers) {
+        identifierNamesCache = {
+            ...identifierNamesCache,
+            propertyIdentifiers: {}
+        };
+    }
+
+    options = {
+        ...options,
+        identifierNamesCache
+    };
+
+    return options;
+};

+ 3 - 3
src/options/validators/IsIdentifierNamesCache.ts

@@ -13,11 +13,11 @@ import { DEFAULT_PRESET } from '../presets/Default';
  * @returns {boolean}
  */
 const validateDictionary = (value: unknown | TIdentifierNamesCacheDictionary): boolean => {
-    if (typeof value !== 'object') {
-        return false;
+    if (value === undefined) {
+        return true;
     }
 
-    if (value === null) {
+    if (typeof value !== 'object' || value === null) {
         return false;
     }
 

+ 2 - 2
src/types/TIdentifierNamesCache.ts

@@ -1,7 +1,7 @@
 import { TIdentifierNamesCacheDictionary } from './TIdentifierNamesCacheDictionary';
 
 export type TIdentifierNamesCache = {
-    globalIdentifiers: TIdentifierNamesCacheDictionary;
-    propertyIdentifiers: TIdentifierNamesCacheDictionary;
+    globalIdentifiers?: TIdentifierNamesCacheDictionary;
+    propertyIdentifiers?: TIdentifierNamesCacheDictionary;
 } | null;
 

+ 134 - 0
test/functional-tests/options/OptionsNormalizer.spec.ts

@@ -257,6 +257,140 @@ describe('OptionsNormalizer', () => {
             });
         });
 
+        describe('identifierNamesCacheRule', () => {
+            describe('Variant #1: all fields are exist with values', () => {
+                before(() => {
+                    optionsPreset = getNormalizedOptions({
+                        ...getDefaultOptions(),
+                        identifierNamesCache: {
+                            globalIdentifiers: {
+                                foo: '_0x123456'
+                            },
+                            propertyIdentifiers: {
+                                bar: '_0x654321'
+                            }
+                        }
+                    });
+
+                    expectedOptionsPreset = {
+                        ...getDefaultOptions(),
+                        identifierNamesCache: {
+                            globalIdentifiers: {
+                                foo: '_0x123456'
+                            },
+                            propertyIdentifiers: {
+                                bar: '_0x654321'
+                            }
+                        }
+                    };
+                });
+
+                it('should not normalize options preset', () => {
+                    assert.deepEqual(optionsPreset, expectedOptionsPreset);
+                });
+            });
+
+            describe('Variant #2: some fields are exist with values', () => {
+                before(() => {
+                    optionsPreset = getNormalizedOptions({
+                        ...getDefaultOptions(),
+                        identifierNamesCache: {
+                            globalIdentifiers: {
+                                foo: '_0x123456'
+                            },
+                            propertyIdentifiers: {}
+                        }
+                    });
+
+                    expectedOptionsPreset = {
+                        ...getDefaultOptions(),
+                        identifierNamesCache: {
+                            globalIdentifiers: {
+                                foo: '_0x123456'
+                            },
+                            propertyIdentifiers: {}
+                        }
+                    };
+                });
+
+                it('should not normalize options preset', () => {
+                    assert.deepEqual(optionsPreset, expectedOptionsPreset);
+                });
+            });
+
+            describe('Variant #3: all fields are exist with empty objects', () => {
+                before(() => {
+                    optionsPreset = getNormalizedOptions({
+                        ...getDefaultOptions(),
+                        identifierNamesCache: {
+                            globalIdentifiers: {},
+                            propertyIdentifiers: {}
+                        }
+                    });
+
+                    expectedOptionsPreset = {
+                        ...getDefaultOptions(),
+                        identifierNamesCache: {
+                            globalIdentifiers: {},
+                            propertyIdentifiers: {}
+                        }
+                    };
+                });
+
+                it('should not normalize options preset', () => {
+                    assert.deepEqual(optionsPreset, expectedOptionsPreset);
+                });
+            });
+
+            describe('Variant #4: some fields are missing', () => {
+                before(() => {
+                    optionsPreset = getNormalizedOptions({
+                        ...getDefaultOptions(),
+                        identifierNamesCache: {
+                            globalIdentifiers: {
+                                foo: '_0x123456'
+                            }
+                        }
+                    });
+
+                    expectedOptionsPreset = {
+                        ...getDefaultOptions(),
+                        identifierNamesCache: {
+                            globalIdentifiers: {
+                                foo: '_0x123456'
+                            },
+                            propertyIdentifiers: {}
+                        }
+                    };
+                });
+
+                it('should normalize options preset', () => {
+                    assert.deepEqual(optionsPreset, expectedOptionsPreset);
+                });
+            });
+
+            describe('Variant #5: all fields are missing', () => {
+                before(() => {
+                    optionsPreset = getNormalizedOptions({
+                        ...getDefaultOptions(),
+                        identifierNamesCache: {}
+                    });
+
+                    expectedOptionsPreset = {
+                        ...getDefaultOptions(),
+                        identifierNamesCache: {
+                            globalIdentifiers: {},
+                            propertyIdentifiers: {}
+                        }
+                    };
+                });
+
+                it('should normalize options preset', () => {
+                    assert.deepEqual(optionsPreset, expectedOptionsPreset);
+                });
+            });
+        });
+
         describe('seedRule', () => {
             describe('Variant #1: seed value is string', () => {
                 before(() => {

+ 41 - 1
test/functional-tests/options/identifier-names-cache/Validation.spec.ts

@@ -76,7 +76,47 @@ describe('`identifierNamesCache` validation', () => {
                 });
             });
 
-            describe('Variant #4: `null` value', () => {
+            describe('Variant #4: object with some empty identifier names cache', () => {
+                let testFunc: () => string;
+
+                beforeEach(() => {
+                    testFunc = () => JavaScriptObfuscator.obfuscate(
+                        '',
+                        {
+                            ...NO_ADDITIONAL_NODES_PRESET,
+                            identifierNamesCache: {
+                                globalIdentifiers: {
+                                    foo: '_0x123456'
+                                }
+                            }
+                        }
+                    ).getObfuscatedCode();
+                });
+
+                it('should pass validation', () => {
+                    assert.doesNotThrow(testFunc);
+                });
+            });
+
+            describe('Variant #5: empty object', () => {
+                let testFunc: () => string;
+
+                beforeEach(() => {
+                    testFunc = () => JavaScriptObfuscator.obfuscate(
+                        '',
+                        {
+                            ...NO_ADDITIONAL_NODES_PRESET,
+                            identifierNamesCache: {}
+                        }
+                    ).getObfuscatedCode();
+                });
+
+                it('should pass validation', () => {
+                    assert.doesNotThrow(testFunc);
+                });
+            });
+
+            describe('Variant #5: `null` value', () => {
                 let testFunc: () => string;
 
                 beforeEach(() => {

Some files were not shown because too many files changed in this diff