OpenVAS Libraries  9.0.3
nasl_tree.c
Go to the documentation of this file.
1 /* Nessus Attack Scripting Language
2  *
3  * Copyright (C) 2002 - 2004 Tenable Network Security
4  *
5  * This program is free software; you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License version 2,
7  * as published by the Free Software Foundation
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software
16  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
17  *
18  */
19 
20 #include <stdlib.h> /* for abort */
21 #include <string.h> /* for memcpy */
22 
23 #include <glib.h> /* for g_free */
24 
25 #include <regex.h>
26 
27 #include "nasl_tree.h"
28 #include "nasl_global_ctxt.h"
29 #include "nasl_func.h"
30 #include "nasl_var.h"
31 #include "nasl_lex_ctxt.h"
32 #include "exec.h"
33 
34 #include "nasl_debug.h"
35 
36 tree_cell *
37 alloc_tree_cell (int lnb, char *s)
38 {
39  tree_cell *p = g_malloc0 (sizeof (tree_cell));
40  int i;
41 
42  p->type = 0;
43  p->size = 0;
44  p->line_nb = lnb;
45  p->x.str_val = s;
46  p->ref_count = 1;
47  for (i = 0; i < 4; i++)
48  p->link[i] = NULL;
49  return p;
50 }
51 
52 tree_cell *
54 {
55  tree_cell *c = alloc_tree_cell (0, NULL);
56  c->type = typ;
57  return c;
58 }
59 
60 tree_cell *
61 alloc_RE_cell (int lnb, int t, tree_cell * l, char *re_str)
62 {
63  regex_t *re = g_malloc0 (sizeof (regex_t));
64  int e;
65 
66  tree_cell *c = alloc_tree_cell (lnb, NULL);
67  c->type = t; /* We could check the type... */
68  c->link[0] = l;
69  c->link[1] = FAKE_CELL;
70  e = regcomp (re, re_str, REG_EXTENDED | REG_NOSUB | REG_ICASE);
71  if (!e)
72  c->x.ref_val = re;
73  else
74  {
75  char errbuf[100];
76  regerror (e, re, errbuf, sizeof (errbuf));
77  nasl_perror (NULL, "Line %d: Cannot compile regex: %s (error %d: %s)\n",
78  lnb, re_str, e, errbuf);
79  g_free (re);
80  }
81  g_free (re_str);
82  return c;
83 }
84 
85 tree_cell *
86 alloc_expr_cell (int lnb, int t, tree_cell * l, tree_cell * r)
87 {
88  tree_cell *c = alloc_tree_cell (lnb, NULL);
89  c->type = t;
90  c->link[0] = l;
91  c->link[1] = r;
92  return c;
93 }
94 
95 tree_cell *
96 dup_cell (const tree_cell * tc)
97 {
98  tree_cell *r;
99  int i;
100 
101  if (tc == NULL)
102  return NULL;
103  else if (tc == FAKE_CELL)
104  return FAKE_CELL;
105 
106  r = alloc_tree_cell (tc->line_nb, NULL);
107  r->type = tc->type;
108  r->size = tc->size;
109  switch (tc->type)
110  {
111  case CONST_STR:
112  case CONST_DATA:
113  r->x.str_val = g_malloc0 (tc->size + 1);
114  memcpy (r->x.str_val, tc->x.str_val, tc->size);
115  break;
116  default:
117  r->x = tc->x;
118  break;
119  }
120 
121  for (i = 0; i < 4; i++)
122  r->link[i] = dup_cell (tc->link[i]);
123  return r;
124 }
125 
126 static void
127 free_tree (tree_cell * c)
128 {
129  int i;
130  nasl_array *a;
131 
132  if (c == NULL || c == FAKE_CELL)
133  return;
134 #if 0
135  nasl_dump_tree (c);
136 #endif
137  for (i = 0; i < 4; i++)
138  if (c->link[i] != NULL)
139  deref_cell (c->link[i]);
140  if (c->x.str_val != NULL)
141  switch (c->type)
142  {
143  case CONST_STR:
144  case CONST_DATA:
145 #ifdef SCRATCH_FREED_MEMORY
146  if (c->size > 0)
147  memset (c->x.str_val, 0xFF, c->size);
148 #endif
149  g_free (c->x.str_val);
150  break;
151 
152  case CONST_REGEX:
153  case COMP_RE_MATCH:
154  case COMP_RE_NOMATCH:
155  if (c->x.ref_val != NULL)
156  {
157  regfree (c->x.ref_val);
158  g_free (c->x.ref_val);
159  }
160  break;
161 
162  case DYN_ARRAY:
163  a = c->x.ref_val;
164  if (a != NULL)
165  {
166  free_array (a);
167  g_free (c->x.ref_val);
168  }
169  break;
170 
171  case NODE_FUN_DEF:
172  case NODE_FUN_CALL:
173  case NODE_VAR:
174  case NODE_DECL:
175  case NODE_ARG:
176  case NODE_ARRAY_EL:
177  case NODE_FOREACH:
178  g_free (c->x.str_val);
179  break;
180  }
181 #ifdef SCRATCH_FREED_MEMORY
182  memset (c, 0xFF, sizeof (*c));
183 #endif
184  g_free (c);
185 }
186 
187 void
189 {
190  if (c == NULL || c == FAKE_CELL)
191  return;
192  c->ref_count++;
193  if (c->ref_count < 0)
194  {
195  nasl_perror (NULL, "ref_cell: ref count is negative!\n");
196  nasl_dump_tree (c);
197  abort ();
198  }
199 }
200 
201 void
203 {
204  if (c == NULL || c == FAKE_CELL)
205  return;
206  if (--c->ref_count <= 0)
207  free_tree (c);
208 }
209 
210 /* Debug */
211 
212 static char *node_names[] = {
213  "NODE_EMPTY",
214  "NODE_IF_ELSE",
215  "NODE_INSTR_L",
216  "NODE_FOR",
217  "NODE_WHILE",
218  "NODE_FOREACH",
219  "NODE_REPEAT_UNTIL",
220  "NODE_REPEATED",
221  "NODE_FUN_DEF",
222  "NODE_FUN_CALL",
223  "NODE_DECL",
224  "NODE_ARG",
225  "NODE_RETURN",
226  "NODE_BREAK",
227  "NODE_CONTINUE",
228 
229  "NODE_ARRAY_EL",
230  "NODE_AFF",
231  "NODE_VAR",
232  "NODE_LOCAL",
233  "NODE_GLOBAL",
234  "NODE_PLUS_EQ",
235  "NODE_MINUS_EQ",
236  "NODE_MULT_EQ",
237  "NODE_DIV_EQ",
238  "NODE_MODULO_EQ",
239 
240  "NODE_L_SHIFT_EQ",
241  "NODE_R_SHIFT_EQ",
242  "NODE_R_USHIFT_EQ",
243  "EXPR_AND",
244  "EXPR_OR",
245  "EXPR_NOT",
246 
247  "EXPR_PLUS",
248  "EXPR_MINUS",
249  "EXPR_U_MINUS",
250  "EXPR_MULT",
251  "EXPR_DIV",
252  "EXPR_MODULO",
253  "EXPR_EXPO",
254 
255  "EXPR_BIT_AND",
256  "EXPR_BIT_OR",
257  "EXPR_BIT_XOR",
258  "EXPR_BIT_NOT",
259  "EXPR_INCR",
260  "EXPR_DECR",
261  "EXPR_L_SHIFT",
262  "EXPR_R_SHIFT",
263  "EXPR_R_USHIFT",
264 
265  "COMP_MATCH",
266  "COMP_NOMATCH",
267  "COMP_RE_MATCH",
268  "COMP_RE_NOMATCH",
269 
270  "COMP_LT",
271  "COMP_LE",
272  "COMP_EQ",
273  "COMP_NE",
274  "COMP_GT",
275  "COMP_GE",
276  "CONST_INT",
277  "CONST_STR",
278  "CONST_DATA",
279  "CONST_REGEX",
280 
281  "ARRAY_ELEM",
282 
283  "REF_VAR",
284  "REF_ARRAY",
285  "DYN_ARRAY"
286 };
287 
288 static void
289 prefix (int n, int i)
290 {
291  int j;
292  for (j = 0; j < n; j++)
293  putchar (' ');
294  if (i <= 0)
295  fputs (" ", stdout);
296  else
297  printf ("%d: ", i);
298 }
299 
300 char *
302 {
303  static char txt[80];
304 
305  if (c == NULL)
306  return "NULL";
307  else if (c == FAKE_CELL)
308  return "FAKE";
309  else
310  switch (c->type)
311  {
312  case CONST_INT:
313  snprintf (txt, sizeof (txt), "%ld", c->x.i_val);
314  break;
315  case CONST_STR:
316  case CONST_DATA: /* Beurk (English: Yuck) */
317  if (c->size >= sizeof (txt) + 2)
318  {
319  snprintf (txt, sizeof (txt), "\"%s", c->x.str_val);
320  strcpy (txt + (sizeof (txt) - 5), "...\"");
321  }
322  else
323  snprintf (txt, sizeof (txt), "\"%s\"", c->x.str_val);
324  break;
325  default:
326  snprintf (txt, sizeof (txt), "???? (%s)", nasl_type_name (c->type));
327  break;
328  }
329  return txt;
330 }
331 
332 static void
333 dump_tree (const tree_cell * c, int n, int idx)
334 {
335  int i;
336 
337  if (c == NULL)
338  return;
339 
340  prefix (n, idx);
341 
342  if (c == FAKE_CELL)
343  {
344  puts ("* FAKE *");
345  return;
346  }
347 
348  if (c->line_nb > 0)
349  printf ("L%d: ", c->line_nb);
350 
351 #if 0
352  if ((int) c < 0x1000)
353  {
354  printf ("* INVALID PTR 0x%x *\n", (int) c);
355  return;
356  }
357 #endif
358  if (c->type < 0 || c->type >= sizeof (node_names) / sizeof (node_names[0]))
359  printf ("* UNKNOWN %d (0x%x)*\n", c->type, c->type);
360  else
361  printf ("%s (%d)\n", node_names[c->type], c->type);
362 
363 
364  prefix (n, idx);
365  printf ("Ref_count=%d", c->ref_count);
366  if (c->size > 0)
367  {
368  /*prefix(n, idx); */
369  printf ("\tSize=%d (0x%x)", c->size, c->size);
370  }
371  putchar ('\n');
372 
373  switch (c->type)
374  {
375  case CONST_INT:
376  prefix (n, 0);
377  printf ("Val=%ld\n", c->x.i_val);
378  break;
379 
380  case CONST_STR:
381  case CONST_DATA:
382  case NODE_VAR:
383  case NODE_FUN_DEF:
384  case NODE_FUN_CALL:
385  case NODE_DECL:
386  case NODE_ARG:
387  case NODE_ARRAY_EL:
388  case ARRAY_ELEM:
389  prefix (n, 0);
390  if (c->x.str_val == NULL)
391  printf ("Val=(null)\n");
392  else
393  printf ("Val=\"%s\"\n", c->x.str_val);
394  break;
395  case REF_VAR:
396  prefix (n, 0);
397  if (c->x.ref_val == NULL)
398  printf ("Ref=(null)\n");
399  else
400  {
401  named_nasl_var *v = c->x.ref_val;
402  printf ("Ref=(type=%d, name=%s, value=%s)\n", v->u.var_type,
403  v->var_name != NULL ? v->var_name : "(null)",
404  var2str (&v->u));
405  }
406  break;
407 
408  case REF_ARRAY:
409  case DYN_ARRAY:
410  break;
411  }
412 
413  for (i = 0; i < 4; i++)
414  {
415  dump_tree (c->link[i], n + 3, i + 1);
416  }
417 }
418 
419 const char *
421 {
422  static char txt4[4][32]; /* This function may be called 4 times in the same expression */
423  static int i = 0;
424  char *txt;
425 
426  if (++i > 4)
427  i = 0;
428  txt = txt4[i];
429 
430  if (t >= 0 && t < sizeof (node_names) / sizeof (node_names[0]))
431  snprintf (txt, 32, "%s (%d)", node_names[t], t);
432  else
433  snprintf (txt, 32, "*UNKNOWN* (%d)", t);
434  return txt;
435 }
436 
437 
438 void
440 {
441  printf ("^^^^ %p ^^^^^\n", c);
442  if (c == NULL)
443  puts ("NULL CELL");
444  else if (c == FAKE_CELL)
445  puts ("FAKE CELL");
446  else
447  dump_tree (c, 0, 0);
448  printf ("vvvvvvvvvvvvvvvvvv\n");
449 }
450 
451 char *
453 {
454  static char txt[32];
455  if (c == NULL || c == FAKE_CELL || c->line_nb <= 0)
456  return "";
457  snprintf (txt, sizeof (txt), " at or near line %d ", c->line_nb);
458  return txt;
459 }
460 
461 
462 int
464 {
465  if (pc == NULL || pc == FAKE_CELL)
466  return 1;
467  switch (pc->type)
468  {
469  case CONST_INT:
470  case CONST_STR:
471  case CONST_DATA:
472  case REF_ARRAY:
473  case DYN_ARRAY:
474  return 1;
475  default:
476  return 0;
477  }
478  /*NOTREACHED*/}
479 
480 int
481 cell_type (const tree_cell * c)
482 {
483  if (c == NULL || c == FAKE_CELL)
484  return 0;
485  else
486  return c->type;
487 }
#define FAKE_CELL
Definition: nasl_tree.h:120
struct TC * link[4]
Definition: nasl_tree.h:117
void ref_cell(tree_cell *c)
Definition: nasl_tree.c:188
char * var_name
Definition: nasl_var.h:70
short type
Definition: nasl_tree.h:107
char * str_val
Definition: nasl_tree.h:113
void nasl_dump_tree(const tree_cell *c)
Definition: nasl_tree.c:439
short ref_count
Definition: nasl_tree.h:109
struct st_a_nasl_var u
Definition: nasl_var.h:68
void deref_cell(tree_cell *c)
Definition: nasl_tree.c:202
short line_nb
Definition: nasl_tree.h:108
void * ref_val
Definition: nasl_tree.h:115
union TC::@7 x
tree_cell * alloc_typed_cell(int typ)
Definition: nasl_tree.c:53
int var_type
Definition: nasl_var.h:54
tree_cell * alloc_RE_cell(int lnb, int t, tree_cell *l, char *re_str)
Definition: nasl_tree.c:61
int nasl_is_leaf(const tree_cell *pc)
Definition: nasl_tree.c:463
Definition: nasl_tree.h:105
char * dump_cell_val(const tree_cell *c)
Definition: nasl_tree.c:301
void nasl_perror(lex_ctxt *lexic, char *msg,...)
Definition: nasl_debug.c:94
tree_cell * dup_cell(const tree_cell *tc)
Definition: nasl_tree.c:96
long int i_val
Definition: nasl_tree.h:114
tree_cell * alloc_tree_cell(int lnb, char *s)
Definition: nasl_tree.c:37
const char * var2str(const anon_nasl_var *v)
Definition: nasl_var.c:1189
const char * nasl_type_name(int t)
Definition: nasl_tree.c:420
int cell_type(const tree_cell *c)
Definition: nasl_tree.c:481
void free_array(nasl_array *a)
Definition: nasl_var.c:366
char * get_line_nb(const tree_cell *c)
Definition: nasl_tree.c:452
tree_cell * alloc_expr_cell(int lnb, int t, tree_cell *l, tree_cell *r)
Definition: nasl_tree.c:86
int size
Definition: nasl_tree.h:110