nasl_text_utils.c

来自「大国补丁后的nessus2.2.8的源代码」· C语言 代码 · 共 1,313 行 · 第 1/2 页

C
1,313
字号
/* 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. * */  /* This file implements all the functions that are related to  * text-related utilities in the NASL functions.  */  #include <includes.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 "strutils.h"#include "nasl_regex.h"#include "nasl_debug.h"#include "nasl_text_utils.h"tree_cell* nasl_string(lex_ctxt* lexic){  tree_cell	*retc;  int		vi, vn, newlen;  int		sz, typ;  const char	*s, *p1;  char		*p2;  retc = alloc_tree_cell(0, NULL);  retc->type = CONST_DATA;  retc->size = 0;  retc->x.str_val = emalloc(0);  vn = array_max_index(&lexic->ctx_vars);  for (vi = 0; vi < vn; vi ++)    {      if ((typ = get_var_type_by_num(lexic, vi)) == VAR2_UNDEF)	continue;      s = get_str_var_by_num(lexic, vi);      sz = get_var_size_by_num(lexic, vi);      if (sz <= 0)	sz = strlen(s);      newlen = retc->size + sz;      retc->x.str_val = erealloc(retc->x.str_val, newlen + 1);      p2 = retc->x.str_val + retc->size;      p1 = s;      retc->size = newlen;      if (typ != VAR2_STRING)	{	  memcpy(p2, p1, sz);	  p2[sz] = '\0';	}      else	while (*p1 != '\0')	  {	    if(*p1 == '\\' && p1[1] != '\0')	      {		switch (p1[1])		  {		  case 'n':		    *p2 ++ = '\n';		    break;		  case 't':		    *p2 ++ = '\t';		    break;		  case 'r':		    *p2++ = '\r';		    break;		  case '\\':		    *p2++ = '\\';		    break;		  case 'x':		    if (isxdigit(p1[2]) && isxdigit(p1[3]))		      {			*p2++ = 			  16 *			  (isdigit(p1[2]) ? p1[2]-'0' : 10+tolower(p1[2])-'a')			  +			  (isdigit(p1[3]) ? p1[3]-'0' : 10+tolower(p1[3])-'a');			p1 += 2;			retc->size -= 2;		      }		    else		      {			nasl_perror(lexic, "Buggy hex value '\\x%c%c' skipped\n",				isprint(p1[2]) ? p1[2] : '.',				isprint(p1[3]) ? p1[3] : '.' );			/* We do not increment p1 by  4,			   we may miss the end of the string */		      }		    break;		  default:		    	nasl_perror(lexic, "Unknown%d escape sequence '\\%c'\n", getpid(),			    isprint(p1[1]) ? p1[1] : '.' );		    retc->size --;		    break;		  }		p1 += 2;		retc->size --;	      }	    else	      *p2++ = *p1++;	  }    }  retc->x.str_val[retc->size] = '\0';  return retc;}/*---------------------------------------------------------------------*/#define RAW_STR_LEN	32768 tree_cell* nasl_rawstring(lex_ctxt* lexic){  tree_cell	*retc;  int		vi, vn, i, j, x;  int		sz, typ;  const char	*s;   int		total_len = 0;  retc = alloc_tree_cell(0, NULL);  retc->type = CONST_DATA;  retc->size = 0;  retc->x.str_val = emalloc(RAW_STR_LEN);  vn = array_max_index(&lexic->ctx_vars);  for (vi = 0; vi < vn && total_len < RAW_STR_LEN-1; vi ++)    {      if ((typ = get_var_type_by_num(lexic, vi)) == VAR2_UNDEF)	continue;      sz = get_var_size_by_num(lexic, vi);      if (typ == VAR2_INT)	{	  x = get_int_var_by_num(lexic, vi, 0);	  retc->x.str_val[total_len ++] = x;	}      else	{	  int		current_len = sz;	  char		str[RAW_STR_LEN];	  	  s = get_str_var_by_num(lexic, vi);	  if (sz <= 0)	    sz = strlen(s);	  if (sz >= RAW_STR_LEN) 	    {	      nasl_perror(lexic, "Error. Too long argument in raw_string()\n");	      break;	    }	  /* Should we test if the variable is composed only of digits? */	  if(typ == VAR2_STRING)	    {	      /* TBD:I should decide at last if we keep those "purified" 	       * string or not, and if we do, if "CONST_STR" & "VAR2_STR" are	       * "not pure" strings */	      for(i=0, j=0; i < sz; i++)		{		  if(s[i]=='\\')		    {		      if (s[i+1] == 'n')			{			  str[j++]='\n';			  i++;			}		      else if (s[i+1] == 't')			{			  str[j++]='\t';			  i++;			}		      else if (s[i+1] == 'r')			{ 			  str[j++] = '\r';			  i++;			}		      else if (s[i+1] == 'x' && 			       isxdigit(s[i+2]) && isxdigit(s[i+3]))			{			  x = 0;			  if(isdigit(s[i+2]))			    x = (s[i+2]-'0')*16;			  else			    x=(10+tolower(s[i+2])-'a')*16;			  if(isdigit(s[i+3]))			    x += s[i+3]-'0';			  else			    x += tolower(s[i+3])+10-'a';			  str[j++]=x;			  i+=3;			}		      else if(s[i+1] == '\\')			{			  str[j++] = s[i];			  i++;			}		      else			i++;		    }		  else		    str[j++] = s[i];		}	      current_len = j;	    }	  else	    {	      memcpy(str, s, sz);	      str[sz] = '\0';	      current_len = sz;	    }		  if(total_len + current_len > RAW_STR_LEN)	    {	      nasl_perror(lexic, "Error. Too long argument in raw_string()\n");	      break;	    }	  bcopy(str, retc->x.str_val + total_len, current_len);	  total_len += current_len;	}    } retc->size = total_len; return retc;}/*---------------------------------------------------------------------*/tree_cell* nasl_strlen(lex_ctxt* lexic){ int		len = get_var_size_by_num(lexic, 0); tree_cell * retc;  retc = alloc_tree_cell(0, NULL); retc->ref_count = 1; retc->type = CONST_INT; retc->x.i_val = len; return retc;}tree_cell*nasl_strcat(lex_ctxt* lexic){  tree_cell	*retc;  char		*s;  int		vi, vn, newlen;  int		sz;  retc = alloc_tree_cell(0, NULL);  retc->type = CONST_DATA;  retc->size = 0;  retc->x.str_val = emalloc(0);  vn = array_max_index(&lexic->ctx_vars);  for (vi = 0; vi < vn; vi ++)    {      s = get_str_var_by_num(lexic, vi);      if (s == NULL)	continue;      sz = get_var_size_by_num(lexic, vi);      if (sz <= 0)	sz = strlen(s);      newlen = retc->size + sz;      retc->x.str_val = erealloc(retc->x.str_val, newlen + 1);      memcpy(retc->x.str_val + retc->size, s, sz);      retc->size = newlen;    }  retc->x.str_val[retc->size] = '\0';  return retc;}/*---------------------------------------------------------------------*/tree_cell* nasl_display(lex_ctxt* lexic){  tree_cell	*r, *retc;  int		j;  r = nasl_string(lexic);    for (j = 0; j < r->size; j ++)    putchar(isprint(r->x.str_val[j]) || isspace(r->x.str_val[j]) ?	    r->x.str_val[j] : '.');  retc = alloc_tree_cell(0, NULL);  retc->type = CONST_INT;  retc->x.i_val = r->size;  deref_cell(r);  return retc;}/*---------------------------------------------------------------------*/tree_cell* nasl_hex(lex_ctxt * lexic){ tree_cell * retc; int v = get_int_var_by_num(lexic, 0, -1); char ret[7];   if(v == -1)   return NULL;   snprintf(ret, sizeof(ret), "0x%02x", (unsigned char)v);  retc = alloc_tree_cell(0, NULL);  retc->type = CONST_STR;  retc->size = strlen(ret);  retc->x.str_val = estrdup(ret);    return retc;}/*---------------------------------------------------------------------*/tree_cell* nasl_hexstr(lex_ctxt * lexic){ tree_cell * retc; char *s = get_str_var_by_num(lexic, 0); int len = get_var_size_by_num(lexic, 0); char * ret; int i;   if(s == NULL)   return NULL;     ret = emalloc(len * 2 + 1);  for(i=0;i<len;i++)  {   char tmp[3];   snprintf(tmp, sizeof(tmp), "%02x", (unsigned char)s[i]);   strcat(ret, tmp);  }     retc = alloc_tree_cell(0, NULL);  retc->type = CONST_STR;  retc->size = strlen(ret);  retc->x.str_val = ret;    return retc;}/*---------------------------------------------------------------------*/tree_cell* nasl_ord(lex_ctxt* lexic){  tree_cell	*retc;  unsigned char	*val = (unsigned char*)get_str_var_by_num(lexic, 0);   if (val == NULL)    {      nasl_perror(lexic, "ord() usage : ord(char)\n");      return NULL;    }  retc = alloc_tree_cell(0, NULL);  retc->type = CONST_INT;  retc->x.i_val = val[0];  return retc;}/*---------------------------------------------------------------------*/tree_cell * nasl_tolower(lex_ctxt * lexic){ tree_cell * retc; char * str = get_str_var_by_num(lexic, 0); int str_len = get_var_size_by_num(lexic, 0); int i;  if(str == NULL)  return NULL;   str = nasl_strndup(str, str_len); for(i=0;i<str_len;i++) 	str[i] = tolower(str[i]);	 retc = alloc_tree_cell(0, NULL); retc->type = CONST_DATA; retc->size = str_len; retc->x.str_val = str; return retc;}/*---------------------------------------------------------------------*/tree_cell * nasl_toupper(lex_ctxt * lexic){ tree_cell * retc; char * str = get_str_var_by_num(lexic, 0); int str_len = get_var_size_by_num(lexic, 0); int i;  if(str == NULL)  return NULL;   str = nasl_strndup(str, str_len); for(i=0;i<str_len;i++) 	str[i] = toupper(str[i]);	 retc = alloc_tree_cell(0, NULL); retc->type = CONST_DATA; retc->size = str_len; retc->x.str_val = str; return retc;}/*---------------------------------------------------------------------*//* * regex syntax : * *	ereg(pattern, string) */tree_cell* nasl_ereg(lex_ctxt* lexic){ char * pattern = get_str_local_var_by_name(lexic, "pattern"); char * string = get_str_local_var_by_name(lexic, "string"); int	icase       = get_int_local_var_by_name(lexic, "icase", 0); int	multiline = get_int_local_var_by_name(lexic, "multiline", 0); char * s; int copt = 0; tree_cell * retc; regex_t re;  if(icase != 0) 	copt = REG_ICASE;  if(pattern == NULL || string == NULL) 	return NULL; nasl_re_set_syntax(RE_SYNTAX_POSIX_EGREP); if(nasl_regcomp(&re, pattern, REG_EXTENDED|REG_NOSUB|copt))  {   nasl_perror(lexic, "ereg() : regcomp() failed\n");   return NULL;  }    retc = alloc_tree_cell(0, NULL);  retc->type = CONST_INT;  string = estrdup(string);  if (multiline)    s = NULL;  else    s = strchr(string, '\n');  if ( s != NULL ) s[0] = '\0';  if (s != string )  {  if(nasl_regexec(&re, string, 0, NULL, 0) == 0)    retc->x.i_val = 1;  else    retc->x.i_val = 0;  } else retc->x.i_val = 0;  efree(&string); nasl_regfree(&re); return retc;}/*---------------------------------------------------------------------*/#define NS	16/* * Copied from php3 */ /* this is the meat and potatoes of regex replacement! */static char * _regreplace(const char *pattern, 		const char *replace, const char *string, int icase, int extended){	regex_t re;	regmatch_t subs[NS];	char *buf,	/* buf is where we build the replaced string */	     *nbuf,	/* nbuf is used when we grow the buffer */		 *walkbuf; /* used to walk buf when replacing backrefs */	const char *walk; /* used to walk replacement string for backrefs */	int buf_len;	int pos, tmp, string_len, new_l;	int err, copts = 0;	string_len = strlen(string);	if (icase)		copts = REG_ICASE;	if (extended)		copts |= REG_EXTENDED;	err = nasl_regcomp(&re, pattern, copts);	if (err) {		return NULL;	}	/* start with a buffer that is twice the size of the stringo	   we're doing replacements in */	buf_len = 2 * string_len + 1;	buf = emalloc(buf_len * sizeof(char));		err = pos = 0;	buf[0] = '\0';	while (!err) {		err = nasl_regexec(&re, &string[pos], (size_t) NS, subs, (pos ? REG_NOTBOL : 0));		if (err && err != REG_NOMATCH) {			return(NULL);		}		if (!err) {			/* backref replacement is done in two passes:			   1) find out how long the string will be, and allocate buf			   2) copy the part before match, replacement and backrefs to buf			   Jaakko Hyv鋞ti <Jaakko.Hyvatti@iki.fi>			   */			new_l = strlen(buf) + subs[0].rm_so; /* part before the match */			walk = replace;			while (*walk)				if ('\\' == *walk					&& '0' <= walk[1] && '9' >= walk[1]					&& subs[walk[1] - '0'].rm_so > -1					&& subs[walk[1] - '0'].rm_eo > -1) {					new_l += subs[walk[1] - '0'].rm_eo						- subs[walk[1] - '0'].rm_so;					walk += 2;				} else {					new_l++;					walk++;				}			if (new_l + 1 > buf_len) {				buf_len = 1 + buf_len + 2 * new_l;				nbuf = emalloc(buf_len);				strcpy(nbuf, buf);				efree(&buf);				buf = nbuf;			}			tmp = strlen(buf);			/* copy the part of the string before the match */			strncat(buf, &string[pos], subs[0].rm_so);			/* copy replacement and backrefs */			walkbuf = &buf[tmp + subs[0].rm_so];			walk = replace;			while (*walk)				if ('\\' == *walk					&& '0' <= walk[1] && '9' >= walk[1]					&& subs[walk[1] - '0'].rm_so > -1					&& subs[walk[1] - '0'].rm_eo > -1) {					tmp = subs[walk[1] - '0'].rm_eo						- subs[walk[1] - '0'].rm_so;					memcpy (walkbuf,							&string[pos + subs[walk[1] - '0'].rm_so],							tmp);					walkbuf += tmp;					walk += 2;				} else					*walkbuf++ = *walk++;			*walkbuf = '\0';			/* and get ready to keep looking for replacements */			if (subs[0].rm_so == subs[0].rm_eo) {				if (subs[0].rm_so + pos >= string_len)					break;				new_l = strlen (buf) + 1;				if (new_l + 1 > buf_len) {					buf_len = 1 + buf_len + 2 * new_l;					nbuf = emalloc(buf_len * sizeof(char));					strcpy(nbuf, buf);					efree(&buf);					buf = nbuf;				}				pos += subs[0].rm_eo + 1;				buf [new_l-1] = string [pos-1];				buf [new_l] = '\0';			} else {				pos += subs[0].rm_eo;			}		} else { /* REG_NOMATCH */			new_l = strlen(buf) + strlen(&string[pos]);			if (new_l + 1 > buf_len) {				buf_len = new_l + 1; /* now we know exactly how long it is */				nbuf = emalloc(buf_len * sizeof(char));				strcpy(nbuf, buf);				efree(&buf);				buf = nbuf;			}			/* stick that last bit of string on our output */			strcat(buf, &string[pos]);					}	}	buf [new_l] = '\0';  	nasl_regfree(&re);	/* whew. */	return (buf);}tree_cell* nasl_ereg_replace(lex_ctxt* lexic){ char * pattern = get_str_local_var_by_name(lexic, "pattern"); char * replace = get_str_local_var_by_name(lexic, "replace"); char * string  = get_str_local_var_by_name(lexic, "string"); int    icase   = get_int_local_var_by_name(lexic, "icase", 0); char * r;  tree_cell * retc;  if(pattern == NULL || replace == NULL) {  nasl_perror(lexic, "Usage : ereg_replace(string:<string>, pattern:<pat>, replace:<replace>, icase:<TRUE|FALSE>\n");  return NULL; } if (string == NULL)  {#if NASL_DEBUG > 1   nasl_perror(lexic, "ereg_replace: string == NULL\n");#endif    return NULL;  } r = _regreplace(pattern, replace, string, icase, 1); if ( r == NULL )	return FAKE_CELL;  retc = alloc_tree_cell(0, NULL); retc->type = CONST_DATA; retc->size = strlen(r); retc->x.str_val =  r; return retc;}/*---------------------------------------------------------------------*//* * regex syntax :

⌨️ 快捷键说明

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