StringArrayCallsWrapperTemplate.spec.ts 28 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641
  1. import 'reflect-metadata';
  2. import format from 'string-template';
  3. import { assert } from 'chai';
  4. import { ServiceIdentifiers } from '../../../../../../src/container/ServiceIdentifiers';
  5. import { ICryptUtilsStringArray } from '../../../../../../src/interfaces/utils/ICryptUtilsStringArray';
  6. import { IInversifyContainerFacade } from '../../../../../../src/interfaces/container/IInversifyContainerFacade';
  7. import { IObfuscationResult } from '../../../../../../src/interfaces/source-code/IObfuscationResult';
  8. import { IRandomGenerator } from '../../../../../../src/interfaces/utils/IRandomGenerator';
  9. import { AtobTemplate } from '../../../../../../src/custom-code-helpers/string-array/templates/string-array-calls-wrapper/AtobTemplate';
  10. import { Rc4Template } from '../../../../../../src/custom-code-helpers/string-array/templates/string-array-calls-wrapper/Rc4Template';
  11. import { StringArrayBase64DecodeTemplate } from '../../../../../../src/custom-code-helpers/string-array/templates/string-array-calls-wrapper/StringArrayBase64DecodeTemplate';
  12. import { StringArrayCallsWrapperTemplate } from '../../../../../../src/custom-code-helpers/string-array/templates/string-array-calls-wrapper/StringArrayCallsWrapperTemplate';
  13. import { StringArrayRC4DecodeTemplate } from '../../../../../../src/custom-code-helpers/string-array/templates/string-array-calls-wrapper/StringArrayRC4DecodeTemplate';
  14. import { StringArrayTemplate } from '../../../../../../src/custom-code-helpers/string-array/templates/string-array/StringArrayTemplate';
  15. import { NO_ADDITIONAL_NODES_PRESET } from '../../../../../../src/options/presets/NoCustomNodes';
  16. import { InversifyContainerFacade } from '../../../../../../src/container/InversifyContainerFacade';
  17. import { JavaScriptObfuscator } from '../../../../../../src/JavaScriptObfuscatorFacade';
  18. import { minimizeCode } from '../../../../../helpers/minimizeCode';
  19. import { readFileAsString } from '../../../../../helpers/readFileAsString';
  20. import { swapLettersCase } from '../../../../../helpers/swapLettersCase';
  21. describe('StringArrayCallsWrapperTemplate', () => {
  22. const stringArrayName: string = 'stringArrayName';
  23. const stringArrayFunctionName: string = 'stringArrayFunctionName';
  24. const stringArrayCallsWrapperName: string = 'stringArrayCallsWrapperName';
  25. const stringArrayCacheName: string = 'stringArrayCache';
  26. const atobFunctionName: string = 'atob';
  27. const rc4FunctionName: string = 'rc4';
  28. let cryptUtilsSwappedAlphabet: ICryptUtilsStringArray,
  29. randomGenerator: IRandomGenerator;
  30. before(() => {
  31. const inversifyContainerFacade: IInversifyContainerFacade = new InversifyContainerFacade();
  32. inversifyContainerFacade.load('', '', {});
  33. cryptUtilsSwappedAlphabet = inversifyContainerFacade
  34. .get<ICryptUtilsStringArray>(ServiceIdentifiers.ICryptUtilsStringArray);
  35. randomGenerator = inversifyContainerFacade
  36. .get<IRandomGenerator>(ServiceIdentifiers.IRandomGenerator);
  37. });
  38. describe('Variant #1: `base64` encoding', () => {
  39. describe('Variant #1: `selfDefending` option is disabled', () => {
  40. const selfDefendingEnabled: boolean = false;
  41. describe('Variant #1: index shift amount is `0`', () => {
  42. const index: string = '0x0';
  43. const indexShiftAmount: number = 0;
  44. const expectedDecodedValue: string = 'test1';
  45. let decodedValue: string;
  46. before(() => {
  47. const stringArrayTemplate = format(StringArrayTemplate(), {
  48. stringArrayName,
  49. stringArrayFunctionName,
  50. stringArrayStorageItems: `'${cryptUtilsSwappedAlphabet.btoa('test1')}'`
  51. });
  52. const atobPolyfill = format(AtobTemplate(selfDefendingEnabled), {
  53. atobFunctionName
  54. });
  55. const atobDecodeTemplate: string = format(
  56. StringArrayBase64DecodeTemplate(randomGenerator),
  57. {
  58. atobPolyfill,
  59. atobFunctionName,
  60. selfDefendingCode: '',
  61. stringArrayCacheName,
  62. stringArrayCallsWrapperName
  63. }
  64. );
  65. const stringArrayCallsWrapperTemplate: string = format(StringArrayCallsWrapperTemplate(), {
  66. decodeCodeHelperTemplate: atobDecodeTemplate,
  67. indexShiftAmount,
  68. stringArrayCacheName,
  69. stringArrayCallsWrapperName,
  70. stringArrayFunctionName
  71. });
  72. decodedValue = Function(`
  73. ${stringArrayTemplate}
  74. ${stringArrayCallsWrapperTemplate}
  75. return ${stringArrayCallsWrapperName}(${index});
  76. `)();
  77. });
  78. it('should correctly return decoded value', () => {
  79. assert.deepEqual(decodedValue, expectedDecodedValue);
  80. });
  81. });
  82. describe('Variant #2: index shift amount is `5`', () => {
  83. const index: string = '0x5';
  84. const indexShiftAmount: number = 5;
  85. const expectedDecodedValue: string = 'test1';
  86. let decodedValue: string;
  87. before(() => {
  88. const stringArrayTemplate = format(StringArrayTemplate(), {
  89. stringArrayName,
  90. stringArrayFunctionName,
  91. stringArrayStorageItems: `'${cryptUtilsSwappedAlphabet.btoa('test1')}'`
  92. });
  93. const atobPolyfill = format(AtobTemplate(selfDefendingEnabled), {
  94. atobFunctionName
  95. });
  96. const atobDecodeTemplate: string = format(
  97. StringArrayBase64DecodeTemplate(randomGenerator),
  98. {
  99. atobPolyfill,
  100. atobFunctionName,
  101. selfDefendingCode: '',
  102. stringArrayCacheName,
  103. stringArrayCallsWrapperName
  104. }
  105. );
  106. const stringArrayCallsWrapperTemplate: string = format(StringArrayCallsWrapperTemplate(), {
  107. decodeCodeHelperTemplate: atobDecodeTemplate,
  108. indexShiftAmount,
  109. stringArrayCacheName,
  110. stringArrayCallsWrapperName,
  111. stringArrayFunctionName
  112. });
  113. decodedValue = Function(`
  114. ${stringArrayTemplate}
  115. ${stringArrayCallsWrapperTemplate}
  116. return ${stringArrayCallsWrapperName}(${index});
  117. `)();
  118. });
  119. it('should correctly return decoded value', () => {
  120. assert.deepEqual(decodedValue, expectedDecodedValue);
  121. });
  122. });
  123. describe('Variant #3: no regexp inside atob template', () => {
  124. const indexShiftAmount: number = 0;
  125. const expectedRegExpTestValue: string = '12345';
  126. let decodedValue: string;
  127. before(() => {
  128. const stringArrayTemplate = format(StringArrayTemplate(), {
  129. stringArrayName,
  130. stringArrayFunctionName,
  131. stringArrayStorageItems: `'${swapLettersCase('c3RyaQ==')}'`
  132. });
  133. const atobPolyfill = format(AtobTemplate(selfDefendingEnabled), {
  134. atobFunctionName
  135. });
  136. const atobDecodeTemplate: string = format(
  137. StringArrayBase64DecodeTemplate(randomGenerator),
  138. {
  139. atobPolyfill,
  140. atobFunctionName,
  141. selfDefendingCode: '',
  142. stringArrayCacheName,
  143. stringArrayCallsWrapperName
  144. }
  145. );
  146. const stringArrayCallsWrapperTemplate: string = format(StringArrayCallsWrapperTemplate(), {
  147. decodeCodeHelperTemplate: atobDecodeTemplate,
  148. indexShiftAmount,
  149. stringArrayCacheName,
  150. stringArrayCallsWrapperName,
  151. stringArrayFunctionName
  152. });
  153. decodedValue = Function(`
  154. ${stringArrayTemplate}
  155. ${stringArrayCallsWrapperTemplate}
  156. /(.+)/.test("12345");
  157. ${stringArrayCallsWrapperName}(0x0);
  158. return RegExp.$1;
  159. `)();
  160. });
  161. it('should correctly return RegExp.$1 match without mutation by atob template', () => {
  162. assert.deepEqual(decodedValue, expectedRegExpTestValue);
  163. });
  164. });
  165. });
  166. describe('Variant #2: `selfDefending` option is enabled', () => {
  167. const selfDefendingEnabled: boolean = true;
  168. describe('Variant #1: correct code evaluation for single-line code', () => {
  169. describe('Variant #1: index shift amount is `0`', () => {
  170. const index: string = '0x0';
  171. const indexShiftAmount: number = 0;
  172. const expectedDecodedValue: string = 'test1test1';
  173. let decodedValue: string;
  174. before(async() => {
  175. const stringArrayTemplate = format(StringArrayTemplate(), {
  176. stringArrayName,
  177. stringArrayFunctionName,
  178. stringArrayStorageItems: `'${cryptUtilsSwappedAlphabet.btoa('test1test1')}'`
  179. });
  180. const atobPolyfill = format(AtobTemplate(selfDefendingEnabled), {
  181. atobFunctionName
  182. });
  183. const atobDecodeTemplate: string = format(
  184. StringArrayBase64DecodeTemplate(randomGenerator),
  185. {
  186. atobPolyfill,
  187. atobFunctionName,
  188. selfDefendingCode: '',
  189. stringArrayCacheName,
  190. stringArrayCallsWrapperName
  191. }
  192. );
  193. const stringArrayCallsWrapperTemplate: string = await minimizeCode(
  194. format(StringArrayCallsWrapperTemplate(), {
  195. decodeCodeHelperTemplate: atobDecodeTemplate,
  196. indexShiftAmount,
  197. stringArrayCacheName,
  198. stringArrayCallsWrapperName,
  199. stringArrayFunctionName
  200. })
  201. );
  202. decodedValue = Function(`
  203. ${stringArrayTemplate}
  204. ${stringArrayCallsWrapperTemplate}
  205. return ${stringArrayCallsWrapperName}(${index});
  206. `)();
  207. });
  208. it('should correctly return decoded value', () => {
  209. assert.deepEqual(decodedValue, expectedDecodedValue);
  210. });
  211. });
  212. });
  213. describe('Variant #2: invalid code evaluation for multi-line code', () => {
  214. describe('Variant #1: index shift amount is `0`', () => {
  215. const index: string = '0x0';
  216. const indexShiftAmount: number = 0;
  217. const expectedDecodedValue: string = 'test18est1';
  218. let decodedValue: string;
  219. before(() => {
  220. const stringArrayTemplate = format(StringArrayTemplate(), {
  221. stringArrayName,
  222. stringArrayFunctionName,
  223. stringArrayStorageItems: `'${cryptUtilsSwappedAlphabet.btoa('test1test1')}'`
  224. });
  225. const atobPolyfill = format(AtobTemplate(selfDefendingEnabled), {
  226. atobFunctionName
  227. });
  228. const atobDecodeTemplate: string = format(
  229. StringArrayBase64DecodeTemplate(randomGenerator),
  230. {
  231. atobPolyfill,
  232. atobFunctionName,
  233. selfDefendingCode: '',
  234. stringArrayCacheName,
  235. stringArrayCallsWrapperName
  236. }
  237. );
  238. const stringArrayCallsWrapperTemplate: string = format(StringArrayCallsWrapperTemplate(), {
  239. decodeCodeHelperTemplate: atobDecodeTemplate,
  240. indexShiftAmount,
  241. stringArrayCacheName,
  242. stringArrayCallsWrapperName,
  243. stringArrayFunctionName
  244. });
  245. decodedValue = Function(`
  246. ${stringArrayTemplate}
  247. ${stringArrayCallsWrapperTemplate}
  248. return ${stringArrayCallsWrapperName}(${index});
  249. `)();
  250. });
  251. it('should correctly return decoded value', () => {
  252. assert.deepEqual(decodedValue, expectedDecodedValue);
  253. });
  254. });
  255. });
  256. });
  257. });
  258. describe('Variant #2: `rc4` encoding', () => {
  259. describe('Variant #1: `selfDefending` option is disabled', () => {
  260. const selfDefendingEnabled: boolean = false;
  261. describe('Variant #1: index shift amount is `0`', () => {
  262. const index: string = '0x0';
  263. const key: string = 'key';
  264. const indexShiftAmount: number = 0;
  265. const expectedDecodedValue: string = 'test1';
  266. let decodedValue: string;
  267. before(() => {
  268. const stringArrayTemplate = format(StringArrayTemplate(), {
  269. stringArrayName,
  270. stringArrayFunctionName,
  271. stringArrayStorageItems: `'${cryptUtilsSwappedAlphabet.btoa(cryptUtilsSwappedAlphabet.rc4('test1', key))}'`
  272. });
  273. const atobPolyfill = format(AtobTemplate(selfDefendingEnabled), {
  274. atobFunctionName
  275. });
  276. const rc4Polyfill = format(Rc4Template(), {
  277. atobFunctionName,
  278. rc4FunctionName
  279. });
  280. const rc4decodeCodeHelperTemplate: string = format(
  281. StringArrayRC4DecodeTemplate(randomGenerator),
  282. {
  283. atobPolyfill,
  284. rc4Polyfill,
  285. rc4FunctionName,
  286. selfDefendingCode: '',
  287. stringArrayCacheName,
  288. stringArrayCallsWrapperName
  289. }
  290. );
  291. const stringArrayCallsWrapperTemplate: string = format(StringArrayCallsWrapperTemplate(), {
  292. decodeCodeHelperTemplate: rc4decodeCodeHelperTemplate,
  293. indexShiftAmount,
  294. stringArrayCacheName,
  295. stringArrayCallsWrapperName,
  296. stringArrayFunctionName
  297. });
  298. decodedValue = Function(`
  299. ${stringArrayTemplate}
  300. ${stringArrayCallsWrapperTemplate}
  301. return ${stringArrayCallsWrapperName}('${index}', '${key}');
  302. `)();
  303. });
  304. it('should correctly return decoded value', () => {
  305. assert.deepEqual(decodedValue, expectedDecodedValue);
  306. });
  307. });
  308. describe('Variant #2: index shift amount is `5`', () => {
  309. const index: string = '0x5';
  310. const key: string = 'key';
  311. const indexShiftAmount: number = 5;
  312. const expectedDecodedValue: string = 'test1';
  313. let decodedValue: string;
  314. before(() => {
  315. const stringArrayTemplate = format(StringArrayTemplate(), {
  316. stringArrayName,
  317. stringArrayFunctionName,
  318. stringArrayStorageItems: `'${cryptUtilsSwappedAlphabet.btoa(cryptUtilsSwappedAlphabet.rc4('test1', key))}'`
  319. });
  320. const atobPolyfill = format(AtobTemplate(selfDefendingEnabled), {
  321. atobFunctionName
  322. });
  323. const rc4Polyfill = format(Rc4Template(), {
  324. atobFunctionName,
  325. rc4FunctionName
  326. });
  327. const rc4decodeCodeHelperTemplate: string = format(
  328. StringArrayRC4DecodeTemplate(randomGenerator),
  329. {
  330. atobPolyfill,
  331. rc4Polyfill,
  332. rc4FunctionName,
  333. selfDefendingCode: '',
  334. stringArrayCacheName,
  335. stringArrayCallsWrapperName
  336. }
  337. );
  338. const stringArrayCallsWrapperTemplate: string = format(StringArrayCallsWrapperTemplate(), {
  339. decodeCodeHelperTemplate: rc4decodeCodeHelperTemplate,
  340. indexShiftAmount,
  341. stringArrayCacheName,
  342. stringArrayCallsWrapperName,
  343. stringArrayFunctionName
  344. });
  345. decodedValue = Function(`
  346. ${stringArrayTemplate}
  347. ${stringArrayCallsWrapperTemplate}
  348. return ${stringArrayCallsWrapperName}('${index}', '${key}');
  349. `)();
  350. });
  351. it('should correctly return decoded value', () => {
  352. assert.deepEqual(decodedValue, expectedDecodedValue);
  353. });
  354. });
  355. });
  356. describe('Variant #2: `selfDefending` option is enabled', () => {
  357. const selfDefendingEnabled: boolean = true;
  358. describe('Variant #1: correct code evaluation for single-line code', () => {
  359. describe('Variant #1: index shift amount is `0`', () => {
  360. const index: string = '0x0';
  361. const key: string = 'key';
  362. const indexShiftAmount: number = 0;
  363. const expectedDecodedValue: string = 'test1';
  364. let decodedValue: string;
  365. before(async() => {
  366. const stringArrayTemplate = format(StringArrayTemplate(), {
  367. stringArrayName,
  368. stringArrayFunctionName,
  369. stringArrayStorageItems: `'${cryptUtilsSwappedAlphabet.btoa(cryptUtilsSwappedAlphabet.rc4('test1', key))}'`
  370. });
  371. const atobPolyfill = format(AtobTemplate(selfDefendingEnabled), {
  372. atobFunctionName
  373. });
  374. const rc4Polyfill = format(Rc4Template(), {
  375. atobFunctionName,
  376. rc4FunctionName
  377. });
  378. const rc4decodeCodeHelperTemplate: string = format(
  379. StringArrayRC4DecodeTemplate(randomGenerator),
  380. {
  381. atobPolyfill,
  382. rc4Polyfill,
  383. rc4FunctionName,
  384. selfDefendingCode: '',
  385. stringArrayCacheName,
  386. stringArrayCallsWrapperName
  387. }
  388. );
  389. const stringArrayCallsWrapperTemplate: string = await minimizeCode(
  390. format(StringArrayCallsWrapperTemplate(), {
  391. decodeCodeHelperTemplate: rc4decodeCodeHelperTemplate,
  392. indexShiftAmount,
  393. stringArrayCacheName,
  394. stringArrayCallsWrapperName,
  395. stringArrayFunctionName
  396. })
  397. );
  398. console.log(stringArrayCallsWrapperTemplate);
  399. decodedValue = Function(`
  400. ${stringArrayTemplate}
  401. ${stringArrayCallsWrapperTemplate}
  402. return ${stringArrayCallsWrapperName}('${index}', '${key}');
  403. `)();
  404. });
  405. it('should correctly return decoded value', () => {
  406. assert.deepEqual(decodedValue, expectedDecodedValue);
  407. });
  408. });
  409. });
  410. describe('Variant #2: invalid code evaluation for multi-line code', () => {
  411. describe('Variant #1: index shift amount is `0`', () => {
  412. const index: string = '0x0';
  413. const key: string = 'key';
  414. const indexShiftAmount: number = 0;
  415. const expectedDecodedValue: string = 'test\u001c';
  416. let decodedValue: string;
  417. before(() => {
  418. const stringArrayTemplate = format(StringArrayTemplate(), {
  419. stringArrayName,
  420. stringArrayFunctionName,
  421. stringArrayStorageItems: `'${cryptUtilsSwappedAlphabet.btoa(cryptUtilsSwappedAlphabet.rc4('test1', key))}'`
  422. });
  423. const atobPolyfill = format(AtobTemplate(selfDefendingEnabled), {
  424. atobFunctionName
  425. });
  426. const rc4Polyfill = format(Rc4Template(), {
  427. atobFunctionName,
  428. rc4FunctionName
  429. });
  430. const rc4decodeCodeHelperTemplate: string = format(
  431. StringArrayRC4DecodeTemplate(randomGenerator),
  432. {
  433. atobPolyfill,
  434. rc4Polyfill,
  435. rc4FunctionName,
  436. selfDefendingCode: '',
  437. stringArrayCacheName,
  438. stringArrayCallsWrapperName
  439. }
  440. );
  441. const stringArrayCallsWrapperTemplate: string = format(StringArrayCallsWrapperTemplate(), {
  442. decodeCodeHelperTemplate: rc4decodeCodeHelperTemplate,
  443. indexShiftAmount,
  444. stringArrayCacheName,
  445. stringArrayCallsWrapperName,
  446. stringArrayFunctionName
  447. });
  448. decodedValue = Function(`
  449. ${stringArrayTemplate}
  450. ${stringArrayCallsWrapperTemplate}
  451. return ${stringArrayCallsWrapperName}('${index}', '${key}');
  452. `)();
  453. });
  454. it('should correctly return decoded value', () => {
  455. assert.deepEqual(decodedValue, expectedDecodedValue);
  456. });
  457. });
  458. });
  459. });
  460. });
  461. describe('Prevailing kind of variables', () => {
  462. describe('`var` kind', () => {
  463. let obfuscatedCode: string,
  464. stringArrayCallsWrapperVariableRegExp: RegExp = /var (_0x(\w){4,6}) *= *(_0x(\w){4,6})\[(_0x(\w){4,6})];/;
  465. beforeEach(() => {
  466. const code: string = readFileAsString(__dirname + '/fixtures/prevailing-kind-of-variables-var.js');
  467. const obfuscationResult: IObfuscationResult = JavaScriptObfuscator.obfuscate(
  468. code,
  469. {
  470. ...NO_ADDITIONAL_NODES_PRESET,
  471. stringArray: true,
  472. stringArrayThreshold: 1
  473. }
  474. );
  475. obfuscatedCode = obfuscationResult.getObfuscatedCode();
  476. });
  477. it('Should return correct kind of variables for string array calls wrapper code', () => {
  478. assert.match(obfuscatedCode, stringArrayCallsWrapperVariableRegExp);
  479. });
  480. it('Should does not break on obfuscating', () => {
  481. assert.doesNotThrow(() => obfuscatedCode);
  482. });
  483. });
  484. describe('`const` kind', () => {
  485. let obfuscatedCode: string,
  486. stringArrayCallsWrapperVariableRegExp: RegExp = /let (_0x(\w){4,6}) *= *(_0x(\w){4,6})\[(_0x(\w){4,6})];/;
  487. beforeEach(() => {
  488. const code: string = readFileAsString(__dirname + '/fixtures/prevailing-kind-of-variables-const.js');
  489. const obfuscationResult: IObfuscationResult = JavaScriptObfuscator.obfuscate(
  490. code,
  491. {
  492. ...NO_ADDITIONAL_NODES_PRESET,
  493. stringArray: true,
  494. stringArrayThreshold: 1
  495. }
  496. );
  497. obfuscatedCode = obfuscationResult.getObfuscatedCode();
  498. });
  499. it('Should return correct kind of variables for string array calls wrapper code', () => {
  500. assert.match(obfuscatedCode, stringArrayCallsWrapperVariableRegExp);
  501. });
  502. it('Should does not break on obfuscating', () => {
  503. assert.doesNotThrow(() => obfuscatedCode);
  504. });
  505. });
  506. describe('`let` kind', () => {
  507. let obfuscatedCode: string,
  508. stringArrayCallsWrapperVariableRegExp: RegExp = /let (_0x(\w){4,6}) *= *(_0x(\w){4,6})\[(_0x(\w){4,6})];/;
  509. beforeEach(() => {
  510. const code: string = readFileAsString(__dirname + '/fixtures/prevailing-kind-of-variables-let.js');
  511. const obfuscationResult: IObfuscationResult = JavaScriptObfuscator.obfuscate(
  512. code,
  513. {
  514. ...NO_ADDITIONAL_NODES_PRESET,
  515. stringArray: true,
  516. stringArrayThreshold: 1
  517. }
  518. );
  519. obfuscatedCode = obfuscationResult.getObfuscatedCode();
  520. });
  521. it('Should return correct kind of variables for string array calls wrapper code', () => {
  522. assert.match(obfuscatedCode, stringArrayCallsWrapperVariableRegExp);
  523. });
  524. it('Should does not break on obfuscating', () => {
  525. assert.doesNotThrow(() => obfuscatedCode);
  526. });
  527. });
  528. });
  529. });