BaseIdentifierObfuscatingReplacer.ts 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128
  1. import { inject, injectable, } from 'inversify';
  2. import { ServiceIdentifiers } from '../../../../container/ServiceIdentifiers';
  3. import * as ESTree from 'estree';
  4. import { TIdentifierNamesGeneratorFactory } from '../../../../types/container/generators/TIdentifierNamesGeneratorFactory';
  5. import { TNodeWithLexicalScope } from '../../../../types/node/TNodeWithLexicalScope';
  6. import { IIdentifierNamesGenerator } from '../../../../interfaces/generators/identifier-names-generators/IIdentifierNamesGenerator';
  7. import { IIdentifierObfuscatingReplacer } from '../../../../interfaces/node-transformers/obfuscating-transformers/obfuscating-replacers/IIdentifierObfuscatingReplacer';
  8. import { IOptions } from '../../../../interfaces/options/IOptions';
  9. import { AbstractObfuscatingReplacer } from '../AbstractObfuscatingReplacer';
  10. import { NodeFactory } from '../../../../node/NodeFactory';
  11. @injectable()
  12. export class BaseIdentifierObfuscatingReplacer extends AbstractObfuscatingReplacer implements IIdentifierObfuscatingReplacer {
  13. /**
  14. * @type {IIdentifierNamesGenerator}
  15. */
  16. private readonly identifierNamesGenerator: IIdentifierNamesGenerator;
  17. /**
  18. * @type {Map<TNodeWithLexicalScope, Map<string, string>>}
  19. */
  20. private readonly blockScopesMap: Map<TNodeWithLexicalScope, Map<string, string>> = new Map();
  21. /**
  22. * @param {TIdentifierNamesGeneratorFactory} identifierNamesGeneratorFactory
  23. * @param {IOptions} options
  24. */
  25. constructor (
  26. @inject(ServiceIdentifiers.Factory__IIdentifierNamesGenerator)
  27. identifierNamesGeneratorFactory: TIdentifierNamesGeneratorFactory,
  28. @inject(ServiceIdentifiers.IOptions) options: IOptions
  29. ) {
  30. super(options);
  31. this.identifierNamesGenerator = identifierNamesGeneratorFactory(options);
  32. }
  33. /**
  34. * @param {string} nodeValue
  35. * @param {TNodeWithLexicalScope} lexicalScopeNode
  36. * @returns {Identifier}
  37. */
  38. public replace (nodeValue: string, lexicalScopeNode: TNodeWithLexicalScope): ESTree.Identifier {
  39. if (this.blockScopesMap.has(lexicalScopeNode)) {
  40. const namesMap: Map<string, string> = <Map<string, string>>this.blockScopesMap.get(lexicalScopeNode);
  41. if (namesMap.has(nodeValue)) {
  42. nodeValue = <string>namesMap.get(nodeValue);
  43. }
  44. }
  45. return NodeFactory.identifierNode(nodeValue);
  46. }
  47. /**
  48. * Store `nodeName` of global identifiers as key in map with random name as value.
  49. * Reserved name will be ignored.
  50. *
  51. * @param {string} nodeName
  52. * @param {TNodeWithLexicalScope} lexicalScopeNode
  53. */
  54. public storeGlobalName (nodeName: string, lexicalScopeNode: TNodeWithLexicalScope): void {
  55. if (this.isReservedName(nodeName)) {
  56. return;
  57. }
  58. const identifierName: string = this.identifierNamesGenerator.generateWithPrefix();
  59. if (!this.blockScopesMap.has(lexicalScopeNode)) {
  60. this.blockScopesMap.set(lexicalScopeNode, new Map());
  61. }
  62. const namesMap: Map<string, string> = <Map<string, string>>this.blockScopesMap.get(lexicalScopeNode);
  63. namesMap.set(nodeName, identifierName);
  64. }
  65. /**
  66. * Store `nodeName` of local identifier as key in map with random name as value.
  67. * Reserved name will be ignored.
  68. *
  69. * @param {string} nodeName
  70. * @param {TNodeWithLexicalScope} lexicalScopeNode
  71. */
  72. public storeLocalName (nodeName: string, lexicalScopeNode: TNodeWithLexicalScope): void {
  73. if (this.isReservedName(nodeName)) {
  74. return;
  75. }
  76. const identifierName: string = this.identifierNamesGenerator.generate();
  77. if (!this.blockScopesMap.has(lexicalScopeNode)) {
  78. this.blockScopesMap.set(lexicalScopeNode, new Map());
  79. }
  80. const namesMap: Map<string, string> = <Map<string, string>>this.blockScopesMap.get(lexicalScopeNode);
  81. namesMap.set(nodeName, identifierName);
  82. }
  83. /**
  84. * Preserve `name` to protect it from further using.
  85. *
  86. * @param {string} name
  87. */
  88. public preserveName (name: string): void {
  89. this.identifierNamesGenerator.preserveName(name);
  90. }
  91. /**
  92. * @param {string} name
  93. * @returns {boolean}
  94. */
  95. private isReservedName (name: string): boolean {
  96. if (!this.options.reservedNames.length) {
  97. return false;
  98. }
  99. return this.options.reservedNames
  100. .some((reservedName: string) => {
  101. return new RegExp(reservedName, 'g').exec(name) !== null;
  102. });
  103. }
  104. }