nasl_tree.c

来自「大国补丁后的nessus2.2.8的源代码」· C语言 代码 · 共 489 行

C
489
字号
/* Nessus Attack Scripting Language  * * Copyright (C) 2002 - 2004 Tenable Network Security * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2, * as published by the Free Software Foundation * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * */#include <includes.h>#include "nasl_regex.h"#include "nasl_tree.h"#include "nasl_global_ctxt.h"#include "nasl_func.h"#include "nasl_var.h"#include "nasl_lex_ctxt.h"#include "exec.h"#include "nasl_debug.h"tree_cell*alloc_tree_cell(int lnb, char * s){  tree_cell	*p = malloc(sizeof(tree_cell));  int		i;  if (p == NULL)    {      perror("malloc");      abort();    }  p->type = 0;  p->size = 0;  p->line_nb = lnb;  p->x.str_val = s;  p->ref_count = 1;  for (i = 0; i < 4;i ++)    p->link[i] = NULL;  return p;}tree_cell*alloc_typed_cell(int typ){  tree_cell	*c = alloc_tree_cell(0, NULL);  c->type = typ;  return c;}  tree_cell*alloc_RE_cell(int lnb, int t, tree_cell *l, char *re_str){  regex_t	*re = emalloc(sizeof(regex_t));  int	e;  tree_cell *c = alloc_tree_cell(lnb, NULL);  c->type = t;			/* We could check the type... */  c->link[0] = l;  c->link[1] = FAKE_CELL;  e = nasl_regcomp(re, re_str, REG_EXTENDED|REG_NOSUB|REG_ICASE);  if (! e)    c->x.ref_val = re;  else    {      nasl_perror(NULL, "Line %d: Cannot compile regex: %s (error = %d)\n",		  lnb, re_str, e);      efree(&re);    }  free(re_str);  return c;}tree_cell*alloc_expr_cell(int lnb, int t, tree_cell *l, tree_cell *r){  tree_cell *c = alloc_tree_cell(lnb, NULL);  c->type = t;  c->link[0] = l;  c->link[1] = r;  return c;}tree_cell*dup_cell(const tree_cell* tc){  tree_cell	*r;  int		i;  if (tc == NULL)    return NULL;  else if (tc == FAKE_CELL)    return FAKE_CELL;  r  = alloc_tree_cell(tc->line_nb, NULL);  r->type = tc->type;  r->size = tc->size;  switch (tc->type)    {    case CONST_STR:    case CONST_DATA:      r->x.str_val = emalloc(tc->size);      memcpy(r->x.str_val, tc->x.str_val, tc->size);      break;    default:      r->x = tc->x;      break;    }  for (i = 0; i < 4; i ++)    r->link[i] = dup_cell(tc->link[i]);  return r;}static voidfree_tree(tree_cell *c){  int			i;  nasl_array		*a;  if (c == NULL || c == FAKE_CELL)    return;#if 0  nasl_dump_tree(c);#endif  for (i = 0; i < 4; i ++)    if (c->link[i] != NULL)      deref_cell(c->link[i]);  if (c->x.str_val != NULL)    switch(c->type)      {      case CONST_STR:      case CONST_DATA:#ifdef SCRATCH_FREED_MEMORY	if (c->size > 0)	  memset(c->x.str_val, 0xFF, c->size);#endif	efree(&c->x.str_val);	break;      case CONST_REGEX:      case COMP_RE_MATCH:      case COMP_RE_NOMATCH:	if (c->x.ref_val != NULL)	  {	    nasl_regfree(c->x.ref_val);	    efree(&c->x.ref_val);	  }	break;      case DYN_ARRAY:	a = c->x.ref_val;	if (a != NULL)	  {	    free_array(a);	    efree(&c->x.ref_val);	  }	break;      case NODE_FUN_DEF:      case NODE_FUN_CALL:      case NODE_VAR:      case NODE_DECL:      case NODE_ARG:      case NODE_ARRAY_EL:      case NODE_FOREACH:	efree(&c->x.str_val);	break;      }#ifdef SCRATCH_FREED_MEMORY  memset(c, 0xFF, sizeof(*c));#endif  efree(&c);}voidref_cell(tree_cell* c){  if (c == NULL || c == FAKE_CELL)    return;  c->ref_count ++;  if (c->ref_count < 0)    {      nasl_perror(NULL, "ref_cell: ref count is negative!\n");      nasl_dump_tree(c);      abort();    }}voidderef_cell(tree_cell* c){  if (c == NULL || c == FAKE_CELL)    return;  if (-- c->ref_count <= 0)    free_tree(c);}/* Debug */static char * node_names[] = {   "NODE_EMPTY",  "NODE_IF_ELSE",  "NODE_INSTR_L",  "NODE_FOR",  "NODE_WHILE",  "NODE_FOREACH",  "NODE_REPEAT_UNTIL",  "NODE_REPEATED",  "NODE_FUN_DEF",  "NODE_FUN_CALL",  "NODE_DECL",  "NODE_ARG",  "NODE_RETURN",  "NODE_BREAK",  "NODE_CONTINUE",  "NODE_ARRAY_EL",  "NODE_AFF",  "NODE_VAR",  "NODE_LOCAL",  "NODE_GLOBAL",  "NODE_PLUS_EQ",  "NODE_MINUS_EQ",  "NODE_MULT_EQ",  "NODE_DIV_EQ",  "NODE_MODULO_EQ",  "NODE_L_SHIFT_EQ",  "NODE_R_SHIFT_EQ",  "NODE_R_USHIFT_EQ",  "EXPR_AND",  "EXPR_OR",  "EXPR_NOT",  "EXPR_PLUS",  "EXPR_MINUS",  "EXPR_U_MINUS",  "EXPR_MULT",  "EXPR_DIV",  "EXPR_MODULO",  "EXPR_EXPO",  "EXPR_BIT_AND",  "EXPR_BIT_OR",  "EXPR_BIT_XOR",  "EXPR_BIT_NOT",  "EXPR_INCR",  "EXPR_DECR",  "EXPR_L_SHIFT",  "EXPR_R_SHIFT",  "EXPR_R_USHIFT",  "COMP_MATCH",  "COMP_NOMATCH",  "COMP_RE_MATCH",  "COMP_RE_NOMATCH",  "COMP_LT",  "COMP_LE",  "COMP_EQ",  "COMP_NE",  "COMP_GT",  "COMP_GE",  "CONST_INT",  "CONST_STR",  "CONST_DATA",  "CONST_REGEX",  "ARRAY_ELEM",  "REF_VAR",  "REF_ARRAY",  "DYN_ARRAY"};static voidprefix(int n, int i){  int	j;  for (j = 0; j < n; j ++)    putchar(' ');  if (i <= 0)    fputs("   ", stdout);  else    printf("%d: ", i);}char*dump_cell_val(const tree_cell* c){  static char	txt[80];  if (c == NULL)    return "NULL";  else if (c == FAKE_CELL)     return "FAKE";  else    switch(c->type)      {      case CONST_INT:	snprintf(txt, sizeof(txt), "%d", c->x.i_val);	break;      case CONST_STR:      case CONST_DATA:		/* Beurk */	if (c->size >= sizeof(txt) + 2)	  {	    snprintf(txt, sizeof(txt), "\"%s", c->x.str_val);	    strcpy(txt + (sizeof(txt) - 5), "...\"");	  }	else	  snprintf(txt, sizeof(txt), "\"%s\"", c->x.str_val);	break;      default:	snprintf(txt, sizeof(txt), "???? (%s)", nasl_type_name(c->type));	break;      }  return txt;}static voiddump_tree(const tree_cell* c, int n, int idx){  int	i;  if (c == NULL)    return;  prefix(n, idx);  if (c == FAKE_CELL)    {      puts("* FAKE *");      return;    }  if (c->line_nb > 0)    printf("L%d: ", c->line_nb);#if 0  if ((int) c < 0x1000)    {      printf("* INVALID PTR 0x%x *\n", (int) c);      return;    }#endif  if (c->type < 0 || c->type >= sizeof(node_names) / sizeof(node_names[0]))    printf("* UNKNOWN %d (0x%x)*\n", c->type, c->type);  else    printf("%s (%d)\n", node_names[c->type],c->type);  prefix(n, idx);  printf("Ref_count=%d", c->ref_count);  if (c->size > 0)    {      /*prefix(n, idx);*/      printf("\tSize=%d (0x%x)", c->size, c->size);    }  putchar('\n');  switch(c->type)    {    case CONST_INT:      prefix(n, 0);      printf("Val=%d\n", c->x.i_val);      break;    case CONST_STR:    case CONST_DATA:    case NODE_VAR:    case NODE_FUN_DEF:    case NODE_FUN_CALL:    case NODE_DECL:    case NODE_ARG:    case NODE_ARRAY_EL:    case ARRAY_ELEM:      prefix(n, 0);      if (c->x.str_val == NULL)	printf("Val=(null)\n");      else	printf("Val=\"%s\"\n", c->x.str_val);      break;    case REF_VAR:      prefix(n, 0);      if (c->x.ref_val == NULL)	printf("Ref=(null)\n");      else	{	  named_nasl_var	*v = c->x.ref_val;	  printf("Ref=(type=%d, name=%s, value=%s)\n",		 v->u.var_type, v->var_name != NULL ? v->var_name : "(null)",		 var2str(&v->u));	}      break;    case REF_ARRAY:    case DYN_ARRAY:      break;    }  for (i = 0; i < 4; i ++)    {      dump_tree(c->link[i], n+3, i+1);    }}const char*nasl_type_name(int t){  static char	txt4[4][32];	/*  This function may be called 4 times in the same expression */  static int	i = 0;  char	*txt;  if (++ i > 4) i = 0;  txt = txt4[i];  if (t >= 0 || t < sizeof(node_names) / sizeof(node_names[0]))    snprintf(txt, 32, "%s (%d)", node_names[t], t);  else    snprintf(txt, 32, "*UNKNOWN* (%d)", t);  return txt;} voidnasl_dump_tree(const tree_cell* c){  printf("^^^^ %08x ^^^^^\n", (int) c);  if (c == NULL)    puts("NULL CELL");  else if (c == FAKE_CELL)    puts ("FAKE CELL");  else    dump_tree(c, 0, 0);  printf("vvvvvvvvvvvvvvvvvv\n");}char*get_line_nb(const tree_cell* c){  static char txt[32];  if (c == NULL || c == FAKE_CELL || c->line_nb <= 0)    return "";  snprintf(txt, sizeof(txt), " at or near line %d ", c->line_nb);  return txt;}intnasl_is_leaf(const tree_cell* pc){  if (pc == NULL || pc == FAKE_CELL)    return 1;  switch(pc->type)    {    case CONST_INT:    case CONST_STR:    case CONST_DATA:    case REF_ARRAY:    case DYN_ARRAY:      return 1;    default:      return 0;    }  /*NOTREACHED*/}intcell_type(const tree_cell* c){  if (c == NULL || c== FAKE_CELL)    return 0;  else    return c->type;}

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?