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