From 3635f824cc13883a1c09c59a195fc644358f487c Mon Sep 17 00:00:00 2001
From: "Tobias S. Josefowitz" <tobij@tobij.de>
Date: Sat, 11 Jan 2014 20:09:47 -0500
Subject: [PATCH] svalue: prevent shift overflow when building typefield

---
 src/array.c  | 2 +-
 src/svalue.c | 8 ++++----
 src/svalue.h | 8 ++++++++
 3 files changed, 13 insertions(+), 5 deletions(-)

diff --git a/src/array.c b/src/array.c
index 29e4bda211..eaae9a7e4f 100644
--- a/src/array.c
+++ b/src/array.c
@@ -1428,7 +1428,7 @@ PMOD_EXPORT TYPE_FIELD array_fix_type_field(struct array *v)
 
   for(e=0; e<v->size; e++) {
     check_svalue (ITEM(v) + e);
-    t |= 1 << TYPEOF(ITEM(v)[e]);
+    t |= BITOF(ITEM(v)[e]);
   }
 
 #ifdef PIKE_DEBUG
diff --git a/src/svalue.c b/src/svalue.c
index 0f32235318..dc784ba1da 100644
--- a/src/svalue.c
+++ b/src/svalue.c
@@ -2344,7 +2344,7 @@ PMOD_EXPORT TYPE_FIELD real_gc_mark_svalues(struct svalue *s, size_t num)
 		      GC_DO_MARK, MARK_PRE,
 		      DO_MARK_FUNC_SVALUE, GC_DO_MARK,
 		      DO_MARK_STRING, GC_DO_MARK);
-    t |= 1 << TYPEOF(*s);
+    t |= BITOF(*s);
   }
   return freed ? t : 0;
 }
@@ -2361,7 +2361,7 @@ TYPE_FIELD gc_mark_weak_svalues(struct svalue *s, size_t num)
 		      GC_DONT_MARK, MARK_PRE,
 		      DO_MARK_FUNC_SVALUE, DO_MARK_OBJ_WEAK,
 		      DO_MARK_STRING, GC_DO_MARK);
-    t |= 1 << TYPEOF(*s);
+    t |= BITOF(*s);
   }
   return freed ? t : 0;
 }
@@ -2440,7 +2440,7 @@ PMOD_EXPORT TYPE_FIELD real_gc_cycle_check_svalues(struct svalue *s, size_t num)
 		      DO_CYCLE_CHECK, {},
 		      DO_CYCLE_CHECK_FUNC_SVALUE, DO_CYCLE_CHECK,
 		      DONT_CYCLE_CHECK_STRING, DONT_CYCLE_CHECK);
-    t |= 1 << TYPEOF(*s);
+    t |= BITOF(*s);
   }
   return freed ? t : 0;
 }
@@ -2457,7 +2457,7 @@ TYPE_FIELD gc_cycle_check_weak_svalues(struct svalue *s, size_t num)
 		      DO_CYCLE_CHECK_WEAK, {},
 		      DO_CYCLE_CHECK_FUNC_SVALUE, DO_CYCLE_CHECK_WEAK,
 		      DONT_CYCLE_CHECK_STRING, DONT_CYCLE_CHECK);
-    t |= 1 << TYPEOF(*s);
+    t |= BITOF(*s);
   }
   return freed ? t : 0;
 }
diff --git a/src/svalue.h b/src/svalue.h
index 247d8f0378..6a183a4c31 100644
--- a/src/svalue.h
+++ b/src/svalue.h
@@ -847,6 +847,14 @@ int svalues_are_constant(const struct svalue *s,
 			 TYPE_FIELD hint,
 			 struct processing *p);
 
+static INLINE TYPE_FIELD BITOF(struct svalue sv) {
+    if (TYPEOF(sv) >= sizeof(TYPE_FIELD) * 8) {
+        return BIT_MIXED | BIT_UNFINISHED;
+    }
+
+    return 1 << TYPEOF(sv);
+}
+
 #define gc_cycle_check_without_recurse gc_mark_without_recurse
 #define gc_cycle_check_weak_without_recurse gc_mark_without_recurse
 
-- 
GitLab