Fixed crash when macros are recursing.
authorRyan C. Gordon <icculus@icculus.org>
Mon, 23 Feb 2009 20:43:41 -0500
changeset 689 5872092cbf95
parent 688 29ee34e66161
child 690 4710df464f13
Fixed crash when macros are recursing.
mojoshader_preprocessor.c
--- a/mojoshader_preprocessor.c	Mon Feb 23 20:26:12 2009 -0500
+++ b/mojoshader_preprocessor.c	Mon Feb 23 20:43:41 2009 -0500
@@ -41,6 +41,7 @@
     int isfail;
     int out_of_memory;
     char failstr[256];
+    int recursion_count;
     Conditional *conditional_pool;
     IncludeState *include_stack;
     IncludeState *include_pool;
@@ -1136,9 +1137,14 @@
 } // handle_pp_ifndef
 
 
-// !!! FIXME: #define a b, #define b a ... recursion! check for this!
 static int handle_pp_identifier(Context *ctx)
 {
+    if (ctx->recursion_count++ >= 256)
+    {
+        fail(ctx, "Recursing macros");
+        return 0;
+    } // if
+
     IncludeState *state = ctx->include_stack;
     char *sym = (char *) alloca(state->tokenlen+1);
     memcpy(sym, state->token, state->tokenlen);
@@ -1403,6 +1409,9 @@
                 token = TOKEN_PP_UNARY_PLUS;
         } // else if
 
+        if (token != TOKEN_IDENTIFIER)
+            ctx->recursion_count = 0;
+
         switch (token)
         {
             case TOKEN_EOI:
@@ -1679,6 +1688,10 @@
         const int skipping = ((cond != NULL) && (cond->skipping));
 
         Token token = lexer(state);
+
+        if (token != TOKEN_IDENTIFIER)
+            ctx->recursion_count = 0;
+
         if (token == TOKEN_EOI)
         {
             assert(state->bytes_left == 0);