From c1b8f0b0da2fce4e6513e37d58a1ec6095c88500 Mon Sep 17 00:00:00 2001
From: Martin Stjernholm <mast@lysator.liu.se>
Date: Mon, 2 Jul 2001 22:09:18 +0200
Subject: [PATCH] Take more care to avoid leaving throw_svalue around with a
 backtrace.

Rev: src/builtin_functions.c:1.390
Rev: src/cpp.c:1.90
Rev: src/interpret.c:1.212
Rev: src/interpret.h:1.91
Rev: src/language.yacc:1.255
Rev: src/las.c:1.255
Rev: src/mapping.c:1.129
Rev: src/modules/Java/jvm.c:1.34
Rev: src/object.c:1.176
Rev: src/pike_error.h:1.12
Rev: src/preprocessor.h:1.43
Rev: src/svalue.c:1.110
---
 src/builtin_functions.c |  4 +++-
 src/cpp.c               |  4 +++-
 src/interpret.c         | 25 +++++++++++++++++--------
 src/interpret.h         |  5 +++--
 src/language.yacc       |  6 +++---
 src/las.c               |  6 +++++-
 src/mapping.c           |  8 ++++++--
 src/modules/Java/jvm.c  |  6 ++++--
 src/object.c            |  6 ++++--
 src/pike_error.h        |  8 ++++++--
 src/preprocessor.h      |  4 +++-
 src/svalue.c            |  8 ++++----
 12 files changed, 61 insertions(+), 29 deletions(-)

diff --git a/src/builtin_functions.c b/src/builtin_functions.c
index bd8f812610..13c263b142 100644
--- a/src/builtin_functions.c
+++ b/src/builtin_functions.c
@@ -5,7 +5,7 @@
 \*/
 /**/
 #include "global.h"
-RCSID("$Id: builtin_functions.c,v 1.389 2001/07/02 07:02:44 hubbe Exp $");
+RCSID("$Id: builtin_functions.c,v 1.390 2001/07/02 20:09:16 mast Exp $");
 #include "interpret.h"
 #include "svalue.h"
 #include "pike_macros.h"
@@ -3140,6 +3140,8 @@ node *optimize_replace(node *n)
 	if (SETJMP(tmp)) {
 	  yywarning("Optimizer failure in replace().");
 	  pop_n_elems(Pike_sp - save_sp);
+	  free_svalue(&throw_value);
+	  throw_value.type = T_INT;
 	} else {
 	  extern struct program *multi_string_replace_program;
 	  INT16 lfun;
diff --git a/src/cpp.c b/src/cpp.c
index 2b78836c40..c1e2bf9489 100644
--- a/src/cpp.c
+++ b/src/cpp.c
@@ -5,7 +5,7 @@
 \*/
 
 /*
- * $Id: cpp.c,v 1.89 2001/06/14 19:28:08 grubba Exp $
+ * $Id: cpp.c,v 1.90 2001/07/02 20:09:16 mast Exp $
  */
 #include "global.h"
 #include "stralloc.h"
@@ -1225,6 +1225,8 @@ static int do_safe_index_call(struct pike_string *s)
   
   if (SETJMP(recovery)) {
     res = 0;
+    free_svalue(&throw_value);
+    throw_value.type = T_INT;
   } else {
     ref_push_string(s);
     f_index(2);
diff --git a/src/interpret.c b/src/interpret.c
index 1947a0e008..c529a3bdd3 100644
--- a/src/interpret.c
+++ b/src/interpret.c
@@ -5,7 +5,7 @@
 \*/
 /**/
 #include "global.h"
-RCSID("$Id: interpret.c,v 1.211 2001/07/02 04:09:48 hubbe Exp $");
+RCSID("$Id: interpret.c,v 1.212 2001/07/02 20:09:17 mast Exp $");
 #include "interpret.h"
 #include "object.h"
 #include "program.h"
@@ -1619,7 +1619,7 @@ PMOD_EXPORT int apply_low_safe_and_stupid(struct object *o, INT32 offset)
   return ret;
 }
 
-PMOD_EXPORT void safe_apply_low(struct object *o,int fun,int args)
+PMOD_EXPORT void safe_apply_low2(struct object *o,int fun,int args, int handle_errors)
 {
   JMP_BUF recovery;
 
@@ -1628,8 +1628,7 @@ PMOD_EXPORT void safe_apply_low(struct object *o,int fun,int args)
   throw_value.type=T_INT;
   if(SETJMP(recovery))
   {
-    if(throw_value.type != T_INT)
-      call_handle_error();
+    if(handle_errors) call_handle_error();
     Pike_sp->u.integer = 0;
     Pike_sp->subtype=NUMBER_NUMBER;
     Pike_sp->type = T_INT;
@@ -1651,13 +1650,17 @@ PMOD_EXPORT void safe_apply_low(struct object *o,int fun,int args)
   UNSETJMP(recovery);
 }
 
+PMOD_EXPORT void safe_apply_low(struct object *o,int fun,int args)
+{
+  safe_apply_low2(o, fun, args, 1);
+}
 
 PMOD_EXPORT void safe_apply(struct object *o, char *fun ,INT32 args)
 {
 #ifdef PIKE_DEBUG
   if(!o->prog) fatal("Apply safe on destructed object.\n");
 #endif
-  safe_apply_low(o, find_identifier(fun, o->prog), args);
+  safe_apply_low2(o, find_identifier(fun, o->prog), args, 1);
 }
 
 PMOD_EXPORT void safe_apply_handler(const char *fun,
@@ -1666,16 +1669,22 @@ PMOD_EXPORT void safe_apply_handler(const char *fun,
 				    INT32 args)
 {
   int i;
+  free_svalue(&throw_value);
+  throw_value.type = T_INT;
   if (handler && handler->prog &&
       (i = find_identifier(fun, handler->prog)) != -1) {
-    safe_apply_low(handler, i, args);
+    safe_apply_low2(handler, i, args, 0);
   } else if (compat && compat->prog &&
 	     (i = find_identifier(fun, compat->prog)) != -1) {
-    safe_apply_low(compat, i, args);
+    safe_apply_low2(compat, i, args, 0);
   } else {
     struct object *master_obj = master();
     i = find_identifier(fun, master_obj->prog);
-    safe_apply_low(master_obj, i, args);
+    safe_apply_low2(master_obj, i, args, 0);
+  }
+  if (throw_value.type != T_STRING && throw_value.type != T_INT) {
+    free_svalue(&throw_value);
+    throw_value.type = T_INT;
   }
 }
 
diff --git a/src/interpret.h b/src/interpret.h
index 197f902d0c..4bcd0c97d0 100644
--- a/src/interpret.h
+++ b/src/interpret.h
@@ -5,7 +5,7 @@
 \*/
 
 /*
- * $Id: interpret.h,v 1.90 2001/06/29 23:33:30 hubbe Exp $
+ * $Id: interpret.h,v 1.91 2001/07/02 20:09:17 mast Exp $
  */
 #ifndef INTERPRET_H
 #define INTERPRET_H
@@ -266,7 +266,7 @@ do{ \
     fun_=find_identifier(FUN,master_ob->prog); \
     master_cnt = master_ob->prog->id; \
   } \
-  safe_apply_low(master_ob, fun_, ARGS); \
+  safe_apply_low2(master_ob, fun_, ARGS, 1); \
 }while(0)
 
 #define SAFE_APPLY_HANDLER(FUN, HANDLER, COMPAT, ARGS) do {	\
@@ -332,6 +332,7 @@ PMOD_EXPORT void f_call_function(INT32 args);
 PMOD_EXPORT void call_handle_error(void);
 PMOD_EXPORT int apply_low_safe_and_stupid(struct object *o, INT32 offset);
 PMOD_EXPORT void safe_apply_low(struct object *o,int fun,int args);
+PMOD_EXPORT void safe_apply_low2(struct object *o,int fun,int args, int handle_errors);
 PMOD_EXPORT void safe_apply(struct object *o, char *fun ,INT32 args);
 PMOD_EXPORT void safe_apply_handler(const char *fun,
 				    struct object *handler,
diff --git a/src/language.yacc b/src/language.yacc
index 8637a18f0c..ef8e57cdf3 100644
--- a/src/language.yacc
+++ b/src/language.yacc
@@ -112,7 +112,7 @@
 /* This is the grammar definition of Pike. */
 
 #include "global.h"
-RCSID("$Id: language.yacc,v 1.254 2001/06/30 22:11:09 mast Exp $");
+RCSID("$Id: language.yacc,v 1.255 2001/07/02 20:09:17 mast Exp $");
 #ifdef HAVE_MEMORY_H
 #include <memory.h>
 #endif
@@ -3833,9 +3833,9 @@ static void safe_inc_enum(void)
   struct svalue *save_sp = Pike_sp;
   JMP_BUF recovery;
 
-  free_svalue(&throw_value);
-  throw_value.type = T_INT;
   if (SETJMP(recovery)) {
+    free_svalue(&throw_value);
+    throw_value.type = T_INT;
     yyerror("Bad implicit enum value (failed to add 1).");
     while(Pike_sp > save_sp) pop_stack();
   } else {
diff --git a/src/las.c b/src/las.c
index a840f0c022..34c1b992f2 100644
--- a/src/las.c
+++ b/src/las.c
@@ -5,7 +5,7 @@
 \*/
 /**/
 #include "global.h"
-RCSID("$Id: las.c,v 1.254 2001/06/23 21:52:09 hubbe Exp $");
+RCSID("$Id: las.c,v 1.255 2001/07/02 20:09:17 mast Exp $");
 
 #include "language.h"
 #include "interpret.h"
@@ -1752,6 +1752,8 @@ node *index_node(node *n, char *node_name, struct pike_string *id)
 	     *
 	     * FIXME: Report the error thrown.
 	     */
+	    free_svalue(&throw_value);
+	    throw_value.type = T_INT;
 	    if (Pike_sp > save_sp) {
 	      pop_n_elems(Pike_sp - save_sp);
 	    } else if (Pike_sp != save_sp) {
@@ -4998,6 +5000,8 @@ ptrdiff_t eval_low(node *n)
 	  yyerror("Nonstandard error format.");
 	}
       }
+      free_svalue(&throw_value);
+      throw_value.type = T_INT;
     }else{
       if(foo.yes)
 	pop_n_elems(Pike_sp-save_sp);
diff --git a/src/mapping.c b/src/mapping.c
index d8243ecc89..ff1df7d3ce 100644
--- a/src/mapping.c
+++ b/src/mapping.c
@@ -5,7 +5,7 @@
 \*/
 /**/
 #include "global.h"
-RCSID("$Id: mapping.c,v 1.128 2001/07/01 21:34:51 mast Exp $");
+RCSID("$Id: mapping.c,v 1.129 2001/07/02 20:09:18 mast Exp $");
 #include "main.h"
 #include "object.h"
 #include "mapping.h"
@@ -1650,7 +1650,11 @@ void describe_mapping(struct mapping *m,struct processing *p,int indent)
     }
 
     t_flag = 0;
-    if(!SETJMP(catch))
+    if(SETJMP(catch)) {
+      free_svalue(&throw_value);
+      throw_value.type = T_INT;
+    }
+    else
       sort_array_destructively(a);
     UNSETJMP(catch);
     t_flag = save_t_flag;
diff --git a/src/modules/Java/jvm.c b/src/modules/Java/jvm.c
index 1d9a311d6a..f47d427676 100644
--- a/src/modules/Java/jvm.c
+++ b/src/modules/Java/jvm.c
@@ -1,5 +1,5 @@
 /*
- * $Id: jvm.c,v 1.33 2001/04/23 22:17:32 marcus Exp $
+ * $Id: jvm.c,v 1.34 2001/07/02 20:09:07 mast Exp $
  *
  * Pike interface to Java Virtual Machine
  *
@@ -17,7 +17,7 @@
 #endif /* HAVE_CONFIG_H */
 
 #include "global.h"
-RCSID("$Id: jvm.c,v 1.33 2001/04/23 22:17:32 marcus Exp $");
+RCSID("$Id: jvm.c,v 1.34 2001/07/02 20:09:07 mast Exp $");
 #include "program.h"
 #include "interpret.h"
 #include "stralloc.h"
@@ -1636,6 +1636,8 @@ static void do_native_dispatch(struct native_method_context *ctx,
     make_java_exception(ctx->nat->jvm, env, &throw_value);
     pop_n_elems(Pike_sp-osp);
     UNSETJMP(recovery);
+    free_svalue(&throw_value);
+    throw_value.type = PIKE_T_INT;
     return;
   }
 
diff --git a/src/object.c b/src/object.c
index 7a38296e02..3386be3a91 100644
--- a/src/object.c
+++ b/src/object.c
@@ -5,7 +5,7 @@
 \*/
 /**/
 #include "global.h"
-RCSID("$Id: object.c,v 1.175 2001/07/01 18:29:58 mast Exp $");
+RCSID("$Id: object.c,v 1.176 2001/07/02 20:09:18 mast Exp $");
 #include "object.h"
 #include "dynamic_buffer.h"
 #include "interpret.h"
@@ -408,6 +408,8 @@ PMOD_EXPORT struct object *get_master(void)
 #endif
 	/* do nothing */
 	UNSETJMP(tmp);
+	free_svalue(&throw_value);
+	throw_value.type = T_INT;
       }else{
 	f_decode_value(2);
 	UNSETJMP(tmp);
@@ -513,7 +515,7 @@ static void call_destroy(struct object *o, int foo)
 		o, o->refs);
 #endif
       if(foo) push_int(1);
-      safe_apply_low(o, e, foo?1:0);
+      safe_apply_low2(o, e, foo?1:0, 1);
       pop_stack();
 #ifdef GC_VERBOSE
       if (Pike_in_gc > GC_PASS_PREPARE)
diff --git a/src/pike_error.h b/src/pike_error.h
index cc479f5020..d7a42ae5f5 100644
--- a/src/pike_error.h
+++ b/src/pike_error.h
@@ -5,7 +5,7 @@
 \*/
 
 /*
- * $Id: pike_error.h,v 1.11 2001/03/28 10:02:42 hubbe Exp $
+ * $Id: pike_error.h,v 1.12 2001/07/02 20:09:18 mast Exp $
  */
 #ifndef PIKE_ERROR_H
 #define PIKE_ERROR_H
@@ -294,7 +294,11 @@ void cleanup_error(void);
 #define exception_endtry \
             else \
                 __exception_rethrow = 1; \
-            if(!__is_exception) \
+            if(__is_exception) { \
+		free_svalue(&throw_value); \
+		throw_value.type = T_INT; \
+	    } \
+	    else \
                 UNSETJMP(exception); \
             if(__exception_rethrow) \
                 rethrow; \
diff --git a/src/preprocessor.h b/src/preprocessor.h
index 400b795928..53097bcbde 100644
--- a/src/preprocessor.h
+++ b/src/preprocessor.h
@@ -1,5 +1,5 @@
 /*
- * $Id: preprocessor.h,v 1.42 2001/06/07 20:16:26 grubba Exp $
+ * $Id: preprocessor.h,v 1.43 2001/07/02 20:09:18 mast Exp $
  *
  * Preprocessor template.
  * Based on cpp.c 1.45
@@ -764,6 +764,8 @@ static ptrdiff_t calc(struct cpp *this, WCHAR *data, ptrdiff_t len,
     }else{
       cpp_error(this, "Nonstandard error format.");
     }
+    free_svalue(&throw_value);
+    throw_value.type = T_INT;
     FIND_EOL();
     push_int(0);
   }else{
diff --git a/src/svalue.c b/src/svalue.c
index c4be8fcc42..92202b3b38 100644
--- a/src/svalue.c
+++ b/src/svalue.c
@@ -62,7 +62,7 @@ static int pike_isnan(double x)
 #endif /* HAVE__ISNAN */
 #endif /* HAVE_ISNAN */
 
-RCSID("$Id: svalue.c,v 1.109 2001/07/01 21:34:51 mast Exp $");
+RCSID("$Id: svalue.c,v 1.110 2001/07/02 20:09:18 mast Exp $");
 
 struct svalue dest_ob_zero = {
   T_INT, 0,
@@ -487,7 +487,7 @@ PMOD_EXPORT unsigned INT32 hash_svalue(const struct svalue *s)
 
     if(FIND_LFUN(s->u.object->prog,LFUN___HASH) != -1)
     {
-      safe_apply_low(s->u.object, FIND_LFUN(s->u.object->prog,LFUN___HASH), 0);
+      safe_apply_low2(s->u.object, FIND_LFUN(s->u.object->prog,LFUN___HASH), 0, 1);
       if(sp[-1].type == T_INT)
       {
 	q=sp[-1].u.integer;
@@ -533,7 +533,7 @@ PMOD_EXPORT int svalue_is_true(const struct svalue *s)
 
     if(FIND_LFUN(s->u.object->prog,LFUN_NOT)!=-1)
     {
-      safe_apply_low(s->u.object,FIND_LFUN(s->u.object->prog,LFUN_NOT),0);
+      safe_apply_low2(s->u.object,FIND_LFUN(s->u.object->prog,LFUN_NOT),0,1);
       if(sp[-1].type == T_INT && sp[-1].u.integer == 0)
       {
 	pop_stack();
@@ -1076,7 +1076,7 @@ PMOD_EXPORT void describe_svalue(const struct svalue *s,int indent,struct proces
 	  push_constant_text("indent");
 	  push_int(indent);
 	  f_aggregate_mapping(2);					      
-	  safe_apply_low(s->u.object, fun ,2);
+	  safe_apply_low2(s->u.object, fun ,2,1);
 
 	  if(!IS_ZERO(sp-1))
 	  {
-- 
GitLab