PageRenderTime 83ms CodeModel.GetById 18ms RepoModel.GetById 1ms app.codeStats 0ms

/openvas-libraries-4.0.7/nasl/nasl_text_utils.c

#
C | 1365 lines | 1076 code | 183 blank | 106 comment | 270 complexity | 0399b1b923bb51901a535fbff3349361 MD5 | raw file
Possible License(s): BSD-3-Clause, GPL-2.0, LGPL-2.0
  1. /* Nessus Attack Scripting Language
  2. *
  3. * Copyright (C) 2002 - 2004 Tenable Network Security
  4. * Copyright (C) 2009 Greenbone Networks GmbH
  5. *
  6. * This program is free software; you can redistribute it and/or modify
  7. * it under the terms of the GNU General Public License version 2,
  8. * as published by the Free Software Foundation
  9. *
  10. * This program is distributed in the hope that it will be useful,
  11. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. * GNU General Public License for more details.
  14. *
  15. * You should have received a copy of the GNU General Public License
  16. * along with this program; if not, write to the Free Software
  17. * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
  18. *
  19. */
  20. /**
  21. * @file
  22. * This file implements all the functions that are related to
  23. * text-related utilities in the NASL functions.
  24. */
  25. #include <ctype.h> /* for isspace */
  26. #include <string.h> /* for strlen */
  27. #include <unistd.h> /* for getpid */
  28. #include "system.h" /* for erealloc */
  29. #include "nasl_tree.h"
  30. #include "nasl_global_ctxt.h"
  31. #include "nasl_func.h"
  32. #include "nasl_var.h"
  33. #include "nasl_lex_ctxt.h"
  34. #include "exec.h"
  35. #include "strutils.h"
  36. #include "nasl_regex.h"
  37. #include "nasl_debug.h"
  38. #include "nasl_text_utils.h"
  39. tree_cell *
  40. nasl_string (lex_ctxt * lexic)
  41. {
  42. tree_cell *retc;
  43. int vi, vn, newlen;
  44. int sz, typ;
  45. const char *s, *p1;
  46. char *p2;
  47. retc = alloc_tree_cell (0, NULL);
  48. retc->type = CONST_DATA;
  49. retc->size = 0;
  50. retc->x.str_val = emalloc (0);
  51. vn = array_max_index (&lexic->ctx_vars);
  52. for (vi = 0; vi < vn; vi++)
  53. {
  54. if ((typ = get_var_type_by_num (lexic, vi)) == VAR2_UNDEF)
  55. continue;
  56. s = get_str_var_by_num (lexic, vi);
  57. sz = get_var_size_by_num (lexic, vi);
  58. if (sz <= 0)
  59. sz = strlen (s);
  60. newlen = retc->size + sz;
  61. retc->x.str_val = erealloc (retc->x.str_val, newlen + 1);
  62. p2 = retc->x.str_val + retc->size;
  63. p1 = s;
  64. retc->size = newlen;
  65. if (typ != VAR2_STRING)
  66. {
  67. memcpy (p2, p1, sz);
  68. p2[sz] = '\0';
  69. }
  70. else
  71. while (*p1 != '\0')
  72. {
  73. if (*p1 == '\\' && p1[1] != '\0')
  74. {
  75. switch (p1[1])
  76. {
  77. case 'n':
  78. *p2++ = '\n';
  79. break;
  80. case 't':
  81. *p2++ = '\t';
  82. break;
  83. case 'r':
  84. *p2++ = '\r';
  85. break;
  86. case '\\':
  87. *p2++ = '\\';
  88. break;
  89. case 'x':
  90. if (isxdigit (p1[2]) && isxdigit (p1[3]))
  91. {
  92. *p2++ =
  93. 16 * (isdigit (p1[2]) ? p1[2] - '0' : 10 +
  94. tolower (p1[2]) - 'a') +
  95. (isdigit (p1[3]) ? p1[3] - '0' : 10 +
  96. tolower (p1[3]) - 'a');
  97. p1 += 2;
  98. retc->size -= 2;
  99. }
  100. else
  101. {
  102. nasl_perror (lexic,
  103. "Buggy hex value '\\x%c%c' skipped\n",
  104. isprint (p1[2]) ? p1[2] : '.',
  105. isprint (p1[3]) ? p1[3] : '.');
  106. /* We do not increment p1 by 4,
  107. we may miss the end of the string */
  108. }
  109. break;
  110. default:
  111. nasl_perror (lexic, "Unknown%d escape sequence '\\%c'\n",
  112. getpid (), isprint (p1[1]) ? p1[1] : '.');
  113. retc->size--;
  114. break;
  115. }
  116. p1 += 2;
  117. retc->size--;
  118. }
  119. else
  120. *p2++ = *p1++;
  121. }
  122. }
  123. retc->x.str_val[retc->size] = '\0';
  124. return retc;
  125. }
  126. /*---------------------------------------------------------------------*/
  127. #define RAW_STR_LEN 32768
  128. tree_cell *
  129. nasl_rawstring (lex_ctxt * lexic)
  130. {
  131. tree_cell *retc;
  132. int vi, vn, i, j, x;
  133. int sz, typ;
  134. const char *s;
  135. int total_len = 0;
  136. retc = alloc_tree_cell (0, NULL);
  137. retc->type = CONST_DATA;
  138. retc->size = 0;
  139. retc->x.str_val = emalloc (RAW_STR_LEN);
  140. vn = array_max_index (&lexic->ctx_vars);
  141. for (vi = 0; vi < vn && total_len < RAW_STR_LEN - 1; vi++)
  142. {
  143. if ((typ = get_var_type_by_num (lexic, vi)) == VAR2_UNDEF)
  144. continue;
  145. sz = get_var_size_by_num (lexic, vi);
  146. if (typ == VAR2_INT)
  147. {
  148. x = get_int_var_by_num (lexic, vi, 0);
  149. retc->x.str_val[total_len++] = x;
  150. }
  151. else
  152. {
  153. int current_len = sz;
  154. char str[RAW_STR_LEN];
  155. s = get_str_var_by_num (lexic, vi);
  156. if (sz <= 0)
  157. sz = strlen (s);
  158. if (sz >= RAW_STR_LEN)
  159. {
  160. nasl_perror (lexic, "Error. Too long argument in raw_string()\n");
  161. break;
  162. }
  163. /* Should we test if the variable is composed only of digits? */
  164. if (typ == VAR2_STRING)
  165. {
  166. /* TBD:I should decide at last if we keep those "purified"
  167. * string or not, and if we do, if "CONST_STR" & "VAR2_STR" are
  168. * "not pure" strings */
  169. for (i = 0, j = 0; i < sz; i++)
  170. {
  171. if (s[i] == '\\')
  172. {
  173. if (s[i + 1] == 'n')
  174. {
  175. str[j++] = '\n';
  176. i++;
  177. }
  178. else if (s[i + 1] == 't')
  179. {
  180. str[j++] = '\t';
  181. i++;
  182. }
  183. else if (s[i + 1] == 'r')
  184. {
  185. str[j++] = '\r';
  186. i++;
  187. }
  188. else if (s[i + 1] == 'x' && isxdigit (s[i + 2])
  189. && isxdigit (s[i + 3]))
  190. {
  191. x = 0;
  192. if (isdigit (s[i + 2]))
  193. x = (s[i + 2] - '0') * 16;
  194. else
  195. x = (10 + tolower (s[i + 2]) - 'a') * 16;
  196. if (isdigit (s[i + 3]))
  197. x += s[i + 3] - '0';
  198. else
  199. x += tolower (s[i + 3]) + 10 - 'a';
  200. str[j++] = x;
  201. i += 3;
  202. }
  203. else if (s[i + 1] == '\\')
  204. {
  205. str[j++] = s[i];
  206. i++;
  207. }
  208. else
  209. i++;
  210. }
  211. else
  212. str[j++] = s[i];
  213. }
  214. current_len = j;
  215. }
  216. else
  217. {
  218. memcpy (str, s, sz);
  219. str[sz] = '\0';
  220. current_len = sz;
  221. }
  222. if (total_len + current_len > RAW_STR_LEN)
  223. {
  224. nasl_perror (lexic, "Error. Too long argument in raw_string()\n");
  225. break;
  226. }
  227. bcopy (str, retc->x.str_val + total_len, current_len);
  228. total_len += current_len;
  229. }
  230. }
  231. retc->size = total_len;
  232. return retc;
  233. }
  234. /*---------------------------------------------------------------------*/
  235. tree_cell *
  236. nasl_strlen (lex_ctxt * lexic)
  237. {
  238. int len = get_var_size_by_num (lexic, 0);
  239. tree_cell *retc;
  240. retc = alloc_tree_cell (0, NULL);
  241. retc->ref_count = 1;
  242. retc->type = CONST_INT;
  243. retc->x.i_val = len;
  244. return retc;
  245. }
  246. tree_cell *
  247. nasl_strcat (lex_ctxt * lexic)
  248. {
  249. tree_cell *retc;
  250. char *s;
  251. int vi, vn, newlen;
  252. int sz;
  253. retc = alloc_tree_cell (0, NULL);
  254. retc->type = CONST_DATA;
  255. retc->size = 0;
  256. retc->x.str_val = emalloc (0);
  257. vn = array_max_index (&lexic->ctx_vars);
  258. for (vi = 0; vi < vn; vi++)
  259. {
  260. s = get_str_var_by_num (lexic, vi);
  261. if (s == NULL)
  262. continue;
  263. sz = get_var_size_by_num (lexic, vi);
  264. if (sz <= 0)
  265. sz = strlen (s);
  266. newlen = retc->size + sz;
  267. retc->x.str_val = erealloc (retc->x.str_val, newlen + 1);
  268. memcpy (retc->x.str_val + retc->size, s, sz);
  269. retc->size = newlen;
  270. }
  271. retc->x.str_val[retc->size] = '\0';
  272. return retc;
  273. }
  274. /*---------------------------------------------------------------------*/
  275. tree_cell *
  276. nasl_display (lex_ctxt * lexic)
  277. {
  278. tree_cell *r, *retc;
  279. int j;
  280. r = nasl_string (lexic);
  281. for (j = 0; j < r->size; j++)
  282. putchar (isprint (r->x.str_val[j])
  283. || isspace (r->x.str_val[j]) ? r->x.str_val[j] : '.');
  284. retc = alloc_tree_cell (0, NULL);
  285. retc->type = CONST_INT;
  286. retc->x.i_val = r->size;
  287. deref_cell (r);
  288. return retc;
  289. }
  290. /*---------------------------------------------------------------------*/
  291. tree_cell *
  292. nasl_hex (lex_ctxt * lexic)
  293. {
  294. tree_cell *retc;
  295. int v = get_int_var_by_num (lexic, 0, -1);
  296. char ret[7];
  297. if (v == -1)
  298. return NULL;
  299. snprintf (ret, sizeof (ret), "0x%02x", (unsigned char) v); /* RATS: ignore */
  300. retc = alloc_tree_cell (0, NULL);
  301. retc->type = CONST_STR;
  302. retc->size = strlen (ret);
  303. retc->x.str_val = estrdup (ret);
  304. return retc;
  305. }
  306. /*---------------------------------------------------------------------*/
  307. tree_cell *
  308. nasl_hexstr (lex_ctxt * lexic)
  309. {
  310. tree_cell *retc;
  311. char *s = get_str_var_by_num (lexic, 0);
  312. int len = get_var_size_by_num (lexic, 0);
  313. char *ret;
  314. int i;
  315. if (s == NULL)
  316. return NULL;
  317. ret = emalloc (len * 2 + 1);
  318. for (i = 0; i < len; i++)
  319. {
  320. /* if i < len there are at least three chars left in ret + 2 * i */
  321. snprintf (ret + 2 * i, 3, "%02x", (unsigned char) s[i]); /* RATS: ignore */
  322. }
  323. retc = alloc_tree_cell (0, NULL);
  324. retc->type = CONST_STR;
  325. retc->size = strlen (ret);
  326. retc->x.str_val = ret;
  327. return retc;
  328. }
  329. /*---------------------------------------------------------------------*/
  330. tree_cell *
  331. nasl_ord (lex_ctxt * lexic)
  332. {
  333. tree_cell *retc;
  334. unsigned char *val = (unsigned char *) get_str_var_by_num (lexic, 0);
  335. if (val == NULL)
  336. {
  337. nasl_perror (lexic, "ord() usage : ord(char)\n");
  338. return NULL;
  339. }
  340. retc = alloc_tree_cell (0, NULL);
  341. retc->type = CONST_INT;
  342. retc->x.i_val = val[0];
  343. return retc;
  344. }
  345. /*---------------------------------------------------------------------*/
  346. tree_cell *
  347. nasl_tolower (lex_ctxt * lexic)
  348. {
  349. tree_cell *retc;
  350. char *str = get_str_var_by_num (lexic, 0);
  351. int str_len = get_var_size_by_num (lexic, 0);
  352. int i;
  353. if (str == NULL)
  354. return NULL;
  355. str = nasl_strndup (str, str_len);
  356. for (i = 0; i < str_len; i++)
  357. str[i] = tolower (str[i]);
  358. retc = alloc_tree_cell (0, NULL);
  359. retc->type = CONST_DATA;
  360. retc->size = str_len;
  361. retc->x.str_val = str;
  362. return retc;
  363. }
  364. /*---------------------------------------------------------------------*/
  365. tree_cell *
  366. nasl_toupper (lex_ctxt * lexic)
  367. {
  368. tree_cell *retc;
  369. char *str = get_str_var_by_num (lexic, 0);
  370. int str_len = get_var_size_by_num (lexic, 0);
  371. int i;
  372. if (str == NULL)
  373. return NULL;
  374. str = nasl_strndup (str, str_len);
  375. for (i = 0; i < str_len; i++)
  376. str[i] = toupper (str[i]);
  377. retc = alloc_tree_cell (0, NULL);
  378. retc->type = CONST_DATA;
  379. retc->size = str_len;
  380. retc->x.str_val = str;
  381. return retc;
  382. }
  383. /*---------------------------------------------------------------------*/
  384. /*
  385. * regex syntax :
  386. *
  387. * ereg(pattern, string)
  388. */
  389. tree_cell *
  390. nasl_ereg (lex_ctxt * lexic)
  391. {
  392. char *pattern = get_str_local_var_by_name (lexic, "pattern");
  393. char *string = get_str_local_var_by_name (lexic, "string");
  394. int icase = get_int_local_var_by_name (lexic, "icase", 0);
  395. int multiline = get_int_local_var_by_name (lexic, "multiline", 0);
  396. char *s;
  397. int copt = 0;
  398. tree_cell *retc;
  399. regex_t re;
  400. if (icase != 0)
  401. copt = REG_ICASE;
  402. if (pattern == NULL || string == NULL)
  403. return NULL;
  404. nasl_re_set_syntax (RE_SYNTAX_POSIX_EGREP);
  405. if (nasl_regcomp (&re, pattern, REG_EXTENDED | REG_NOSUB | copt))
  406. {
  407. nasl_perror (lexic, "ereg() : regcomp() failed\n");
  408. return NULL;
  409. }
  410. retc = alloc_tree_cell (0, NULL);
  411. retc->type = CONST_INT;
  412. string = estrdup (string);
  413. if (multiline)
  414. s = NULL;
  415. else
  416. s = strchr (string, '\n');
  417. if (s != NULL)
  418. s[0] = '\0';
  419. if (s != string)
  420. {
  421. if (nasl_regexec (&re, string, 0, NULL, 0) == 0)
  422. retc->x.i_val = 1;
  423. else
  424. retc->x.i_val = 0;
  425. }
  426. else
  427. retc->x.i_val = 0;
  428. efree (&string);
  429. nasl_regfree (&re);
  430. return retc;
  431. }
  432. /*---------------------------------------------------------------------*/
  433. #define NS 16
  434. /*
  435. * Copied from php3
  436. */
  437. /* this is the meat and potatoes of regex replacement! */
  438. static char *
  439. _regreplace (const char *pattern, const char *replace, const char *string,
  440. int icase, int extended)
  441. {
  442. regex_t re;
  443. regmatch_t subs[NS];
  444. char *buf, /* buf is where we build the replaced string */
  445. *nbuf, /* nbuf is used when we grow the buffer */
  446. *walkbuf; /* used to walk buf when replacing backrefs */
  447. const char *walk; /* used to walk replacement string for backrefs */
  448. int buf_len;
  449. int pos, tmp, string_len, new_l;
  450. int err, copts = 0;
  451. string_len = strlen (string);
  452. if (icase)
  453. copts = REG_ICASE;
  454. if (extended)
  455. copts |= REG_EXTENDED;
  456. err = nasl_regcomp (&re, pattern, copts);
  457. if (err)
  458. {
  459. return NULL;
  460. }
  461. /* start with a buffer that is twice the size of the stringo
  462. we're doing replacements in */
  463. buf_len = 2 * string_len + 1;
  464. buf = emalloc (buf_len * sizeof (char));
  465. err = pos = 0;
  466. buf[0] = '\0';
  467. while (!err)
  468. {
  469. err =
  470. nasl_regexec (&re, &string[pos], (size_t) NS, subs,
  471. (pos ? REG_NOTBOL : 0));
  472. if (err && err != REG_NOMATCH)
  473. {
  474. return (NULL);
  475. }
  476. if (!err)
  477. {
  478. /* backref replacement is done in two passes:
  479. 1) find out how long the string will be, and allocate buf
  480. 2) copy the part before match, replacement and backrefs to buf
  481. Jaakko Hyvätti <Jaakko.Hyvatti@iki.fi>
  482. */
  483. new_l = strlen (buf) + subs[0].rm_so; /* part before the match */
  484. walk = replace;
  485. while (*walk)
  486. if ('\\' == *walk && '0' <= walk[1] && '9' >= walk[1]
  487. && subs[walk[1] - '0'].rm_so > -1
  488. && subs[walk[1] - '0'].rm_eo > -1)
  489. {
  490. new_l += subs[walk[1] - '0'].rm_eo - subs[walk[1] - '0'].rm_so;
  491. walk += 2;
  492. }
  493. else
  494. {
  495. new_l++;
  496. walk++;
  497. }
  498. if (new_l + 1 > buf_len)
  499. {
  500. buf_len = 1 + buf_len + 2 * new_l;
  501. nbuf = emalloc (buf_len);
  502. strcpy (nbuf, buf);
  503. efree (&buf);
  504. buf = nbuf;
  505. }
  506. tmp = strlen (buf);
  507. /* copy the part of the string before the match */
  508. strncat (buf, &string[pos], subs[0].rm_so); /* RATS: ignore */
  509. /* copy replacement and backrefs */
  510. walkbuf = &buf[tmp + subs[0].rm_so];
  511. walk = replace;
  512. while (*walk)
  513. if ('\\' == *walk && '0' <= walk[1] && '9' >= walk[1]
  514. && subs[walk[1] - '0'].rm_so > -1
  515. && subs[walk[1] - '0'].rm_eo > -1)
  516. {
  517. tmp = subs[walk[1] - '0'].rm_eo - subs[walk[1] - '0'].rm_so;
  518. memcpy (walkbuf, &string[pos + subs[walk[1] - '0'].rm_so], tmp);
  519. walkbuf += tmp;
  520. walk += 2;
  521. }
  522. else
  523. *walkbuf++ = *walk++;
  524. *walkbuf = '\0';
  525. /* and get ready to keep looking for replacements */
  526. if (subs[0].rm_so == subs[0].rm_eo)
  527. {
  528. if (subs[0].rm_so + pos >= string_len)
  529. break;
  530. new_l = strlen (buf) + 1;
  531. if (new_l + 1 > buf_len)
  532. {
  533. buf_len = 1 + buf_len + 2 * new_l;
  534. nbuf = emalloc (buf_len * sizeof (char));
  535. strcpy (nbuf, buf);
  536. efree (&buf);
  537. buf = nbuf;
  538. }
  539. pos += subs[0].rm_eo + 1;
  540. buf[new_l - 1] = string[pos - 1];
  541. buf[new_l] = '\0';
  542. }
  543. else
  544. {
  545. pos += subs[0].rm_eo;
  546. }
  547. }
  548. else
  549. { /* REG_NOMATCH */
  550. new_l = strlen (buf) + strlen (&string[pos]);
  551. if (new_l + 1 > buf_len)
  552. {
  553. buf_len = new_l + 1; /* now we know exactly how long it is */
  554. nbuf = emalloc (buf_len * sizeof (char));
  555. strcpy (nbuf, buf);
  556. efree (&buf);
  557. buf = nbuf;
  558. }
  559. /* stick that last bit of string on our output */
  560. strcat (buf, &string[pos]);
  561. }
  562. }
  563. buf[new_l] = '\0';
  564. nasl_regfree (&re);
  565. /* whew. */
  566. return (buf);
  567. }
  568. tree_cell *
  569. nasl_ereg_replace (lex_ctxt * lexic)
  570. {
  571. char *pattern = get_str_local_var_by_name (lexic, "pattern");
  572. char *replace = get_str_local_var_by_name (lexic, "replace");
  573. char *string = get_str_local_var_by_name (lexic, "string");
  574. int icase = get_int_local_var_by_name (lexic, "icase", 0);
  575. char *r;
  576. tree_cell *retc;
  577. if (pattern == NULL || replace == NULL)
  578. {
  579. nasl_perror (lexic,
  580. "Usage : ereg_replace(string:<string>, pattern:<pat>, replace:<replace>, icase:<TRUE|FALSE>\n");
  581. return NULL;
  582. }
  583. if (string == NULL)
  584. {
  585. #if NASL_DEBUG > 1
  586. nasl_perror (lexic, "ereg_replace: string == NULL\n");
  587. #endif
  588. return NULL;
  589. }
  590. r = _regreplace (pattern, replace, string, icase, 1);
  591. if (r == NULL)
  592. return FAKE_CELL;
  593. retc = alloc_tree_cell (0, NULL);
  594. retc->type = CONST_DATA;
  595. retc->size = strlen (r);
  596. retc->x.str_val = r;
  597. return retc;
  598. }
  599. /*---------------------------------------------------------------------*/
  600. /*
  601. * regex syntax :
  602. *
  603. * egrep(pattern, string)
  604. */
  605. tree_cell *
  606. nasl_egrep (lex_ctxt * lexic)
  607. {
  608. char *pattern = get_str_local_var_by_name (lexic, "pattern");
  609. char *string = get_str_local_var_by_name (lexic, "string");
  610. int icase = get_int_local_var_by_name (lexic, "icase", 0);
  611. tree_cell *retc;
  612. regex_t re;
  613. regmatch_t subs[NS];
  614. char *s, *t;
  615. int copt;
  616. char *rets;
  617. int max_size = get_var_size_by_name (lexic, "string");
  618. if (pattern == NULL || string == NULL)
  619. return NULL;
  620. bzero (subs, sizeof (subs));
  621. bzero (&re, sizeof (re));
  622. if (icase != 0)
  623. copt = REG_ICASE;
  624. else
  625. copt = 0;
  626. rets = emalloc (max_size + 1);
  627. string = estrdup (string);
  628. s = string;
  629. while (s[0] == '\n')
  630. s++;
  631. t = strchr (s, '\n');
  632. if (t != NULL)
  633. t[0] = '\0';
  634. if (s[0] != '\0')
  635. for (;;)
  636. {
  637. bzero (&re, sizeof (re));
  638. nasl_re_set_syntax (RE_SYNTAX_POSIX_EGREP);
  639. if (nasl_regcomp (&re, pattern, REG_EXTENDED | copt))
  640. {
  641. nasl_perror (lexic, "egrep() : regcomp() failed\n");
  642. return NULL;
  643. }
  644. if (nasl_regexec (&re, s, (size_t) NS, subs, 0) == 0)
  645. {
  646. char *t = strchr (s, '\n');
  647. if (t != NULL)
  648. t[0] = '\0';
  649. strcat (rets, s);
  650. strcat (rets, "\n");
  651. if (t != NULL)
  652. t[0] = '\n';
  653. }
  654. nasl_regfree (&re);
  655. if (t == NULL)
  656. s = NULL;
  657. else
  658. s = &(t[1]);
  659. if (s != NULL)
  660. {
  661. while (s[0] == '\n')
  662. s++; /* Skip empty lines */
  663. t = strchr (s, '\n');
  664. }
  665. else
  666. t = NULL;
  667. if (t != NULL)
  668. t[0] = '\0';
  669. if (s == NULL || s[0] == '\0')
  670. break;
  671. }
  672. #ifdef I_WANT_MANY_DIRTY_ERROR_MESSAGES
  673. if (rets[0] == '\0')
  674. {
  675. efree (&rets);
  676. efree (&string);
  677. return FAKE_CELL;
  678. }
  679. #endif
  680. efree (&string);
  681. retc = alloc_tree_cell (0, NULL);
  682. retc->type = CONST_DATA;
  683. retc->size = strlen (rets);
  684. retc->x.str_val = rets;
  685. return retc;
  686. }
  687. /*---------------------------------------------------------------------*/
  688. /**
  689. * @brief Does extended regular expression pattern matching.
  690. *
  691. * In NASL, this function returns an array.
  692. */
  693. tree_cell *
  694. nasl_eregmatch (lex_ctxt * lexic)
  695. {
  696. char *pattern = get_str_local_var_by_name (lexic, "pattern");
  697. char *string = get_str_local_var_by_name (lexic, "string");
  698. int icase = get_int_local_var_by_name (lexic, "icase", 0);
  699. int copt = 0, i;
  700. tree_cell *retc;
  701. regex_t re;
  702. regmatch_t subs[NS];
  703. anon_nasl_var v;
  704. nasl_array *a;
  705. if (icase != 0)
  706. copt = REG_ICASE;
  707. if (pattern == NULL || string == NULL)
  708. return NULL;
  709. nasl_re_set_syntax (RE_SYNTAX_POSIX_EGREP);
  710. if (nasl_regcomp (&re, pattern, REG_EXTENDED | copt))
  711. {
  712. nasl_perror (lexic, "regmatch() : regcomp() failed\n");
  713. return NULL;
  714. }
  715. if (nasl_regexec (&re, string, (size_t) NS, subs, 0) != 0)
  716. {
  717. nasl_regfree (&re);
  718. return NULL;
  719. }
  720. retc = alloc_tree_cell (0, NULL);
  721. retc->type = DYN_ARRAY;
  722. retc->x.ref_val = a = emalloc (sizeof (nasl_array));
  723. for (i = 0; i < NS; i++)
  724. if (subs[i].rm_so != -1)
  725. {
  726. v.var_type = VAR2_DATA;
  727. v.v.v_str.s_siz = subs[i].rm_eo - subs[i].rm_so;
  728. v.v.v_str.s_val = (unsigned char *) string + subs[i].rm_so;
  729. (void) add_var_to_list (a, i, &v);
  730. }
  731. nasl_regfree (&re);
  732. return retc;
  733. }
  734. /**
  735. * Syntax: substr(s, i1) or substr(s, i1, i2)
  736. * Returns character from string s starting for position i1 till the end or
  737. * position i2 (start of string is 0)
  738. */
  739. tree_cell *
  740. nasl_substr (lex_ctxt * lexic)
  741. {
  742. char *s1;
  743. int sz1, sz2, i1, i2, typ;
  744. tree_cell *retc;
  745. s1 = get_str_var_by_num (lexic, 0);
  746. sz1 = get_var_size_by_num (lexic, 0);
  747. typ = get_var_type_by_num (lexic, 0);
  748. i1 = get_int_var_by_num (lexic, 1, -1);
  749. #ifndef MAX_INT
  750. #define MAX_INT (~(1 << (sizeof(int) * 8 - 1)))
  751. #endif
  752. i2 = get_int_var_by_num (lexic, 2, MAX_INT);
  753. if (i2 >= sz1)
  754. i2 = sz1 - 1;
  755. if (s1 == NULL || i1 < 0)
  756. {
  757. nasl_perror (lexic, "Usage: substr(string, idx_start [,idx_end])\n");
  758. return NULL;
  759. }
  760. retc = alloc_tree_cell (0, NULL);
  761. retc->type = (typ == CONST_STR ? CONST_STR : CONST_DATA);
  762. if (i1 > i2)
  763. {
  764. retc->x.str_val = emalloc (0);
  765. retc->size = 0;
  766. return retc;
  767. }
  768. sz2 = i2 - i1 + 1;
  769. retc->size = sz2;
  770. retc->x.str_val = emalloc (sz2);
  771. memcpy (retc->x.str_val, s1 + i1, sz2);
  772. return retc;
  773. }
  774. /*---------------------------------------------------------------------*/
  775. /**
  776. * Syntax: insstr(s1, s2, i1, i2) or insstr(s1, s2, i1)
  777. * Insert string s2 into slice [i1:i2] of string s1 and returns the result
  778. * Warning: returns a CONST_DATA!
  779. */
  780. tree_cell *
  781. nasl_insstr (lex_ctxt * lexic)
  782. {
  783. char *s1, *s2, *s3;
  784. int sz1, sz2, sz3, i1, i2;
  785. tree_cell *retc;
  786. s1 = get_str_var_by_num (lexic, 0);
  787. sz1 = get_var_size_by_num (lexic, 0);
  788. s2 = get_str_var_by_num (lexic, 1);
  789. sz2 = get_var_size_by_num (lexic, 1);
  790. i1 = get_int_var_by_num (lexic, 2, -1);
  791. i2 = get_int_var_by_num (lexic, 3, -1);
  792. if (i2 > sz1 || i2 == -1)
  793. i2 = sz1 - 1;
  794. if (s1 == NULL || s2 == NULL || i1 < 0 || i2 < 0)
  795. {
  796. nasl_perror (lexic, "Usage: insstr(str1, str2, idx_start [,idx_end])\n");
  797. return NULL;
  798. }
  799. if (i1 >= sz1)
  800. {
  801. nasl_perror (lexic,
  802. "insstr: cannot insert string2 after end of string1\n");
  803. return NULL;
  804. }
  805. retc = alloc_tree_cell (0, NULL);
  806. retc->type = CONST_DATA;
  807. if (i1 > i2)
  808. {
  809. nasl_perror (lexic,
  810. " insstr: warning! 1st index %d greater than 2nd index %d\n",
  811. i1, i2);
  812. sz3 = sz2;
  813. }
  814. else
  815. sz3 = sz1 + i1 - i2 - 1 + sz2;
  816. s3 = retc->x.str_val = emalloc (sz3);
  817. retc->size = sz3;
  818. if (i1 <= sz1)
  819. {
  820. memcpy (s3, s1, i1);
  821. s3 += i1;
  822. }
  823. memcpy (s3, s2, sz2);
  824. s3 += sz2;
  825. if (i2 < sz1 - 1)
  826. memcpy (s3, s1 + i2 + 1, sz1 - 1 - i2);
  827. return retc;
  828. }
  829. tree_cell *
  830. nasl_match (lex_ctxt * lexic)
  831. {
  832. char *pattern = get_str_local_var_by_name (lexic, "pattern");
  833. char *string = get_str_local_var_by_name (lexic, "string");
  834. int icase = get_int_local_var_by_name (lexic, "icase", 0);
  835. tree_cell *retc;
  836. if (pattern == NULL)
  837. {
  838. nasl_perror (lexic, "nasl_match: parameter 'pattern' missing\n");
  839. return NULL;
  840. }
  841. if (string == NULL)
  842. {
  843. nasl_perror (lexic, "nasl_match: parameter 'string' missing\n");
  844. return NULL;
  845. }
  846. retc = alloc_tree_cell (0, NULL);
  847. retc->type = CONST_INT;
  848. retc->x.i_val = str_match (string, pattern, icase);
  849. return retc;
  850. }
  851. tree_cell *
  852. nasl_split (lex_ctxt * lexic)
  853. {
  854. tree_cell *retc;
  855. nasl_array *a;
  856. char *p, *str, *sep;
  857. int i, i0, j, len, sep_len = 0, keep = 1;
  858. anon_nasl_var v;
  859. str = get_str_var_by_num (lexic, 0);
  860. if (str == NULL)
  861. {
  862. #if NASL_DEBUG > 0
  863. nasl_perror (lexic, "split: missing string parameter\n");
  864. #endif
  865. return NULL;
  866. }
  867. len = get_var_size_by_num (lexic, 0);
  868. if (len <= 0)
  869. len = strlen (str);
  870. if (len <= 0)
  871. return NULL;
  872. sep = get_str_local_var_by_name (lexic, "sep");
  873. if (sep != NULL)
  874. {
  875. sep_len = get_var_size_by_name (lexic, "sep");
  876. if (sep_len <= 0)
  877. sep_len = strlen (sep);
  878. if (sep_len <= 0)
  879. {
  880. nasl_perror (lexic, "split: invalid 'seplen' parameter\n");
  881. return NULL;
  882. }
  883. }
  884. keep = get_int_local_var_by_name (lexic, "keep", 1);
  885. retc = alloc_tree_cell (0, NULL);
  886. retc->type = DYN_ARRAY;
  887. retc->x.ref_val = a = emalloc (sizeof (nasl_array));
  888. bzero (&v, sizeof (v));
  889. v.var_type = VAR2_DATA;
  890. if (sep != NULL)
  891. {
  892. i = 0;
  893. j = 0;
  894. for (;;)
  895. {
  896. if ((p =
  897. (char *) nasl_memmem (str + i, len - i, sep, sep_len)) == NULL)
  898. {
  899. v.v.v_str.s_siz = len - i;
  900. v.v.v_str.s_val = (unsigned char *) str + i;
  901. (void) add_var_to_list (a, j++, &v);
  902. return retc;
  903. }
  904. else
  905. {
  906. if (keep)
  907. v.v.v_str.s_siz = (p - (str + i)) + sep_len;
  908. else
  909. v.v.v_str.s_siz = p - (str + i);
  910. v.v.v_str.s_val = (unsigned char *) str + i;
  911. (void) add_var_to_list (a, j++, &v);
  912. i = (p - str) + sep_len;
  913. if (i >= len)
  914. return retc;
  915. }
  916. }
  917. }
  918. /* Otherwise, we detect the end of line. A little more subtle. */
  919. for (i = i0 = j = 0; i < len; i++)
  920. {
  921. if (str[i] == '\r' && str[i + 1] == '\n')
  922. {
  923. i++;
  924. if (keep)
  925. v.v.v_str.s_siz = i - i0 + 1;
  926. else
  927. v.v.v_str.s_siz = i - i0 - 1;
  928. v.v.v_str.s_val = (unsigned char *) str + i0;
  929. i0 = i + 1;
  930. (void) add_var_to_list (a, j++, &v);
  931. }
  932. else if (str[i] == '\n')
  933. {
  934. if (keep)
  935. v.v.v_str.s_siz = i - i0 + 1;
  936. else
  937. v.v.v_str.s_siz = i - i0;
  938. v.v.v_str.s_val = (unsigned char *) str + i0;
  939. i0 = i + 1;
  940. (void) add_var_to_list (a, j++, &v);
  941. }
  942. }
  943. if (i > i0)
  944. {
  945. v.v.v_str.s_siz = i - i0;
  946. v.v.v_str.s_val = (unsigned char *) str + i0;
  947. (void) add_var_to_list (a, j++, &v);
  948. }
  949. return retc;
  950. }
  951. tree_cell *
  952. nasl_chomp (lex_ctxt * lexic)
  953. {
  954. tree_cell *retc;
  955. char *p = NULL, *str;
  956. int i, len;
  957. str = get_str_var_by_num (lexic, 0);
  958. if (str == NULL)
  959. return NULL;
  960. len = get_var_size_by_num (lexic, 0);
  961. retc = alloc_tree_cell (0, NULL);
  962. retc->type = CONST_DATA;
  963. for (i = 0; i < len; i++)
  964. /** @todo evaluate early break */
  965. if (isspace (str[i]))
  966. {
  967. if (p == NULL)
  968. p = str + i;
  969. }
  970. else
  971. p = NULL;
  972. if (p != NULL)
  973. len = (p - str);
  974. retc->x.str_val = emalloc (len);
  975. retc->size = len;
  976. memcpy (retc->x.str_val, str, len);
  977. retc->x.str_val[len] = '\0';
  978. return retc;
  979. }
  980. /*---------------------------------------------------------------------*/
  981. tree_cell *
  982. nasl_crap (lex_ctxt * lexic)
  983. {
  984. tree_cell *retc;
  985. char *data = get_str_local_var_by_name (lexic, "data");
  986. int data_len = -1;
  987. int len = get_int_local_var_by_name (lexic, "length", -1);
  988. int len2 = get_int_var_by_num (lexic, 0, -1);
  989. if (len < 0 && len2 < 0)
  990. {
  991. nasl_perror (lexic, "crap: invalid or missing 'length' argument\n");
  992. return NULL;
  993. }
  994. if (len >= 0 && len2 >= 0)
  995. {
  996. nasl_perror (lexic, "crap: cannot set both unnamed and named 'length'\n");
  997. return NULL;
  998. }
  999. if (len < 0)
  1000. len = len2;
  1001. if (len == 0)
  1002. return FAKE_CELL;
  1003. if (data != NULL)
  1004. {
  1005. data_len = get_var_size_by_name (lexic, "data");
  1006. if (data_len == 0)
  1007. {
  1008. nasl_perror (lexic, "crap: invalid null 'data' parameter\n");
  1009. return NULL;
  1010. }
  1011. }
  1012. retc = alloc_tree_cell (0, NULL);
  1013. retc->type = CONST_DATA /*CONST_STR */ ;
  1014. retc->x.str_val = emalloc (len + 1);
  1015. retc->size = len;
  1016. if (data == NULL)
  1017. memset (retc->x.str_val, 'X', len);
  1018. else
  1019. {
  1020. int i, r;
  1021. for (i = 0; i < len - data_len; i += data_len)
  1022. memcpy (retc->x.str_val + i, data, data_len);
  1023. if (data_len != 1)
  1024. {
  1025. if ((r = (len % data_len)) > 0)
  1026. memcpy (retc->x.str_val + (len - r), data, r);
  1027. else
  1028. memcpy (retc->x.str_val + (len - data_len), data, data_len);
  1029. }
  1030. else
  1031. retc->x.str_val[len - 1] = data[0];
  1032. }
  1033. retc->x.str_val[len] = '\0';
  1034. return retc;
  1035. }
  1036. /*---------------------------------------------------------------------*/
  1037. tree_cell *
  1038. nasl_strstr (lex_ctxt * lexic)
  1039. {
  1040. char *a = get_str_var_by_num (lexic, 0);
  1041. char *b = get_str_var_by_num (lexic, 1);
  1042. int sz_a = get_var_size_by_num (lexic, 0);
  1043. int sz_b = get_var_size_by_num (lexic, 1);
  1044. char *c;
  1045. tree_cell *retc;
  1046. if (a == NULL || b == NULL)
  1047. return NULL;
  1048. if (sz_b > sz_a)
  1049. return NULL;
  1050. c = (char *) nasl_memmem (a, sz_a, b, sz_b);
  1051. if (c == NULL)
  1052. return FAKE_CELL;
  1053. retc = alloc_tree_cell (0, NULL);
  1054. retc->type = CONST_DATA;
  1055. retc->size = sz_a - (c - a);
  1056. retc->x.str_val = nasl_strndup (c, retc->size);
  1057. return retc;
  1058. }
  1059. /**
  1060. * @brief Returns index of a substring.
  1061. *
  1062. * Returning NULL for "not found" is dangerous as automatic conversion to
  1063. * to integer would change it into 0.
  1064. * So we return (-1).
  1065. *
  1066. * @return -1 if string not found, otherwise index of substring.
  1067. *
  1068. * @see strstr
  1069. */
  1070. tree_cell *
  1071. nasl_stridx (lex_ctxt * lexic)
  1072. {
  1073. char *a = get_str_var_by_num (lexic, 0);
  1074. int sz_a = get_var_size_by_num (lexic, 0);
  1075. char *b = get_str_var_by_num (lexic, 1);
  1076. int sz_b = get_var_size_by_num (lexic, 1);
  1077. char *c;
  1078. int start = get_int_var_by_num (lexic, 2, 0);
  1079. tree_cell *retc = alloc_typed_cell (CONST_INT);
  1080. retc->x.i_val = -1;
  1081. if (a == NULL || b == NULL)
  1082. {
  1083. nasl_perror (lexic, "stridx(string, substring [, start])\n");
  1084. return retc;
  1085. }
  1086. if (start < 0 || start > sz_a)
  1087. {
  1088. nasl_perror (lexic, "stridx(string, substring [, start])\n");
  1089. return retc;
  1090. }
  1091. if ((sz_a == start) || (sz_b > sz_a + start))
  1092. return retc;
  1093. c = (char *) nasl_memmem (a + start, sz_a - start, b, sz_b);
  1094. if (c != NULL)
  1095. retc->x.i_val = c - a;
  1096. return retc;
  1097. }
  1098. /**
  1099. * str_replace(string: s, find: f, replace: r [,count: n])
  1100. */
  1101. tree_cell *
  1102. nasl_str_replace (lex_ctxt * lexic)
  1103. {
  1104. char *a, *b, *r, *s, *c;
  1105. int sz_a, sz_b, sz_r, count;
  1106. int i1, i2, sz2, n, l;
  1107. tree_cell *retc = NULL;
  1108. a = get_str_local_var_by_name (lexic, "string");
  1109. b = get_str_local_var_by_name (lexic, "find");
  1110. r = get_str_local_var_by_name (lexic, "replace");
  1111. sz_a = get_local_var_size_by_name (lexic, "string");
  1112. sz_b = get_local_var_size_by_name (lexic, "find");
  1113. sz_r = get_local_var_size_by_name (lexic, "replace");
  1114. count = get_int_local_var_by_name (lexic, "count", 0);
  1115. if (a == NULL || b == NULL)
  1116. {
  1117. nasl_perror (lexic,
  1118. "Missing argument: str_replace(string: s, find: f, replace: r [,count: c])\n");
  1119. return NULL;
  1120. }
  1121. if (sz_b == 0)
  1122. {
  1123. nasl_perror (lexic, "str_replace: illegal 'find' argument value\n");
  1124. return NULL;
  1125. }
  1126. if (r == NULL)
  1127. {
  1128. r = "";
  1129. sz_r = 0;
  1130. }
  1131. retc = alloc_typed_cell (CONST_DATA);
  1132. s = emalloc (1);
  1133. sz2 = 0;
  1134. n = 0;
  1135. for (i1 = i2 = 0; i1 <= sz_a - sz_b;)
  1136. {
  1137. c = (char *) nasl_memmem (a + i1, sz_a - i1, b, sz_b);
  1138. if (c == NULL)
  1139. break;
  1140. l = (c - a) - i1;
  1141. sz2 += sz_r + l;
  1142. s = erealloc (s, sz2 + 1);
  1143. s[sz2] = '\0';
  1144. if (c - a > i1)
  1145. {
  1146. memcpy (s + i2, a + i1, l);
  1147. i2 += l;
  1148. }
  1149. if (sz_r > 0)
  1150. {
  1151. memcpy (s + i2, r, sz_r);
  1152. i2 += sz_r;
  1153. }
  1154. i1 += l + sz_b;
  1155. n++;
  1156. if (count > 0 && n >= count)
  1157. break;
  1158. }
  1159. if (i1 < sz_a)
  1160. {
  1161. sz2 += (sz_a - i1);
  1162. s = erealloc (s, sz2 + 1);
  1163. s[sz2] = '\0';
  1164. memcpy (s + i2, a + i1, sz_a - i1);
  1165. }
  1166. retc->x.str_val = s;
  1167. retc->size = sz2;
  1168. return retc;
  1169. }
  1170. /*---------------------------------------------------------------------*/
  1171. tree_cell *
  1172. nasl_int (lex_ctxt * lexic)
  1173. {
  1174. int r = get_int_var_by_num (lexic, 0, 0);
  1175. tree_cell *retc;
  1176. retc = alloc_tree_cell (0, NULL);
  1177. retc->type = CONST_INT;
  1178. retc->x.i_val = r;
  1179. return retc;
  1180. }
  1181. /*EOF*/