nse_pcrelib.cc

来自「Ubuntu packages of security software。 相」· CC 代码 · 共 380 行

CC
380
字号
/* lrexlib.c - PCRE regular expression library *//* Reuben Thomas   nov00-18dec04 *//* Shmuel Zeigerman   may04-18dec04 */#include <stdio.h>#include <stdlib.h>#include <string.h>extern "C" {#include "lua.h"#include "lauxlib.h"}#include <locale.h>#include "nbase.h"#include "nmap_error.h"#ifdef HAVE_PCRE_PCRE_H# include <pcre/pcre.h>#else# include <pcre.h>#endif#include "nse_pcrelib.h"static void L_lua_error(lua_State *L, const char *message){	int status;	lua_pushstring(L, message);	status = lua_error(L);}static int get_startoffset(lua_State *L, int stackpos, size_t len){	int startoffset = luaL_optint(L, stackpos, 1);	if(startoffset > 0)		startoffset--;	else if(startoffset < 0) {		startoffset += (int) len;		if(startoffset < 0)			startoffset = 0;	}	return startoffset;}static int udata_tostring (lua_State *L, const char* type_handle,		const char* type_name){	char buf[256];	void *udata = luaL_checkudata(L, 1, type_handle);	if(udata) {		(void)Snprintf(buf, 255, "%s (%p)", type_name, udata);		lua_pushstring(L, buf);	}	else {		(void)Snprintf(buf, 255, "must be userdata of type '%s'", type_name);		(void)luaL_argerror(L, 1, buf);	}	free(udata);	return 1;}typedef struct { const char* key; lua_Number val; } flags_pair;static int get_flags (lua_State *L, const flags_pair *arr){	const flags_pair *p;	lua_newtable(L);	for(p=arr; p->key != NULL; p++) {		lua_pushstring(L, p->key);		lua_pushnumber(L, p->val);		lua_rawset(L, -3);	}	return 1;}static void createmeta(lua_State *L, const char *name){	(void)luaL_newmetatable(L, name);   /* create new metatable */	lua_pushliteral(L, "__index");	lua_pushvalue(L, -2);         /* push metatable */	lua_rawset(L, -3);            /* metatable.__index = metatable */}const char pcre_handle[] = "pcre_regex_handle";const char pcre_typename[] = "pcre_regex";typedef struct {	pcre *pr;	pcre_extra *extra;	int *match;	int ncapt;	const unsigned char *tables;} pcre2;      /* a better name is needed */static const unsigned char *Lpcre_maketables(lua_State *L, int stackpos){	const unsigned char *tables;	char old_locale[256];	char *locale = strdup(luaL_checkstring(L, stackpos));	if(locale == NULL)		L_lua_error(L, "cannot set locale");	strncpy(old_locale, setlocale(LC_CTYPE, NULL), 255); /* store the locale */	if(setlocale(LC_CTYPE, locale) == NULL)        /* set new locale */		L_lua_error(L, "cannot set locale");	tables = pcre_maketables();              /* make tables with new locale */	(void)setlocale(LC_CTYPE, old_locale);         /* restore the old locale */	free(locale);	return tables;}static int Lpcre_comp(lua_State *L){	char buf[256];	const char *error;	int erroffset;	pcre2 *ud;	char *pattern = strdup(luaL_checkstring(L, 1));	int cflags = luaL_optint(L, 2, 0);	const unsigned char *tables = NULL;	if(lua_gettop(L) > 2 && !lua_isnil(L, 3))		tables = Lpcre_maketables(L, 3);	if(tables == NULL)		L_lua_error(L, "PCRE compilation failed");	ud = (pcre2*)lua_newuserdata(L, sizeof(pcre2));	luaL_getmetatable(L, pcre_handle);	(void)lua_setmetatable(L, -2);	ud->match = NULL;	ud->extra = NULL;	ud->tables = tables; /* keep this for eventual freeing */	ud->pr = pcre_compile(pattern, cflags, &error, &erroffset, tables);	if(!ud->pr) {		(void)Snprintf(buf, 255, "%s (pattern offset: %d)", error, erroffset+1);		/* show offset 1-based as it's common in Lua */		L_lua_error(L, buf);	}	ud->extra = pcre_study(ud->pr, 0, &error);	if(error) L_lua_error(L, error);	pcre_fullinfo(ud->pr, ud->extra, PCRE_INFO_CAPTURECOUNT, &ud->ncapt);	/* need (2 ints per capture, plus one for substring match) * 3/2 */	ud->match = (int *) safe_malloc((ud->ncapt + 1) * 3 * sizeof(int));	return 1;}static void Lpcre_getargs(lua_State *L, pcre2 **pud, const char **text,		size_t *text_len){	*pud = (pcre2 *)luaL_checkudata(L, 1, pcre_handle);	if(*pud == NULL)		(void)luaL_argerror(L, 1, ("compiled regexp expected"));	*text = luaL_checklstring(L, 2, text_len);}typedef void (*Lpcre_push_matches) (lua_State *L, const char *text, pcre2 *ud);static void Lpcre_push_substrings (lua_State *L, const char *text, pcre2 *ud){	unsigned int i, j;	unsigned int namecount;	unsigned char *name_table;	int name_entry_size;	unsigned char *tabptr;	const int *match = ud->match;	lua_newtable(L);	for (i = 1; i <= (unsigned) ud->ncapt; i++) {		j = i * 2;		if (match[j] >= 0)			lua_pushlstring(L, text + match[j], (size_t)(match[j + 1] - match[j]));		else			lua_pushboolean(L, 0);		lua_rawseti(L, -2, i);	}	/* now do named subpatterns - NJG */	(void)pcre_fullinfo(ud->pr, ud->extra, PCRE_INFO_NAMECOUNT, &namecount);	if (namecount <= 0)		return;	(void)pcre_fullinfo(ud->pr, ud->extra, PCRE_INFO_NAMETABLE, &name_table);	(void)pcre_fullinfo(ud->pr, ud->extra, PCRE_INFO_NAMEENTRYSIZE, &name_entry_size);	tabptr = name_table;	for (i = 0; i < namecount; i++) {		unsigned int n = (tabptr[0] << 8) | tabptr[1]; /* number of the capturing parenthesis */		if (n > 0 && n <= (unsigned) ud->ncapt) {   /* check range */			unsigned int j = n * 2;			lua_pushstring(L, strdup((char*)tabptr + 2)); /* name of the capture, zero terminated */			if (match[j] >= 0)				lua_pushlstring(L, text + match[j], match[j + 1] - match[j]);			else				lua_pushboolean(L, 0);			lua_rawset(L, -3);		}		tabptr += name_entry_size;	}}static void Lpcre_push_offsets (lua_State *L, const char *text, pcre2 * ud){	unsigned int i, j, k;	if(text) {		/* suppress compiler warning */	}	lua_newtable(L);	for (i=1, j=1; i <= (unsigned) ud->ncapt; i++) {		k = i * 2;		if (ud->match[k] >= 0) {			lua_pushnumber(L, ud->match[k] + 1);			lua_rawseti(L, -2, j++);			lua_pushnumber(L, ud->match[k+1]);			lua_rawseti(L, -2, j++);		}		else {			lua_pushboolean(L, 0);			lua_rawseti(L, -2, j++);			lua_pushboolean(L, 0);			lua_rawseti(L, -2, j++);		}	}}static int Lpcre_match_generic(lua_State *L, Lpcre_push_matches push_matches){	int res;	const char *text;	pcre2 *ud;	size_t elen;	int startoffset;	int eflags = luaL_optint(L, 4, 0);	Lpcre_getargs(L, &ud, &text, &elen);	startoffset = get_startoffset(L, 3, elen);	res = pcre_exec(ud->pr, ud->extra, text, (int)elen, startoffset, eflags,			ud->match, (ud->ncapt + 1) * 3);	if (res >= 0) {		lua_pushnumber(L, (lua_Number) ud->match[0] + 1);		lua_pushnumber(L, (lua_Number) ud->match[1]);		(*push_matches)(L, text, ud);		return 3;	}	return 0;}static int Lpcre_match(lua_State *L){	return Lpcre_match_generic(L, Lpcre_push_substrings);}static int Lpcre_exec(lua_State *L){	return Lpcre_match_generic(L, Lpcre_push_offsets);}static int Lpcre_gmatch(lua_State *L){	int res;	size_t len;	int nmatch = 0, limit = 0;	const char *text;	pcre2 *ud;	int maxmatch = luaL_optint(L, 4, 0);	int eflags = luaL_optint(L, 5, 0);	int startoffset = 0;	Lpcre_getargs(L, &ud, &text, &len);	luaL_checktype(L, 3, LUA_TFUNCTION);	if(maxmatch > 0) /* this must be stated in the docs */		limit = 1;	while (!limit || nmatch < maxmatch) {		res = pcre_exec(ud->pr, ud->extra, text, (int)len, startoffset, eflags,				ud->match, (ud->ncapt + 1) * 3);		if (res >= 0) {			nmatch++;			lua_pushvalue(L, 3);			lua_pushlstring(L, text + ud->match[0], ud->match[1] - ud->match[0]);			Lpcre_push_substrings(L, text, ud);			lua_call(L, 2, 1);			if(lua_toboolean(L, -1))				break;			lua_pop(L, 1);			startoffset = ud->match[1];		} else			break;	}	lua_pushnumber(L, nmatch);	return 1;}static int Lpcre_gc (lua_State *L){	pcre2 *ud = (pcre2 *)luaL_checkudata(L, 1, pcre_handle);	if (ud) {		if(ud->pr)      pcre_free(ud->pr);		if(ud->extra)   pcre_free(ud->extra);		if(ud->tables)  pcre_free((void *)ud->tables);		if(ud->match)   free(ud->match);	}	return 0;}static int Lpcre_tostring (lua_State *L) {	return udata_tostring(L, pcre_handle, pcre_typename);}static int Lpcre_vers (lua_State *L){	lua_pushstring(L, pcre_version());	return 1;}static flags_pair pcre_flags[] ={	{ "CASELESS",        PCRE_CASELESS },	{ "MULTILINE",       PCRE_MULTILINE },	{ "DOTALL",          PCRE_DOTALL },	{ "EXTENDED",        PCRE_EXTENDED },	{ "ANCHORED",        PCRE_ANCHORED },	{ "DOLLAR_ENDONLY",  PCRE_DOLLAR_ENDONLY },	{ "EXTRA",           PCRE_EXTRA },	{ "NOTBOL",          PCRE_NOTBOL },	{ "NOTEOL",          PCRE_NOTEOL },	{ "UNGREEDY",        PCRE_UNGREEDY },	{ "NOTEMPTY",        PCRE_NOTEMPTY },	{ "UTF8",            PCRE_UTF8 },#if PCRE_MAJOR >= 4	{ "NO_AUTO_CAPTURE", PCRE_NO_AUTO_CAPTURE },	{ "NO_UTF8_CHECK",   PCRE_NO_UTF8_CHECK },#endif	{ NULL, 0 }};static int Lpcre_get_flags (lua_State *L) {	return get_flags(L, pcre_flags);}static const luaL_reg pcremeta[] = {	{"exec",       Lpcre_exec},	{"match",      Lpcre_match},	{"gmatch",     Lpcre_gmatch},	{"__gc",       Lpcre_gc},	{"__tostring", Lpcre_tostring},	{NULL, NULL}};/* Open the library */static const luaL_reg pcrelib[] = {	{"new",	Lpcre_comp},	{"flags", Lpcre_get_flags},	{"version", Lpcre_vers},	{NULL, NULL}};LUALIB_API int luaopen_pcrelib(lua_State *L){	createmeta(L, pcre_handle);	luaL_openlib(L, NULL, pcremeta, 0);	lua_pop(L, 1);	luaL_openlib(L, NSE_PCRELIBNAME, pcrelib, 0);		return 1;}

⌨️ 快捷键说明

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