Fixes for RRegex, Use r_regex_match(), comp+exec seems buggy
This commit is contained in:
parent
17750b5e03
commit
f3ddfbb9ec
5 changed files with 65 additions and 75 deletions
|
|
@ -665,7 +665,7 @@ static RList* construct_rop_gadget(RCore *core, ut64 addr, ut8 *buf, int idx,
|
|||
strncpy (grep_str, start, end - start);
|
||||
if (regex) {
|
||||
// get the first regexp.
|
||||
if (r_list_length(rx_list) > 0) {
|
||||
if (r_list_length (rx_list) > 0) {
|
||||
rx = r_list_get_n(rx_list, count++);
|
||||
}
|
||||
}
|
||||
|
|
@ -695,7 +695,8 @@ static RList* construct_rop_gadget(RCore *core, ut64 addr, ut8 *buf, int idx,
|
|||
idx += asmop.size;
|
||||
addr += asmop.size;
|
||||
if (rx) {
|
||||
grep_find = r_regex_exec(rx, asmop.buf_asm, 0, 0, 0);
|
||||
//grep_find = r_regex_exec (rx, asmop.buf_asm, 0, 0, 0);
|
||||
grep_find = r_regex_match (grep, "e", asmop.buf_asm);
|
||||
search_hit = (end && grep && (grep_find < 1));
|
||||
} else {
|
||||
search_hit = (end && grep && strstr (asmop.buf_asm, grep_str));
|
||||
|
|
|
|||
|
|
@ -9,6 +9,7 @@ typedef struct r_regex_t {
|
|||
size_t re_nsub; /* number of parenthesized subexpressions */
|
||||
const char *re_endp; /* end pointer for R_REGEX_PEND */
|
||||
struct re_guts *re_g; /* none of your business :-) */
|
||||
int re_flags;
|
||||
} RRegex;
|
||||
|
||||
typedef struct r_regmatch_t {
|
||||
|
|
@ -60,6 +61,7 @@ typedef int regoff_t;
|
|||
|
||||
R_API RRegex *r_regex_new (const char *pattern, const char *cflags);
|
||||
R_API int r_regex_run (const char *pattern, const char *flags, const char *text);
|
||||
R_API int r_regex_match (const char *pattern, const char *flags, const char *text);
|
||||
R_API int r_regex_flags(const char *flags);
|
||||
R_API int r_regex_comp(RRegex*, const char *, int);
|
||||
R_API size_t r_regex_error(int, const RRegex*, char *, size_t);
|
||||
|
|
@ -67,6 +69,7 @@ R_API size_t r_regex_error(int, const RRegex*, char *, size_t);
|
|||
* gcc under c99 mode won't compile "[]" by itself. As a workaround,
|
||||
* a dummy argument name is added.
|
||||
*/
|
||||
R_API bool r_regex_check(const RRegex *rr, const char *str);
|
||||
R_API int r_regex_exec(const RRegex *, const char *, size_t, RRegexMatch __pmatch[], int);
|
||||
R_API void r_regex_free(RRegex *);
|
||||
R_API void r_regex_fini(RRegex *);
|
||||
|
|
|
|||
|
|
@ -189,15 +189,11 @@ R_API void r_regex_fini(RRegex *preg) {
|
|||
preg->re_magic = 0; /* mark it invalid */
|
||||
g->magic = 0; /* mark it invalid */
|
||||
|
||||
if (g->strip != NULL)
|
||||
free((char *)g->strip);
|
||||
if (g->sets != NULL)
|
||||
free((char *)g->sets);
|
||||
if (g->setbits != NULL)
|
||||
free((char *)g->setbits);
|
||||
if (g->must != NULL)
|
||||
free(g->must);
|
||||
free((char *)g);
|
||||
free(g->strip);
|
||||
free(g->sets);
|
||||
free(g->setbits);
|
||||
free(g->must);
|
||||
free(g);
|
||||
}
|
||||
|
||||
R_API void r_regex_free(RRegex *preg) {
|
||||
|
|
@ -207,10 +203,9 @@ R_API void r_regex_free(RRegex *preg) {
|
|||
|
||||
/*
|
||||
- regcomp - interface for parser and compilation
|
||||
- 0 success, otherwise R_REGEX_something
|
||||
*/
|
||||
R_API int /* 0 success, otherwise R_REGEX_something */
|
||||
r_regex_comp(RRegex *preg, const char *pattern, int cflags)
|
||||
{
|
||||
R_API int r_regex_comp(RRegex *preg, const char *pattern, int cflags) {
|
||||
struct parse pa;
|
||||
struct re_guts *g;
|
||||
struct parse *p = &pa;
|
||||
|
|
@ -224,22 +219,24 @@ r_regex_comp(RRegex *preg, const char *pattern, int cflags)
|
|||
|
||||
cflags = GOODFLAGS(cflags);
|
||||
if ((cflags&R_REGEX_EXTENDED) && (cflags&R_REGEX_NOSPEC))
|
||||
return(R_REGEX_INVARG);
|
||||
return R_REGEX_INVARG;
|
||||
|
||||
if (cflags&R_REGEX_PEND) {
|
||||
if (preg->re_endp < pattern)
|
||||
return(R_REGEX_INVARG);
|
||||
len = preg->re_endp - pattern;
|
||||
} else
|
||||
len = strlen((char *)pattern);
|
||||
} else len = strlen((char *)pattern);
|
||||
|
||||
/* do the mallocs early so failure handling is easy */
|
||||
g = (struct re_guts *)malloc(sizeof(struct re_guts) +
|
||||
(NC-1)*sizeof(cat_t));
|
||||
g = (struct re_guts *)calloc(sizeof(struct re_guts) + (NC-1),sizeof(cat_t));
|
||||
if (g == NULL)
|
||||
return(R_REGEX_ESPACE);
|
||||
return R_REGEX_ESPACE;
|
||||
preg->re_flags = cflags;
|
||||
p->ssize = len/(size_t)2*(size_t)3 + (size_t)1; /* ugh */
|
||||
p->strip = (sop *)calloc(p->ssize, sizeof(sop));
|
||||
if (!p->strip) {
|
||||
return R_REGEX_ESPACE;
|
||||
}
|
||||
p->slen = 0;
|
||||
if (p->strip == NULL) {
|
||||
free((char *)g);
|
||||
|
|
@ -268,19 +265,18 @@ r_regex_comp(RRegex *preg, const char *pattern, int cflags)
|
|||
g->mlen = 0;
|
||||
g->nsub = 0;
|
||||
g->ncategories = 1; /* category 0 is "everything else" */
|
||||
g->categories = &g->catspace[-(CHAR_MIN)];
|
||||
g->categories = &g->catspace[-(CHAR_MIN)]; // WTF
|
||||
(void) memset((char *)g->catspace, 0, NC*sizeof(cat_t));
|
||||
g->backrefs = 0;
|
||||
|
||||
/* do it */
|
||||
EMIT(OEND, 0);
|
||||
g->firststate = THERE();
|
||||
if (cflags&R_REGEX_EXTENDED)
|
||||
if (cflags & R_REGEX_EXTENDED)
|
||||
p_ere(p, OUT);
|
||||
else if (cflags&R_REGEX_NOSPEC)
|
||||
p_str(p);
|
||||
else
|
||||
p_bre(p, OUT, OUT);
|
||||
else if (cflags & R_REGEX_NOSPEC)
|
||||
p_str (p);
|
||||
else p_bre (p, OUT, OUT);
|
||||
EMIT(OEND, 0);
|
||||
g->laststate = THERE();
|
||||
|
||||
|
|
@ -300,17 +296,15 @@ r_regex_comp(RRegex *preg, const char *pattern, int cflags)
|
|||
#endif
|
||||
|
||||
/* win or lose, we're done */
|
||||
if (p->error != 0) /* lose */
|
||||
r_regex_fini(preg);
|
||||
return(p->error);
|
||||
if (p->error) /* lose */
|
||||
r_regex_fini (preg);
|
||||
return p->error;
|
||||
}
|
||||
|
||||
/*
|
||||
- p_ere - ERE parser top level, concatenation and alternation
|
||||
*/
|
||||
static void
|
||||
p_ere(struct parse *p, int stop) /* character this ERE should end at */
|
||||
{
|
||||
static void p_ere(struct parse *p, int stop) { /* character this ERE should end at */
|
||||
char c;
|
||||
sopno prevback = 0;
|
||||
sopno prevfwd = 0;
|
||||
|
|
@ -351,9 +345,7 @@ p_ere(struct parse *p, int stop) /* character this ERE should end at */
|
|||
/*
|
||||
- p_ere_exp - parse one subERE, an atom possibly followed by a repetition op
|
||||
*/
|
||||
static void
|
||||
p_ere_exp(struct parse *p)
|
||||
{
|
||||
static void p_ere_exp(struct parse *p) {
|
||||
char c;
|
||||
sopno pos;
|
||||
int count;
|
||||
|
|
@ -486,9 +478,7 @@ p_ere_exp(struct parse *p)
|
|||
/*
|
||||
- p_str - string (no metacharacters) "parser"
|
||||
*/
|
||||
static void
|
||||
p_str(struct parse *p)
|
||||
{
|
||||
static void p_str(struct parse *p) {
|
||||
REQUIRE(MORE(), R_REGEX_EMPTY);
|
||||
while (MORE())
|
||||
ordinary(p, GETNEXT());
|
||||
|
|
@ -504,8 +494,7 @@ p_str(struct parse *p)
|
|||
* category in such cases. This is fairly harmless; not worth fixing.
|
||||
* The amount of lookahead needed to avoid this kludge is excessive.
|
||||
*/
|
||||
static void
|
||||
p_bre(struct parse *p,
|
||||
static void p_bre(struct parse *p,
|
||||
int end1, /* first terminating character */
|
||||
int end2) /* second terminating character */
|
||||
{
|
||||
|
|
@ -672,9 +661,7 @@ p_count(struct parse *p)
|
|||
* Note a significant property of this code: if the allocset() did SETERROR,
|
||||
* no set operations are done.
|
||||
*/
|
||||
static void
|
||||
p_bracket(struct parse *p)
|
||||
{
|
||||
static void p_bracket(struct parse *p) {
|
||||
cset *cs;
|
||||
int invert = 0;
|
||||
|
||||
|
|
@ -744,16 +731,15 @@ p_bracket(struct parse *p)
|
|||
if (nch(p, cs) == 1) { /* optimize singleton sets */
|
||||
ordinary(p, firstch(p, cs));
|
||||
freeset(p, cs);
|
||||
} else
|
||||
} else {
|
||||
EMIT(OANYOF, freezeset(p, cs));
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
- p_b_term - parse one term of a bracketed character list
|
||||
*/
|
||||
static void
|
||||
p_b_term(struct parse *p, cset *cs)
|
||||
{
|
||||
static void p_b_term(struct parse *p, cset *cs) {
|
||||
char c;
|
||||
char start = 0, finish;
|
||||
int i;
|
||||
|
|
@ -814,9 +800,7 @@ p_b_term(struct parse *p, cset *cs)
|
|||
/*
|
||||
- p_b_cclass - parse a character-class name and deal with it
|
||||
*/
|
||||
static void
|
||||
p_b_cclass(struct parse *p, cset *cs)
|
||||
{
|
||||
static void p_b_cclass(struct parse *p, cset *cs) {
|
||||
char *sp = p->next;
|
||||
struct cclass *cp;
|
||||
size_t len;
|
||||
|
|
@ -847,9 +831,7 @@ p_b_cclass(struct parse *p, cset *cs)
|
|||
*
|
||||
* This implementation is incomplete. xxx
|
||||
*/
|
||||
static void
|
||||
p_b_eclass(struct parse *p, cset *cs)
|
||||
{
|
||||
static void p_b_eclass(struct parse *p, cset *cs) {
|
||||
char c;
|
||||
|
||||
c = p_b_coll_elem(p, '=');
|
||||
|
|
@ -922,9 +904,7 @@ othercase(int ch)
|
|||
*
|
||||
* Boy, is this implementation ever a kludge...
|
||||
*/
|
||||
static void
|
||||
bothcases(struct parse *p, int ch)
|
||||
{
|
||||
static void bothcases(struct parse *p, int ch) {
|
||||
char *oldnext = p->next;
|
||||
char *oldend = p->end;
|
||||
char bracket[3];
|
||||
|
|
@ -1069,9 +1049,7 @@ seterr(struct parse *p, int e)
|
|||
/*
|
||||
- allocset - allocate a set of characters for []
|
||||
*/
|
||||
static cset *
|
||||
allocset(struct parse *p)
|
||||
{
|
||||
static cset * allocset(struct parse *p) {
|
||||
int no = p->g->ncsets++;
|
||||
size_t nc;
|
||||
size_t nbytes;
|
||||
|
|
@ -1128,9 +1106,7 @@ nomem:
|
|||
/*
|
||||
- freeset - free a now-unused set
|
||||
*/
|
||||
static void
|
||||
freeset(struct parse *p, cset *cs)
|
||||
{
|
||||
static void freeset(struct parse *p, cset *cs) {
|
||||
int i;
|
||||
cset *top = &p->g->sets[p->g->ncsets];
|
||||
size_t css = (size_t)p->g->csetsize;
|
||||
|
|
@ -1197,9 +1173,7 @@ firstch(struct parse *p, cset *cs)
|
|||
/*
|
||||
- nch - number of characters in a set
|
||||
*/
|
||||
static int
|
||||
nch(struct parse *p, cset *cs)
|
||||
{
|
||||
static int nch(struct parse *p, cset *cs) {
|
||||
int i;
|
||||
size_t css = (size_t)p->g->csetsize;
|
||||
int n = 0;
|
||||
|
|
@ -1213,9 +1187,7 @@ nch(struct parse *p, cset *cs)
|
|||
/*
|
||||
- mcadd - add a collating element to a cset
|
||||
*/
|
||||
static void
|
||||
mcadd( struct parse *p, cset *cs, char *cp)
|
||||
{
|
||||
static void mcadd( struct parse *p, cset *cs, char *cp) {
|
||||
size_t oldend = cs->smultis;
|
||||
void *np;
|
||||
|
||||
|
|
@ -1240,9 +1212,7 @@ mcadd( struct parse *p, cset *cs, char *cp)
|
|||
* is deferred.
|
||||
*/
|
||||
/* ARGSUSED */
|
||||
static void
|
||||
mcinvert(struct parse *p, cset *cs)
|
||||
{
|
||||
static void mcinvert(struct parse *p, cset *cs) {
|
||||
assert(cs->multis == NULL); /* xxx */
|
||||
}
|
||||
|
||||
|
|
@ -1253,9 +1223,7 @@ mcinvert(struct parse *p, cset *cs)
|
|||
* is deferred.
|
||||
*/
|
||||
/* ARGSUSED */
|
||||
static void
|
||||
mccase(struct parse *p, cset *cs)
|
||||
{
|
||||
static void mccase(struct parse *p, cset *cs) {
|
||||
assert(cs->multis == NULL); /* xxx */
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -128,6 +128,10 @@
|
|||
|
||||
#include "engine.c"
|
||||
|
||||
|
||||
R_API bool r_regex_check(const RRegex *rr, const char *str) {
|
||||
return r_regex_exec (rr, str, 0, NULL, rr->re_flags);
|
||||
}
|
||||
/*
|
||||
- regexec - interface for matching
|
||||
*
|
||||
|
|
@ -137,7 +141,7 @@
|
|||
*/
|
||||
int /* 0 success, R_REGEX_NOMATCH failure */
|
||||
r_regex_exec(const RRegex *preg, const char *string, size_t nmatch,
|
||||
RRegexMatch pmatch[], int eflags)
|
||||
RRegexMatch pmatch[], int eflags)
|
||||
{
|
||||
struct re_guts *g = preg->re_g;
|
||||
#ifdef REDEBUG
|
||||
|
|
@ -145,6 +149,8 @@ r_regex_exec(const RRegex *preg, const char *string, size_t nmatch,
|
|||
#else
|
||||
# define GOODFLAGS(f) ((f)&(R_REGEX_NOTBOL|R_REGEX_NOTEOL|R_REGEX_STARTEND))
|
||||
#endif
|
||||
if (!preg || !string)
|
||||
return R_REGEX_ASSERT;
|
||||
|
||||
if (preg->re_magic != MAGIC1 || g->magic != MAGIC2)
|
||||
return(R_REGEX_BADPAT);
|
||||
|
|
|
|||
|
|
@ -18,6 +18,17 @@ int _main() {
|
|||
return 0;
|
||||
}
|
||||
|
||||
static void test_or() {
|
||||
RRegex *rx = r_regex_new ("(eax|ebx)", "e");
|
||||
printf ("result (%s) = %d\n", "mov eax", r_regex_match("(eax|ebx)", "e", "mov eax"));
|
||||
printf ("result (%s) = %d\n", "mov ebx", r_regex_match("(eax|ebx)", "e", "mov ebx"));
|
||||
printf ("result (%s) = %d\n", "mov eax", r_regex_check(rx, "mov eax"));
|
||||
printf ("result (%s) = %d\n", "mov ebx", r_regex_check(rx, "mov ebx"));
|
||||
printf ("result (%s) = %d\n", "mov eax", r_regex_exec(rx, "mov eax", 0, 0, 1));
|
||||
printf ("result (%s) = %d\n", "mov ebx", r_regex_exec(rx, "mov ebx", 0, 0, 1));
|
||||
r_regex_free (rx);
|
||||
}
|
||||
|
||||
int main(int argc, char **argv) {
|
||||
const char *needle = "^hi";
|
||||
const char *haystack_1 = "patata";
|
||||
|
|
@ -35,5 +46,6 @@ int main(int argc, char **argv) {
|
|||
printf ("result (%s) = %d\n", haystack_2, res);
|
||||
r_regex_free (rx);
|
||||
} else printf ("oops, cannot compile regexp\n");
|
||||
test_or();
|
||||
return 0;
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue