From edd88177d99078e9d03324dec593b60eaa59d3a2 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Henrik=20Grubbstr=C3=B6m=20=28Grubba=29?=
 <grubba@grubba.org>
Date: Thu, 2 May 2019 20:25:29 +0200
Subject: [PATCH] CritBit: Fixed stack inconsistency issues in _m_delete().

cb_delete() did not always set the output value.

_m_delete() now survives a gc() being triggered during cb_delete().
---
 src/post_modules/CritBit/tree_low.c    | 2 ++
 src/post_modules/CritBit/tree_source.H | 7 ++++++-
 2 files changed, 8 insertions(+), 1 deletion(-)

diff --git a/src/post_modules/CritBit/tree_low.c b/src/post_modules/CritBit/tree_low.c
index 94f55bf8ca..2ff1c09216 100644
--- a/src/post_modules/CritBit/tree_low.c
+++ b/src/post_modules/CritBit/tree_low.c
@@ -326,6 +326,8 @@ PARENT:
 	    }
 	}
 
+    } else if (val) {
+      SET_SVAL(*val, PIKE_T_INT, NUMBER_UNDEFINED, integer, 0);
     }
 
     cb_check_node(tree->root);
diff --git a/src/post_modules/CritBit/tree_source.H b/src/post_modules/CritBit/tree_source.H
index 734f994172..0441416c54 100644
--- a/src/post_modules/CritBit/tree_source.H
+++ b/src/post_modules/CritBit/tree_source.H
@@ -77,7 +77,12 @@ cmod_DEFINE_EVAL(COPY_NODE, TREE_CLASSIFY(_copy_node))
 
 	oldsize = (THIS->tree.root) ? THIS->tree.root->size : 0;
 	if (oldsize) {
-	    cb_delete(& THIS->tree, k, Pike_sp++);
+	    /* NB: cb_delete() may run pike code (like eg when
+	     *     comparing bignums). The stack must thus be
+	     *     consistent in case eg a gc() is triggered.
+	     */
+	    push_undefined();
+	    cb_delete(& THIS->tree, k, Pike_sp-1);
 	    size = (THIS->tree.root) ? THIS->tree.root->size : 0;
 	    if (size < oldsize) {
 		THIS->rev++;
-- 
GitLab