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 (shellcode) {
if (!r_egg_shellcode (egg, shellcode)) { if (!r_egg_shellcode (egg, shellcode)) {
eprintf ("Unknown shellcode '%s'\n", 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); r_egg_lang_parsechar (egg, *b);
// XXX: some parse fail errors are false positives :( // 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 // TODO: handle errors here
return R_TRUE; return R_TRUE;
} }

View File

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