From 899dea38f009ebed80ce8b9b62e34b65ec95371e Mon Sep 17 00:00:00 2001 From: hyung-hwan Date: Wed, 16 Aug 2006 08:55:43 +0000 Subject: [PATCH] *** empty log message *** --- ase/awk/awk.h | 3 +- ase/awk/err.c | 3 +- ase/awk/rex.c | 78 ++++++++++++++++++++++++++++++++++++++++++++++++--- ase/awk/rex.h | 10 ++++++- 4 files changed, 87 insertions(+), 7 deletions(-) diff --git a/ase/awk/awk.h b/ase/awk/awk.h index 6e91a6f8..d9e4372b 100644 --- a/ase/awk/awk.h +++ b/ase/awk/awk.h @@ -1,5 +1,5 @@ /* - * $Id: awk.h,v 1.96 2006-08-13 16:04:32 bacon Exp $ + * $Id: awk.h,v 1.97 2006-08-16 08:55:42 bacon Exp $ */ #ifndef _XP_AWK_AWK_H_ @@ -145,6 +145,7 @@ enum XP_AWK_ERUNTIME, /* run-time error */ XP_AWK_ERUNNING, /* there are running instances */ XP_AWK_ETOOMANYRUNS, /* too many running instances */ + XP_AWK_ERECURSION, /* recursion too deep */ XP_AWK_ESRCINOPEN, XP_AWK_ESRCINCLOSE, diff --git a/ase/awk/err.c b/ase/awk/err.c index e9526d5f..061cef3c 100644 --- a/ase/awk/err.c +++ b/ase/awk/err.c @@ -1,5 +1,5 @@ /* - * $Id: err.c,v 1.35 2006-08-10 16:02:15 bacon Exp $ + * $Id: err.c,v 1.36 2006-08-16 08:55:43 bacon Exp $ */ #include @@ -19,6 +19,7 @@ const xp_char_t* xp_awk_geterrstr (int errnum) XP_T("run-time error"), XP_T("one or more running instances"), XP_T("too many running instances"), + XP_T("recursion too deep"), XP_T("cannot open source input"), XP_T("cannot close source input"), diff --git a/ase/awk/rex.c b/ase/awk/rex.c index cb9c754d..c9925f16 100644 --- a/ase/awk/rex.c +++ b/ase/awk/rex.c @@ -1,5 +1,5 @@ /* - * $Id: rex.c,v 1.19 2006-08-10 16:03:35 bacon Exp $ + * $Id: rex.c,v 1.20 2006-08-16 08:55:43 bacon Exp $ */ #include @@ -86,6 +86,12 @@ struct __builder_t xp_size_t capa; } code; + struct + { + int max; + int cur; + } depth; + int errnum; }; @@ -100,6 +106,12 @@ struct __matcher_t } str; } match; + struct + { + int max; + int cur; + } depth; + int errnum; }; @@ -128,6 +140,7 @@ typedef const xp_byte_t* (*atom_matcher_t) ( #define CODEAT(rex,pos,type) (*((type*)&(rex)->code.buf[pos])) static int __build_pattern (__builder_t* rex); +static int __build_pattern0 (__builder_t* rex); static int __build_branch (__builder_t* rex); static int __build_atom (__builder_t* rex); static int __build_charset (__builder_t* rex, struct __code_t* cmd); @@ -146,6 +159,8 @@ static const xp_byte_t* __match_branch ( __matcher_t* matcher, const xp_byte_t* base, __match_t* mat); static const xp_byte_t* __match_branch_body ( __matcher_t* matcher, const xp_byte_t* base, __match_t* mat); +static const xp_byte_t* __match_branch_body0 ( + __matcher_t* matcher, const xp_byte_t* base, __match_t* mat); static const xp_byte_t* __match_atom ( __matcher_t* matcher, const xp_byte_t* base, __match_t* mat); static const xp_byte_t* __match_bol ( @@ -220,6 +235,12 @@ static struct __char_class_t __char_class [] = }; void* xp_awk_buildrex (const xp_char_t* ptn, xp_size_t len, int* errnum) +{ + return xp_awk_safebuildrex (ptn, len, 0, errnum); +} + +void* xp_awk_safebuildrex ( + const xp_char_t* ptn, xp_size_t len, int max_depth, int* errnum) { __builder_t builder; @@ -239,7 +260,9 @@ void* xp_awk_buildrex (const xp_char_t* ptn, xp_size_t len, int* errnum) builder.ptn.curc.type = CT_EOF; builder.ptn.curc.value = XP_T('\0'); - //NEXT_CHAR (&builder, LEVEL_TOP); + builder.depth.max = max_depth; + builder.depth.cur = 0; + if (__next_char (&builder, LEVEL_TOP) == -1) { if (errnum != XP_NULL) *errnum = builder.errnum; @@ -267,17 +290,28 @@ void* xp_awk_buildrex (const xp_char_t* ptn, xp_size_t len, int* errnum) int xp_awk_matchrex (void* code, const xp_char_t* str, xp_size_t len, const xp_char_t** match_ptr, xp_size_t* match_len, int* errnum) +{ + return xp_awk_safematchrex ( + code, str, len, match_ptr, match_len, 0, errnum); +} + +int xp_awk_safematchrex (void* code, + const xp_char_t* str, xp_size_t len, + const xp_char_t** match_ptr, xp_size_t* match_len, + int max_depth, int* errnum) { __matcher_t matcher; __match_t mat; xp_size_t offset = 0; - mat.matched = xp_false; - /* store the source string */ matcher.match.str.ptr = str; matcher.match.str.end = str + len; + matcher.depth.max = max_depth; + matcher.depth.cur = 0; + + mat.matched = xp_false; /* TODO: shoud it allow an offset here??? */ mat.match_ptr = str + offset; @@ -309,12 +343,30 @@ void xp_awk_printrex (void* rex) } static int __build_pattern (__builder_t* builder) +{ + int n; + + if (builder->depth.max > 0 && builder->depth.cur >= builder->depth.max) + { + builder->errnum = XP_AWK_ERECURSION; + return -1; + } + + builder->depth.cur++; + n = __build_pattern0 (builder); + builder->depth.cur--; + + return n; +} + +static int __build_pattern0 (__builder_t* builder) { xp_size_t zero = 0; xp_size_t old_size; xp_size_t pos_nb, pos_el; int n; + old_size = builder->code.size; /* secure space for header and set the header fields to zero */ @@ -905,6 +957,24 @@ static const xp_byte_t* __match_branch ( static const xp_byte_t* __match_branch_body ( __matcher_t* matcher, const xp_byte_t* base, __match_t* mat) +{ + const xp_byte_t* n; + + if (matcher->depth.max > 0 && matcher->depth.cur >= matcher->depth.max) + { + matcher->errnum = XP_AWK_ERECURSION; + return XP_NULL; + } + + matcher->depth.cur++; + n = __match_branch_body0 (matcher, base, mat); + matcher->depth.cur--; + + return n; +} + +static const xp_byte_t* __match_branch_body0 ( + __matcher_t* matcher, const xp_byte_t* base, __match_t* mat) { const xp_byte_t* p; // __match_t mat2; diff --git a/ase/awk/rex.h b/ase/awk/rex.h index bb9fabac..e0b2aafb 100644 --- a/ase/awk/rex.h +++ b/ase/awk/rex.h @@ -1,5 +1,5 @@ /* - * $Id: rex.h,v 1.11 2006-08-10 16:02:15 bacon Exp $ + * $Id: rex.h,v 1.12 2006-08-16 08:55:43 bacon Exp $ **/ #ifndef _XP_AWK_REX_H_ @@ -48,10 +48,18 @@ extern "C" { void* xp_awk_buildrex (const xp_char_t* ptn, xp_size_t len, int* errnum); +void* xp_awk_safebuildrex ( + const xp_char_t* ptn, xp_size_t len, int max_depth, int* errnum); + int xp_awk_matchrex (void* code, const xp_char_t* str, xp_size_t len, const xp_char_t** match_ptr, xp_size_t* match_len, int* errnum); +int xp_awk_safematchrex (void* code, + const xp_char_t* str, xp_size_t len, + const xp_char_t** match_ptr, xp_size_t* match_len, + int max_depth, int* errnum); + void xp_awk_printrex (void* code); #ifdef __cplusplus