Fix #287 - ragg2 segfaults on uneven number of accolades

This commit is contained in:
pancake 2013-10-24 00:51:26 +02:00
parent 61042a4cb9
commit d025bd66f3
3 changed files with 52 additions and 43 deletions

View File

@ -247,7 +247,9 @@ int main(int argc, char **argv) {
}
}
}
r_egg_compile (egg);
if (!r_egg_compile (egg)) {
return 1;
}
if (shellcode) {
if (!r_egg_shellcode (egg, shellcode)) {
eprintf ("Unknown shellcode '%s'\n", shellcode);

View File

@ -261,6 +261,10 @@ R_API int r_egg_compile(REgg *egg) {
r_egg_lang_parsechar (egg, *b);
// XXX: some parse fail errors are false positives :(
}
if (egg->context>0) {
eprintf ("ERROR: expected '}' at the end of the file. %d left\n", egg->context);
return R_FALSE;
}
// TODO: handle errors here
return R_TRUE;
}

View File

@ -2,6 +2,7 @@
#include <r_egg.h>
#define CTX egg->context
char *nested[32] = {0};
char *nestede[32] = {0};
int nestedi[32] = {0};
@ -77,7 +78,6 @@ static int line = 1;
static char elem[1024];
static int attsyntax = 0;
static int elem_n = 0;
static int context = 0;
static char *callname = NULL;
static char *endframe = NULL;
static char *ctxpush[32];
@ -201,7 +201,7 @@ static void rcc_pusharg(REgg *egg, char *str) {
char buf[64], *p = r_egg_mkvar (egg, buf, str, 0);
if (!p) return;
// TODO: free (ctxpush[context]);
ctxpush[context] = strdup (p); // INDEX IT WITH NARGS OR CONTEXT?!?
ctxpush[CTX] = strdup (p); // INDEX IT WITH NARGS OR CONTEXT?!?
nargs++;
if (pushargs)
e->push_arg (egg, varxs, nargs, p);
@ -213,7 +213,7 @@ static void rcc_element(REgg *egg, char *str) {
char *p = strrchr (str, ',');
int num, num2;
if (context) {
if (CTX) {
nargs = 0;
if (mode == GOTO)
mode = NORMAL; // XXX
@ -378,7 +378,7 @@ static void rcc_fun(REgg *egg, const char *str) {
char *ptr, *ptr2;
REggEmit *e = egg->emit;
str = skipspaces (str);
if (context) {
if (CTX) {
ptr = strchr (str, '=');
if (ptr) {
*ptr++ = '\0';
@ -390,7 +390,8 @@ static void rcc_fun(REgg *egg, const char *str) {
} else {
str = skipspaces (str);
rcc_set_callname (skipspaces (str));
egg->emit->comment (egg, "rcc_fun %d (%s)", context, callname);
egg->emit->comment (egg, "rcc_fun %d (%s)",
CTX, callname);
}
} else {
ptr = strchr (str, '@');
@ -457,9 +458,9 @@ static void rcc_fun(REgg *egg, const char *str) {
}
} else {
//e->jmp (egg, ctxpush[context], 0);
if (context>0) {
if (CTX>0) {
// WTF?
eprintf ("LABEL %d\n", context);
eprintf ("LABEL %d\n", CTX);
r_egg_printf (egg, "\n%s:\n", str);
} else {
if (!strcmp (str, "goto")) {
@ -484,10 +485,10 @@ static void shownested() {
}
#endif
static void set_nested(const char *s) {
int c = context-1;
static void set_nested(REgg *egg, const char *s) {
int c = CTX-1;
int i=0;
if (context<1)
if (CTX<1)
return;
free (nested[c]);
nested[c] = strdup (s);
@ -495,8 +496,8 @@ return;
/** clear inner levels **/
for (i=0; i<10; i++) {
//nestedi[context+i] = 0;
free (nested[context+i]);
nested[context+i] = NULL;
free (nested[CTX+i]);
nested[CTX+i] = NULL;
}
}
@ -504,16 +505,16 @@ static void rcc_context(REgg *egg, int delta) {
REggEmit *emit = egg->emit;
char str[64];
nestedi[context-1]++;
if (callname && context>0) {// && delta>0) {
nestedi[CTX-1]++;
if (callname && CTX>0) {// && delta>0) {
// set_nested (callname);
//eprintf (" - - - - - - - set nested d=%d c=%d (%s)\n", delta, context-1, callname);
//shownested();
}
context += delta;
CTX += delta;
lastctxdelta = delta;
if (context == 0 && delta < 0) {
if (CTX == 0 && delta < 0) {
if (mode != NAKED)
emit->frame_end (egg, stackframe+stackfixed, nbrackets);
if (mode == NORMAL) /* XXX : commenting this makes hello.r unhappy! TODO: find a cleaner alternative */
@ -557,26 +558,28 @@ emit->while_end (egg, get_frame_label (context-1));
n = strchr (elem, '!'); /* negate */
if (!strcmp (cn, "while")) {
char lab[128];
sprintf (lab, "__begin_%d_%d_%d", nfunctions, context-1, nestedi[context-1]);
emit->get_while_end (egg, str, ctxpush[context-1], lab); //get_frame_label (2));
sprintf (lab, "__begin_%d_%d_%d", nfunctions,
CTX-1, nestedi[CTX-1]);
emit->get_while_end (egg, str, ctxpush[CTX-1], lab); //get_frame_label (2));
//get_frame_label (2));
//eprintf ("------ (%s)\n", ctxpush[context-1]);
// free (endframe);
// XXX: endframe is deprecated, must use set_nested only
if (delta>0) {
set_nested (str);
set_nested (egg, str);
}
rcc_set_callname ("if"); // append 'if' body
}
if (!strcmp (cn, "if")) {
//emit->branch (egg, b, g, e, n, varsize, get_end_frame_label (egg));
// HACK HACK :D
sprintf (str, "__end_%d_%d_%d", nfunctions, context-1, nestedi[context-1]);
nestede[context-1] = strdup (str);
sprintf (str, "__end_%d_%d_%d", nfunctions, context, nestedi[context-1]);
sprintf (str, "__end_%d_%d_%d", nfunctions,
CTX-1, nestedi[CTX-1]);
nestede[CTX-1] = strdup (str);
sprintf (str, "__end_%d_%d_%d", nfunctions,
CTX, nestedi[CTX-1]);
emit->branch (egg, b, g, e, n, varsize, str);
if (context>0) {
if (CTX>0) {
/* XXX .. */
} else eprintf ("FUCKING CASE\n");
rcc_reset_callname ();
@ -606,7 +609,7 @@ eprintf ("STACKTRAF %d\n", stackframe);
}
/* capture body */
if (c == '}') { /* XXX: repeated code!! */
if (context < 1) {
if (CTX< 1) {
inlinectr = 0;
rcc_context (egg, -1);
slurp = 0;
@ -630,7 +633,7 @@ eprintf ("STACKTRAF %d\n", stackframe);
R_FREE (dstvar);
R_FREE (dstval);
ndstval = 0;
context = 0;
CTX = 0;
return 1;
} else eprintf ("FUCK FUCK\n");
}
@ -654,7 +657,7 @@ static int parseinlinechar(REgg *egg, char c) {
/* capture body */
if (c == '}') { /* XXX: repeated code!! */
if (context < 2) {
if (CTX < 2) {
rcc_context (egg, -1);
slurp = 0;
mode = NORMAL;
@ -727,7 +730,7 @@ static void rcc_next(REgg *egg) {
eprintf ("Invalid number of arguments for goto()\n");
return;
}
e->jmp (egg, ctxpush[context], 0);
e->jmp (egg, ctxpush[CTX], 0);
rcc_reset_callname ();
return;
}
@ -750,7 +753,7 @@ static void rcc_next(REgg *egg) {
char var[128];
if (lastctxdelta>=0)
exit (eprintf ("ERROR: Unsupported while syntax\n"));
sprintf (var, "__begin_%d_%d_%d\n", nfunctions, context, nestedi[context-1]);
sprintf (var, "__begin_%d_%d_%d\n", nfunctions, CTX, nestedi[CTX-1]);
e->while_end (egg, var); //get_frame_label (1));
#if 0
eprintf ("------------------------------------------ lastctx: %d\n", lastctxdelta);
@ -949,33 +952,33 @@ R_API int r_egg_lang_parsechar(REgg *egg, char c) {
slurp = ')';
break;
case '{':
if (context>0) {
if (CTX>0) {
// r_egg_printf (egg, " %s:\n", get_frame_label (0));
r_egg_printf (egg, " __begin_%d_%d_%d:\n",
nfunctions, context, nestedi[context]); //%s:\n", get_frame_label (0));
nfunctions, CTX, nestedi[CTX]); //%s:\n", get_frame_label (0));
}
rcc_context (egg, 1);
break;
case '}':
endframe = nested[context-1];
endframe = nested[CTX-1];
if (endframe) {
// XXX: use endframe[context]
r_egg_printf (egg, "%s\n", endframe);
// R_FREE (endframe);
}
if (context>0) {
if (nestede[context]) {
r_egg_printf (egg, "%s:\n", nestede[context]);
//nestede[context] = NULL;
if (CTX>0) {
if (nestede[CTX]) {
r_egg_printf (egg, "%s:\n", nestede[CTX]);
//nestede[CTX] = NULL;
} else {
r_egg_printf (egg, " __end_%d_%d_%d:\n",
nfunctions, context, nestedi[context-1]);
nfunctions, CTX, nestedi[CTX-1]);
//get_end_frame_label (egg));
}
nbrackets++;
}
rcc_context (egg, -1);
if (context == 0) {
if (CTX== 0) {
nbrackets = 0;
nfunctions++;
}