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 + -
显示快捷键?