From 27f08df1d3988510b031da7e2167233563d90bca Mon Sep 17 00:00:00 2001
From: "Meredith L. Patterson" <mlp@thesmartpolitenerd.com>
Date: Sun, 20 Apr 2014 21:40:09 +0200
Subject: [PATCH] fix infinite loop in isValidCF with indirect

---
 src/parsers/indirect.c | 27 +++++++++++++++++++++------
 1 file changed, 21 insertions(+), 6 deletions(-)

diff --git a/src/parsers/indirect.c b/src/parsers/indirect.c
index c91eaab5..026286d3 100644
--- a/src/parsers/indirect.c
+++ b/src/parsers/indirect.c
@@ -1,16 +1,28 @@
 #include "parser_internal.h"
 
+typedef struct HIndirectEnv_ {
+  const HParser* parser;
+  bool touched;
+} HIndirectEnv;
+
 static HParseResult* parse_indirect(void* env, HParseState* state) {
-  return h_do_parse(env, state);
+  return h_do_parse(((HIndirectEnv*)env)->parser, state);
 }
 
 static bool indirect_isValidCF(void *env) {
-  HParser *p = (HParser*)env;
-  return p->vtable->isValidCF(p->env);
+  HIndirectEnv *ie = (HIndirectEnv*)env;
+  if (ie->touched)
+    return true;
+  ie->touched = true;
+  const HParser *p = ie->parser;
+  // self->vtable->isValidCF = h_true;
+  bool ret = p->vtable->isValidCF(p->env);
+  ie->touched = false;
+  return ret;
 }
 
 static void desugar_indirect(HAllocator *mm__, HCFStack *stk__, void *env) {
-  HCFS_DESUGAR( (HParser *)env );
+  HCFS_DESUGAR( ((HIndirectEnv *)env)->parser );
 }
 
 static const HParserVtable indirect_vt = {
@@ -27,12 +39,15 @@ void h_bind_indirect__m(HAllocator *mm__, HParser* indirect, const HParser* inne
 
 void h_bind_indirect(HParser* indirect, const HParser* inner) {
   assert_message(indirect->vtable == &indirect_vt, "You can only bind an indirect parser");
-  indirect->env = (void*)inner;
+  ((HIndirectEnv*)indirect->env)->parser = inner;
 }
 
 HParser* h_indirect() {
   return h_indirect__m(&system_allocator);
 }
 HParser* h_indirect__m(HAllocator* mm__) {
-  return h_new_parser(mm__, &indirect_vt, NULL);
+  HIndirectEnv *env = h_new(HIndirectEnv, 1);
+  env->parser = NULL;
+  env->touched = false;
+  return h_new_parser(mm__, &indirect_vt, env);
 }
-- 
GitLab