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