rp.c 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922
  1. /**
  2. * Author......: Jens Steube <jens.steube@gmail.com>
  3. * License.....: MIT
  4. */
  5. #include "common.h"
  6. #include "rp.h"
  7. #define NEXT_RULEPOS(rp) if (++(rp) == rule_len) return (RULE_RC_SYNTAX_ERROR)
  8. #define NEXT_RPTOI(r,rp,up) if (((up) = conv_ctoi ((r)[(rp)])) == -1) return (RULE_RC_SYNTAX_ERROR)
  9. #define MANGLE_TOGGLE_AT(a,p) if (class_alpha ((a)[(p)])) (a)[(p)] ^= 0x20
  10. #define MANGLE_LOWER_AT(a,p) if (class_upper ((a)[(p)])) (a)[(p)] ^= 0x20
  11. #define MANGLE_UPPER_AT(a,p) if (class_lower ((a)[(p)])) (a)[(p)] ^= 0x20
  12. /* #define MANGLE_SWITCH(a,l,r) { char c = (l); arr[(r)] = arr[(l)]; arr[(l)] = c; } */
  13. /* #define MANGLE_SWITCH(a,l,r) { char c = (l); (a)[(r)] = (a)[(l)]; (a)[(l)] = c; } */
  14. #define MANGLE_SWITCH(a,l,r) { char c = (a)[(r)]; (a)[(r)] = (a)[(l)]; (a)[(l)] = c; }
  15. bool class_num (char c)
  16. {
  17. return ((c >= '0') && (c <= '9'));
  18. }
  19. bool class_lower (char c)
  20. {
  21. return ((c >= 'a') && (c <= 'z'));
  22. }
  23. bool class_upper (char c)
  24. {
  25. return ((c >= 'A') && (c <= 'Z'));
  26. }
  27. bool class_alpha (char c)
  28. {
  29. return (class_lower (c) || class_upper (c));
  30. }
  31. char conv_ctoi (char c)
  32. {
  33. if (class_num (c))
  34. {
  35. return c - '0';
  36. }
  37. else if (class_upper (c))
  38. {
  39. return c - 'A' + (char) 10;
  40. }
  41. return (char) (-1);
  42. }
  43. int mangle_lrest (char arr[BLOCK_SIZE], int arr_len)
  44. {
  45. int pos;
  46. for (pos = 0; pos < arr_len; pos++) MANGLE_LOWER_AT (arr, pos);
  47. return (arr_len);
  48. }
  49. int mangle_urest (char arr[BLOCK_SIZE], int arr_len)
  50. {
  51. int pos;
  52. for (pos = 0; pos < arr_len; pos++) MANGLE_UPPER_AT (arr, pos);
  53. return (arr_len);
  54. }
  55. int mangle_trest (char arr[BLOCK_SIZE], int arr_len)
  56. {
  57. int pos;
  58. for (pos = 0; pos < arr_len; pos++) MANGLE_TOGGLE_AT (arr, pos);
  59. return (arr_len);
  60. }
  61. int mangle_reverse (char arr[BLOCK_SIZE], int arr_len)
  62. {
  63. int l;
  64. int r;
  65. for (l = 0; l < arr_len; l++)
  66. {
  67. r = arr_len - 1 - l;
  68. if (l >= r) break;
  69. MANGLE_SWITCH (arr, l, r);
  70. }
  71. return (arr_len);
  72. }
  73. int mangle_double (char arr[BLOCK_SIZE], int arr_len)
  74. {
  75. if ((arr_len * 2) >= BLOCK_SIZE) return (arr_len);
  76. memcpy (&arr[arr_len], arr, (size_t) arr_len);
  77. return (arr_len * 2);
  78. }
  79. int mangle_double_times (char arr[BLOCK_SIZE], int arr_len, int times)
  80. {
  81. if (((arr_len * times) + arr_len) >= BLOCK_SIZE) return (arr_len);
  82. int orig_len = arr_len;
  83. int i;
  84. for (i = 0; i < times; i++)
  85. {
  86. memcpy (&arr[arr_len], arr, orig_len);
  87. arr_len += orig_len;
  88. }
  89. return (arr_len);
  90. }
  91. int mangle_reflect (char arr[BLOCK_SIZE], int arr_len)
  92. {
  93. if ((arr_len * 2) >= BLOCK_SIZE) return (arr_len);
  94. mangle_double (arr, arr_len);
  95. mangle_reverse (arr + arr_len, arr_len);
  96. return (arr_len * 2);
  97. }
  98. int mangle_rotate_left (char arr[BLOCK_SIZE], int arr_len)
  99. {
  100. int l;
  101. int r;
  102. for (l = 0, r = arr_len - 1; r > 0; r--)
  103. {
  104. MANGLE_SWITCH (arr, l, r);
  105. }
  106. return (arr_len);
  107. }
  108. int mangle_rotate_right (char arr[BLOCK_SIZE], int arr_len)
  109. {
  110. int l;
  111. int r;
  112. for (l = 0, r = arr_len - 1; l < r; l++)
  113. {
  114. MANGLE_SWITCH (arr, l, r);
  115. }
  116. return (arr_len);
  117. }
  118. int mangle_append (char arr[BLOCK_SIZE], int arr_len, char c)
  119. {
  120. if ((arr_len + 1) >= BLOCK_SIZE) return (arr_len);
  121. arr[arr_len] = c;
  122. return (arr_len + 1);
  123. }
  124. int mangle_prepend (char arr[BLOCK_SIZE], int arr_len, char c)
  125. {
  126. if ((arr_len + 1) >= BLOCK_SIZE) return (arr_len);
  127. int arr_pos;
  128. for (arr_pos = arr_len - 1; arr_pos > -1; arr_pos--)
  129. {
  130. arr[arr_pos + 1] = arr[arr_pos];
  131. }
  132. arr[0] = c;
  133. return (arr_len + 1);
  134. }
  135. int mangle_delete_at (char arr[BLOCK_SIZE], int arr_len, int upos)
  136. {
  137. if (upos >= arr_len) return (arr_len);
  138. int arr_pos;
  139. for (arr_pos = upos; arr_pos < arr_len - 1; arr_pos++)
  140. {
  141. arr[arr_pos] = arr[arr_pos + 1];
  142. }
  143. return (arr_len - 1);
  144. }
  145. int mangle_extract (char arr[BLOCK_SIZE], int arr_len, int upos, int ulen)
  146. {
  147. if (upos >= arr_len) return (arr_len);
  148. if ((upos + ulen) > arr_len) return (arr_len);
  149. int arr_pos;
  150. for (arr_pos = 0; arr_pos < ulen; arr_pos++)
  151. {
  152. arr[arr_pos] = arr[upos + arr_pos];
  153. }
  154. return (ulen);
  155. }
  156. int mangle_omit (char arr[BLOCK_SIZE], int arr_len, int upos, int ulen)
  157. {
  158. if (upos >= arr_len) return (arr_len);
  159. if ((upos + ulen) > arr_len) return (arr_len);
  160. int arr_pos;
  161. for (arr_pos = upos; arr_pos < arr_len - ulen; arr_pos++)
  162. {
  163. arr[arr_pos] = arr[arr_pos + ulen];
  164. }
  165. return (arr_len - ulen);
  166. }
  167. int mangle_insert (char arr[BLOCK_SIZE], int arr_len, int upos, char c)
  168. {
  169. if (upos > arr_len) return (arr_len);
  170. if ((arr_len + 1) >= BLOCK_SIZE) return (arr_len);
  171. int arr_pos;
  172. for (arr_pos = arr_len - 1; arr_pos > upos - 1; arr_pos--)
  173. {
  174. arr[arr_pos + 1] = arr[arr_pos];
  175. }
  176. arr[upos] = c;
  177. return (arr_len + 1);
  178. }
  179. int mangle_insert_multi (char arr[BLOCK_SIZE], int arr_len, int arr_pos, char arr2[BLOCK_SIZE], int arr2_len, int arr2_pos, int arr2_cpy)
  180. {
  181. if ((arr_len + arr2_cpy) > BLOCK_SIZE) return (RULE_RC_REJECT_ERROR);
  182. if (arr_pos > arr_len) return (RULE_RC_REJECT_ERROR);
  183. if (arr2_pos > arr2_len) return (RULE_RC_REJECT_ERROR);
  184. if ((arr2_pos + arr2_cpy) > arr2_len) return (RULE_RC_REJECT_ERROR);
  185. if (arr2_cpy < 1) return (RULE_RC_SYNTAX_ERROR);
  186. memcpy (arr2, arr2 + arr2_pos, arr2_len - arr2_pos);
  187. memcpy (arr2 + arr2_cpy, arr + arr_pos, arr_len - arr_pos);
  188. memcpy (arr + arr_pos, arr2, arr_len - arr_pos + arr2_cpy);
  189. return (arr_len + arr2_cpy);
  190. }
  191. int mangle_overstrike (char arr[BLOCK_SIZE], int arr_len, int upos, char c)
  192. {
  193. if (upos >= arr_len) return (arr_len);
  194. arr[upos] = c;
  195. return (arr_len);
  196. }
  197. int mangle_truncate_at (char arr[BLOCK_SIZE], int arr_len, int upos)
  198. {
  199. if (upos >= arr_len) return (arr_len);
  200. memset (arr + upos, 0, arr_len - upos);
  201. return (upos);
  202. }
  203. int mangle_replace (char arr[BLOCK_SIZE], int arr_len, char oldc, char newc)
  204. {
  205. int arr_pos;
  206. for (arr_pos = 0; arr_pos < arr_len; arr_pos++)
  207. {
  208. if (arr[arr_pos] != oldc) continue;
  209. arr[arr_pos] = newc;
  210. }
  211. return (arr_len);
  212. }
  213. int mangle_purgechar (char arr[BLOCK_SIZE], int arr_len, char c)
  214. {
  215. int arr_pos;
  216. int ret_len;
  217. for (ret_len = 0, arr_pos = 0; arr_pos < arr_len; arr_pos++)
  218. {
  219. if (arr[arr_pos] == c) continue;
  220. arr[ret_len] = arr[arr_pos];
  221. ret_len++;
  222. }
  223. return (ret_len);
  224. }
  225. int mangle_dupeblock_prepend (char arr[BLOCK_SIZE], int arr_len, int ulen)
  226. {
  227. if (ulen > arr_len) return (arr_len);
  228. if ((arr_len + ulen) >= BLOCK_SIZE) return (arr_len);
  229. char cs[100];
  230. memcpy (cs, arr, ulen);
  231. int i;
  232. for (i = 0; i < ulen; i++)
  233. {
  234. char c = cs[i];
  235. arr_len = mangle_insert (arr, arr_len, i, c);
  236. }
  237. return (arr_len);
  238. }
  239. int mangle_dupeblock_append (char arr[BLOCK_SIZE], int arr_len, int ulen)
  240. {
  241. if (ulen > arr_len) return (arr_len);
  242. if ((arr_len + ulen) >= BLOCK_SIZE) return (arr_len);
  243. int upos = arr_len - ulen;
  244. int i;
  245. for (i = 0; i < ulen; i++)
  246. {
  247. char c = arr[upos + i];
  248. arr_len = mangle_append (arr, arr_len, c);
  249. }
  250. return (arr_len);
  251. }
  252. int mangle_dupechar_at (char arr[BLOCK_SIZE], int arr_len, int upos, int ulen)
  253. {
  254. if ( arr_len == 0) return (arr_len);
  255. if ((arr_len + ulen) >= BLOCK_SIZE) return (arr_len);
  256. char c = arr[upos];
  257. int i;
  258. for (i = 0; i < ulen; i++)
  259. {
  260. arr_len = mangle_insert (arr, arr_len, upos, c);
  261. }
  262. return (arr_len);
  263. }
  264. int mangle_dupechar (char arr[BLOCK_SIZE], int arr_len)
  265. {
  266. if ( arr_len == 0) return (arr_len);
  267. if ((arr_len + arr_len) >= BLOCK_SIZE) return (arr_len);
  268. int arr_pos;
  269. for (arr_pos = arr_len - 1; arr_pos > -1; arr_pos--)
  270. {
  271. int new_pos = arr_pos * 2;
  272. arr[new_pos] = arr[arr_pos];
  273. arr[new_pos + 1] = arr[arr_pos];
  274. }
  275. return (arr_len * 2);
  276. }
  277. int mangle_switch_at_check (char arr[BLOCK_SIZE], int arr_len, int upos, int upos2)
  278. {
  279. if (upos >= arr_len) return (arr_len);
  280. if (upos2 >= arr_len) return (arr_len);
  281. MANGLE_SWITCH (arr, upos, upos2);
  282. return (arr_len);
  283. }
  284. int mangle_switch_at (char arr[BLOCK_SIZE], int arr_len, int upos, int upos2)
  285. {
  286. MANGLE_SWITCH (arr, upos, upos2);
  287. return (arr_len);
  288. }
  289. int mangle_chr_shiftl (uint8_t arr[BLOCK_SIZE], int arr_len, int upos)
  290. {
  291. if (upos >= arr_len) return (arr_len);
  292. arr[upos] <<= 1;
  293. return (arr_len);
  294. }
  295. int mangle_chr_shiftr (uint8_t arr[BLOCK_SIZE], int arr_len, int upos)
  296. {
  297. if (upos >= arr_len) return (arr_len);
  298. arr[upos] >>= 1;
  299. return (arr_len);
  300. }
  301. int mangle_chr_incr (uint8_t arr[BLOCK_SIZE], int arr_len, int upos)
  302. {
  303. if (upos >= arr_len) return (arr_len);
  304. arr[upos] += 1;
  305. return (arr_len);
  306. }
  307. int mangle_chr_decr (uint8_t arr[BLOCK_SIZE], int arr_len, int upos)
  308. {
  309. if (upos >= arr_len) return (arr_len);
  310. arr[upos] -= 1;
  311. return (arr_len);
  312. }
  313. int mangle_title (char arr[BLOCK_SIZE], int arr_len)
  314. {
  315. int upper_next = 1;
  316. int pos;
  317. for (pos = 0; pos < arr_len; pos++)
  318. {
  319. if (arr[pos] == ' ')
  320. {
  321. upper_next = 1;
  322. continue;
  323. }
  324. if (upper_next)
  325. {
  326. upper_next = 0;
  327. MANGLE_UPPER_AT (arr, pos);
  328. }
  329. else
  330. {
  331. MANGLE_LOWER_AT (arr, pos);
  332. }
  333. }
  334. return (arr_len);
  335. }
  336. int generate_random_rule (char rule_buf[RP_RULE_BUFSIZ], uint32_t rp_gen_func_min, uint32_t rp_gen_func_max)
  337. {
  338. uint32_t rp_gen_num = get_random_num (rp_gen_func_min, rp_gen_func_max);
  339. uint32_t j;
  340. uint32_t rule_pos = 0;
  341. for (j = 0; j < rp_gen_num; j++)
  342. {
  343. uint32_t r = 0;
  344. uint32_t p1 = 0;
  345. uint32_t p2 = 0;
  346. uint32_t p3 = 0;
  347. switch ((char) get_random_num (0, 9))
  348. {
  349. case 0:
  350. r = get_random_num (0, sizeof (grp_op_nop));
  351. rule_buf[rule_pos++] = grp_op_nop[r];
  352. break;
  353. case 1:
  354. r = get_random_num (0, sizeof (grp_op_pos_p0));
  355. rule_buf[rule_pos++] = grp_op_pos_p0[r];
  356. p1 = get_random_num (0, sizeof (grp_pos));
  357. rule_buf[rule_pos++] = grp_pos[p1];
  358. break;
  359. case 2:
  360. r = get_random_num (0, sizeof (grp_op_pos_p1));
  361. rule_buf[rule_pos++] = grp_op_pos_p1[r];
  362. p1 = get_random_num (1, 6);
  363. rule_buf[rule_pos++] = grp_pos[p1];
  364. break;
  365. case 3:
  366. r = get_random_num (0, sizeof (grp_op_chr));
  367. rule_buf[rule_pos++] = grp_op_chr[r];
  368. p1 = get_random_num (0x20, 0x7e);
  369. rule_buf[rule_pos++] = (char) p1;
  370. break;
  371. case 4:
  372. r = get_random_num (0, sizeof (grp_op_chr_chr));
  373. rule_buf[rule_pos++] = grp_op_chr_chr[r];
  374. p1 = get_random_num (0x20, 0x7e);
  375. rule_buf[rule_pos++] = (char) p1;
  376. p2 = get_random_num (0x20, 0x7e);
  377. while (p1 == p2)
  378. p2 = get_random_num (0x20, 0x7e);
  379. rule_buf[rule_pos++] = (char) p2;
  380. break;
  381. case 5:
  382. r = get_random_num (0, sizeof (grp_op_pos_chr));
  383. rule_buf[rule_pos++] = grp_op_pos_chr[r];
  384. p1 = get_random_num (0, sizeof (grp_pos));
  385. rule_buf[rule_pos++] = grp_pos[p1];
  386. p2 = get_random_num (0x20, 0x7e);
  387. rule_buf[rule_pos++] = (char) p2;
  388. break;
  389. case 6:
  390. r = get_random_num (0, sizeof (grp_op_pos_pos0));
  391. rule_buf[rule_pos++] = grp_op_pos_pos0[r];
  392. p1 = get_random_num (0, sizeof (grp_pos));
  393. rule_buf[rule_pos++] = grp_pos[p1];
  394. p2 = get_random_num (0, sizeof (grp_pos));
  395. while (p1 == p2)
  396. p2 = get_random_num (0, sizeof (grp_pos));
  397. rule_buf[rule_pos++] = grp_pos[p2];
  398. break;
  399. case 7:
  400. r = get_random_num (0, sizeof (grp_op_pos_pos1));
  401. rule_buf[rule_pos++] = grp_op_pos_pos1[r];
  402. p1 = get_random_num (0, sizeof (grp_pos));
  403. rule_buf[rule_pos++] = grp_pos[p1];
  404. p2 = get_random_num (1, sizeof (grp_pos));
  405. while (p1 == p2)
  406. p2 = get_random_num (1, sizeof (grp_pos));
  407. rule_buf[rule_pos++] = grp_pos[p2];
  408. break;
  409. case 8:
  410. r = get_random_num (0, sizeof (grp_op_pos1_pos2_pos3));
  411. rule_buf[rule_pos++] = grp_op_pos1_pos2_pos3[r];
  412. p1 = get_random_num (0, sizeof (grp_pos));
  413. rule_buf[rule_pos++] = grp_pos[p1];
  414. p2 = get_random_num (1, sizeof (grp_pos));
  415. rule_buf[rule_pos++] = grp_pos[p1];
  416. p3 = get_random_num (0, sizeof (grp_pos));
  417. rule_buf[rule_pos++] = grp_pos[p3];
  418. break;
  419. }
  420. }
  421. return (rule_pos);
  422. }
  423. int apply_rule (char *rule, int rule_len, char in[BLOCK_SIZE], int in_len, char out[BLOCK_SIZE])
  424. {
  425. char mem[BLOCK_SIZE];
  426. if (in == NULL) return (RULE_RC_REJECT_ERROR);
  427. if (out == NULL) return (RULE_RC_REJECT_ERROR);
  428. if (in_len < 1) return (RULE_RC_REJECT_ERROR);
  429. if (rule_len < 1) return (RULE_RC_REJECT_ERROR);
  430. int out_len = in_len;
  431. int mem_len = in_len;
  432. memcpy (out, in, out_len);
  433. int rule_pos;
  434. for (rule_pos = 0; rule_pos < rule_len; rule_pos++)
  435. {
  436. int upos; int upos2;
  437. int ulen;
  438. switch (rule[rule_pos])
  439. {
  440. case ' ':
  441. break;
  442. case RULE_OP_MANGLE_NOOP:
  443. break;
  444. case RULE_OP_MANGLE_LREST:
  445. out_len = mangle_lrest (out, out_len);
  446. break;
  447. case RULE_OP_MANGLE_UREST:
  448. out_len = mangle_urest (out, out_len);
  449. break;
  450. case RULE_OP_MANGLE_LREST_UFIRST:
  451. out_len = mangle_lrest (out, out_len);
  452. if (out_len) MANGLE_UPPER_AT (out, 0);
  453. break;
  454. case RULE_OP_MANGLE_UREST_LFIRST:
  455. out_len = mangle_urest (out, out_len);
  456. if (out_len) MANGLE_LOWER_AT (out, 0);
  457. break;
  458. case RULE_OP_MANGLE_TREST:
  459. out_len = mangle_trest (out, out_len);
  460. break;
  461. case RULE_OP_MANGLE_TOGGLE_AT:
  462. NEXT_RULEPOS (rule_pos);
  463. NEXT_RPTOI (rule, rule_pos, upos);
  464. if (upos < out_len) MANGLE_TOGGLE_AT (out, upos);
  465. break;
  466. case RULE_OP_MANGLE_REVERSE:
  467. out_len = mangle_reverse (out, out_len);
  468. break;
  469. case RULE_OP_MANGLE_DUPEWORD:
  470. out_len = mangle_double (out, out_len);
  471. break;
  472. case RULE_OP_MANGLE_DUPEWORD_TIMES:
  473. NEXT_RULEPOS (rule_pos);
  474. NEXT_RPTOI (rule, rule_pos, ulen);
  475. out_len = mangle_double_times (out, out_len, ulen);
  476. break;
  477. case RULE_OP_MANGLE_REFLECT:
  478. out_len = mangle_reflect (out, out_len);
  479. break;
  480. case RULE_OP_MANGLE_ROTATE_LEFT:
  481. mangle_rotate_left (out, out_len);
  482. break;
  483. case RULE_OP_MANGLE_ROTATE_RIGHT:
  484. mangle_rotate_right (out, out_len);
  485. break;
  486. case RULE_OP_MANGLE_APPEND:
  487. NEXT_RULEPOS (rule_pos);
  488. out_len = mangle_append (out, out_len, rule[rule_pos]);
  489. break;
  490. case RULE_OP_MANGLE_PREPEND:
  491. NEXT_RULEPOS (rule_pos);
  492. out_len = mangle_prepend (out, out_len, rule[rule_pos]);
  493. break;
  494. case RULE_OP_MANGLE_DELETE_FIRST:
  495. out_len = mangle_delete_at (out, out_len, 0);
  496. break;
  497. case RULE_OP_MANGLE_DELETE_LAST:
  498. out_len = mangle_delete_at (out, out_len, (out_len) ? out_len - 1 : 0);
  499. break;
  500. case RULE_OP_MANGLE_DELETE_AT:
  501. NEXT_RULEPOS (rule_pos);
  502. NEXT_RPTOI (rule, rule_pos, upos);
  503. out_len = mangle_delete_at (out, out_len, upos);
  504. break;
  505. case RULE_OP_MANGLE_EXTRACT:
  506. NEXT_RULEPOS (rule_pos);
  507. NEXT_RPTOI (rule, rule_pos, upos);
  508. NEXT_RULEPOS (rule_pos);
  509. NEXT_RPTOI (rule, rule_pos, ulen);
  510. out_len = mangle_extract (out, out_len, upos, ulen);
  511. break;
  512. case RULE_OP_MANGLE_OMIT:
  513. NEXT_RULEPOS (rule_pos);
  514. NEXT_RPTOI (rule, rule_pos, upos);
  515. NEXT_RULEPOS (rule_pos);
  516. NEXT_RPTOI (rule, rule_pos, ulen);
  517. out_len = mangle_omit (out, out_len, upos, ulen);
  518. break;
  519. case RULE_OP_MANGLE_INSERT:
  520. NEXT_RULEPOS (rule_pos);
  521. NEXT_RPTOI (rule, rule_pos, upos);
  522. NEXT_RULEPOS (rule_pos);
  523. out_len = mangle_insert (out, out_len, upos, rule[rule_pos]);
  524. break;
  525. case RULE_OP_MANGLE_OVERSTRIKE:
  526. NEXT_RULEPOS (rule_pos);
  527. NEXT_RPTOI (rule, rule_pos, upos);
  528. NEXT_RULEPOS (rule_pos);
  529. out_len = mangle_overstrike (out, out_len, upos, rule[rule_pos]);
  530. break;
  531. case RULE_OP_MANGLE_TRUNCATE_AT:
  532. NEXT_RULEPOS (rule_pos);
  533. NEXT_RPTOI (rule, rule_pos, upos);
  534. out_len = mangle_truncate_at (out, out_len, upos);
  535. break;
  536. case RULE_OP_MANGLE_REPLACE:
  537. NEXT_RULEPOS (rule_pos);
  538. NEXT_RULEPOS (rule_pos);
  539. out_len = mangle_replace (out, out_len, rule[rule_pos - 1], rule[rule_pos]);
  540. break;
  541. case RULE_OP_MANGLE_PURGECHAR:
  542. NEXT_RULEPOS (rule_pos);
  543. out_len = mangle_purgechar (out, out_len, rule[rule_pos]);
  544. break;
  545. case RULE_OP_MANGLE_TOGGLECASE_REC:
  546. /* todo */
  547. break;
  548. case RULE_OP_MANGLE_DUPECHAR_FIRST:
  549. NEXT_RULEPOS (rule_pos);
  550. NEXT_RPTOI (rule, rule_pos, ulen);
  551. out_len = mangle_dupechar_at (out, out_len, 0, ulen);
  552. break;
  553. case RULE_OP_MANGLE_DUPECHAR_LAST:
  554. NEXT_RULEPOS (rule_pos);
  555. NEXT_RPTOI (rule, rule_pos, ulen);
  556. out_len = mangle_dupechar_at (out, out_len, out_len - 1, ulen);
  557. break;
  558. case RULE_OP_MANGLE_DUPECHAR_ALL:
  559. out_len = mangle_dupechar (out, out_len);
  560. break;
  561. case RULE_OP_MANGLE_DUPEBLOCK_FIRST:
  562. NEXT_RULEPOS (rule_pos);
  563. NEXT_RPTOI (rule, rule_pos, ulen);
  564. out_len = mangle_dupeblock_prepend (out, out_len, ulen);
  565. break;
  566. case RULE_OP_MANGLE_DUPEBLOCK_LAST:
  567. NEXT_RULEPOS (rule_pos);
  568. NEXT_RPTOI (rule, rule_pos, ulen);
  569. out_len = mangle_dupeblock_append (out, out_len, ulen);
  570. break;
  571. case RULE_OP_MANGLE_SWITCH_FIRST:
  572. if (out_len >= 2) mangle_switch_at (out, out_len, 0, 1);
  573. break;
  574. case RULE_OP_MANGLE_SWITCH_LAST:
  575. if (out_len >= 2) mangle_switch_at (out, out_len, out_len - 1, out_len - 2);
  576. break;
  577. case RULE_OP_MANGLE_SWITCH_AT:
  578. NEXT_RULEPOS (rule_pos);
  579. NEXT_RPTOI (rule, rule_pos, upos);
  580. NEXT_RULEPOS (rule_pos);
  581. NEXT_RPTOI (rule, rule_pos, upos2);
  582. out_len = mangle_switch_at_check (out, out_len, upos, upos2);
  583. break;
  584. case RULE_OP_MANGLE_CHR_SHIFTL:
  585. NEXT_RULEPOS (rule_pos);
  586. NEXT_RPTOI (rule, rule_pos, upos);
  587. mangle_chr_shiftl ((uint8_t *) out, out_len, upos);
  588. break;
  589. case RULE_OP_MANGLE_CHR_SHIFTR:
  590. NEXT_RULEPOS (rule_pos);
  591. NEXT_RPTOI (rule, rule_pos, upos);
  592. mangle_chr_shiftr ((uint8_t *) out, out_len, upos);
  593. break;
  594. case RULE_OP_MANGLE_CHR_INCR:
  595. NEXT_RULEPOS (rule_pos);
  596. NEXT_RPTOI (rule, rule_pos, upos);
  597. mangle_chr_incr ((uint8_t *) out, out_len, upos);
  598. break;
  599. case RULE_OP_MANGLE_CHR_DECR:
  600. NEXT_RULEPOS (rule_pos);
  601. NEXT_RPTOI (rule, rule_pos, upos);
  602. mangle_chr_decr ((uint8_t *) out, out_len, upos);
  603. break;
  604. case RULE_OP_MANGLE_REPLACE_NP1:
  605. NEXT_RULEPOS (rule_pos);
  606. NEXT_RPTOI (rule, rule_pos, upos);
  607. if ((upos >= 0) && ((upos + 1) < out_len)) mangle_overstrike (out, out_len, upos, out[upos + 1]);
  608. break;
  609. case RULE_OP_MANGLE_REPLACE_NM1:
  610. NEXT_RULEPOS (rule_pos);
  611. NEXT_RPTOI (rule, rule_pos, upos);
  612. if ((upos >= 1) && ((upos + 0) < out_len)) mangle_overstrike (out, out_len, upos, out[upos - 1]);
  613. break;
  614. case RULE_OP_MANGLE_TITLE:
  615. out_len = mangle_title (out, out_len);
  616. break;
  617. case RULE_OP_MANGLE_EXTRACT_MEMORY:
  618. if (mem_len < 1) return (RULE_RC_REJECT_ERROR);
  619. NEXT_RULEPOS (rule_pos);
  620. NEXT_RPTOI (rule, rule_pos, upos);
  621. NEXT_RULEPOS (rule_pos);
  622. NEXT_RPTOI (rule, rule_pos, ulen);
  623. NEXT_RULEPOS (rule_pos);
  624. NEXT_RPTOI (rule, rule_pos, upos2);
  625. if ((out_len = mangle_insert_multi (out, out_len, upos2, mem, mem_len, upos, ulen)) < 1) return (out_len);
  626. break;
  627. case RULE_OP_MANGLE_APPEND_MEMORY:
  628. if (mem_len < 1) return (RULE_RC_REJECT_ERROR);
  629. if ((out_len + mem_len) > BLOCK_SIZE) return (RULE_RC_REJECT_ERROR);
  630. memcpy (out + out_len, mem, mem_len);
  631. out_len += mem_len;
  632. break;
  633. case RULE_OP_MANGLE_PREPEND_MEMORY:
  634. if (mem_len < 1) return (RULE_RC_REJECT_ERROR);
  635. if ((mem_len + out_len) > BLOCK_SIZE) return (RULE_RC_REJECT_ERROR);
  636. memcpy (mem + mem_len, out, out_len);
  637. out_len += mem_len;
  638. memcpy (out, mem, out_len);
  639. break;
  640. case RULE_OP_MEMORIZE_WORD:
  641. memcpy (mem, out, out_len);
  642. mem_len = out_len;
  643. break;
  644. case RULE_OP_REJECT_LESS:
  645. NEXT_RULEPOS (rule_pos);
  646. NEXT_RPTOI (rule, rule_pos, upos);
  647. if (out_len > upos) return (RULE_RC_REJECT_ERROR);
  648. break;
  649. case RULE_OP_REJECT_GREATER:
  650. NEXT_RULEPOS (rule_pos);
  651. NEXT_RPTOI (rule, rule_pos, upos);
  652. if (out_len < upos) return (RULE_RC_REJECT_ERROR);
  653. break;
  654. case RULE_OP_REJECT_CONTAIN:
  655. NEXT_RULEPOS (rule_pos);
  656. if (strchr (out, rule[rule_pos]) != NULL) return (RULE_RC_REJECT_ERROR);
  657. break;
  658. case RULE_OP_REJECT_NOT_CONTAIN:
  659. NEXT_RULEPOS (rule_pos);
  660. if (strchr (out, rule[rule_pos]) == NULL) return (RULE_RC_REJECT_ERROR);
  661. break;
  662. case RULE_OP_REJECT_EQUAL_FIRST:
  663. NEXT_RULEPOS (rule_pos);
  664. if (out[0] != rule[rule_pos]) return (RULE_RC_REJECT_ERROR);
  665. break;
  666. case RULE_OP_REJECT_EQUAL_LAST:
  667. NEXT_RULEPOS (rule_pos);
  668. if (out[out_len - 1] != rule[rule_pos]) return (RULE_RC_REJECT_ERROR);
  669. break;
  670. case RULE_OP_REJECT_EQUAL_AT:
  671. NEXT_RULEPOS (rule_pos);
  672. NEXT_RPTOI (rule, rule_pos, upos);
  673. if ((upos + 1) > out_len) return (RULE_RC_REJECT_ERROR);
  674. NEXT_RULEPOS (rule_pos);
  675. if (out[upos] != rule[rule_pos]) return (RULE_RC_REJECT_ERROR);
  676. break;
  677. case RULE_OP_REJECT_CONTAINS:
  678. NEXT_RULEPOS (rule_pos);
  679. NEXT_RPTOI (rule, rule_pos, upos);
  680. if ((upos + 1) > out_len) return (RULE_RC_REJECT_ERROR);
  681. NEXT_RULEPOS (rule_pos);
  682. int c; int cnt; for (c = 0, cnt = 0; c < out_len; c++) if (out[c] == rule[rule_pos]) cnt++;
  683. if (cnt < upos) return (RULE_RC_REJECT_ERROR);
  684. break;
  685. case RULE_OP_REJECT_MEMORY:
  686. if ((out_len == mem_len) && (memcmp (out, mem, out_len) == 0)) return (RULE_RC_REJECT_ERROR);
  687. break;
  688. default:
  689. return (RULE_RC_SYNTAX_ERROR);
  690. break;
  691. }
  692. }
  693. memset (out + out_len, 0, BLOCK_SIZE - out_len);
  694. return (out_len);
  695. }