emacs-diffs
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

master a4610c3: * src/fns.c (sxhash_obj): Fix crash on sub-char-tables


From: Stefan Monnier
Subject: master a4610c3: * src/fns.c (sxhash_obj): Fix crash on sub-char-tables
Date: Sat, 18 Jan 2020 13:13:29 -0500 (EST)

branch: master
commit a4610c3dca09c526d7ca0647fe4a2abd08d081e7
Author: Stefan Monnier <address@hidden>
Commit: Stefan Monnier <address@hidden>

    * src/fns.c (sxhash_obj): Fix crash on sub-char-tables
    
    Also, look inside overlays, like `internal_equal`.
    
    (internal_equal): Cosmetic tweak.
---
 src/fns.c | 69 ++++++++++++++++++++++++++++-----------------------------------
 1 file changed, 31 insertions(+), 38 deletions(-)

diff --git a/src/fns.c b/src/fns.c
index 4a463a8..436ef1c 100644
--- a/src/fns.c
+++ b/src/fns.c
@@ -2460,12 +2460,9 @@ internal_equal (Lisp_Object o1, Lisp_Object o2, enum 
equal_kind equal_kind,
        if (BOOL_VECTOR_P (o1))
          {
            EMACS_INT size = bool_vector_size (o1);
-           if (size != bool_vector_size (o2))
-             return false;
-           if (memcmp (bool_vector_data (o1), bool_vector_data (o2),
-                       bool_vector_bytes (size)))
-             return false;
-           return true;
+           return (size == bool_vector_size (o2)
+                   && !memcmp (bool_vector_data (o1), bool_vector_data (o2),
+                               bool_vector_bytes (size)));
          }
 
        /* Aside from them, only true vectors, char-tables, compiled
@@ -2491,16 +2488,11 @@ internal_equal (Lisp_Object o1, Lisp_Object o2, enum 
equal_kind equal_kind,
       break;
 
     case Lisp_String:
-      if (SCHARS (o1) != SCHARS (o2))
-       return false;
-      if (SBYTES (o1) != SBYTES (o2))
-       return false;
-      if (memcmp (SDATA (o1), SDATA (o2), SBYTES (o1)))
-       return false;
-      if (equal_kind == EQUAL_INCLUDING_PROPERTIES
-         && !compare_string_intervals (o1, o2))
-       return false;
-      return true;
+      return (SCHARS (o1) == SCHARS (o2)
+             && SBYTES (o1) == SBYTES (o2)
+             && !memcmp (SDATA (o1), SDATA (o2), SBYTES (o1))
+             && (equal_kind != EQUAL_INCLUDING_PROPERTIES
+                 || compare_string_intervals (o1, o2)));
 
     default:
       break;
@@ -4681,24 +4673,19 @@ sxhash (Lisp_Object obj)
 static EMACS_UINT
 sxhash_obj (Lisp_Object obj, int depth)
 {
-  EMACS_UINT hash;
-
   if (depth > SXHASH_MAX_DEPTH)
     return 0;
 
   switch (XTYPE (obj))
     {
     case_Lisp_Int:
-      hash = XUFIXNUM (obj);
-      break;
+      return XUFIXNUM (obj);
 
     case Lisp_Symbol:
-      hash = XHASH (obj);
-      break;
+      return XHASH (obj);
 
     case Lisp_String:
-      hash = sxhash_string (SSDATA (obj), SBYTES (obj));
-      break;
+      return sxhash_string (SSDATA (obj), SBYTES (obj));
 
     case Lisp_Vectorlike:
       {
@@ -4710,40 +4697,46 @@ sxhash_obj (Lisp_Object obj, int depth)
               Emacs, this works differently.  We have to compare element
               by element.  Same for pseudovectors that internal_equal
               examines the Lisp contents of.  */
-           hash = sxhash_vector (obj, depth);
-           break;
+           return (SUB_CHAR_TABLE_P (obj)
+                   /* 'sxhash_vector' can't be applies to a sub-char-table and
+                     it's probably not worth looking into them anyway!  */
+                   ? 42
+                   : sxhash_vector (obj, depth));
          }
        else if (pvec_type == PVEC_BIGNUM)
-         hash = sxhash_bignum (obj);
+         return sxhash_bignum (obj);
        else if (pvec_type == PVEC_MARKER)
          {
            ptrdiff_t bytepos
              = XMARKER (obj)->buffer ? XMARKER (obj)->bytepos : 0;
-           hash = sxhash_combine ((intptr_t) XMARKER (obj)->buffer, bytepos);
-           hash = SXHASH_REDUCE (hash);
+           EMACS_UINT hash
+             = sxhash_combine ((intptr_t) XMARKER (obj)->buffer, bytepos);
+           return SXHASH_REDUCE (hash);
          }
        else if (pvec_type == PVEC_BOOL_VECTOR)
-         hash = sxhash_bool_vector (obj);
+         return sxhash_bool_vector (obj);
+       else if (pvec_type == PVEC_OVERLAY)
+         {
+           EMACS_UINT hash = sxhash_obj (OVERLAY_START (obj), depth);
+           hash = sxhash_combine (hash, sxhash_obj (OVERLAY_END (obj), depth));
+           hash = sxhash_combine (hash, sxhash_obj (XOVERLAY (obj)->plist, 
depth));
+           return SXHASH_REDUCE (hash);
+         }
        else
          /* Others are 'equal' if they are 'eq', so take their
             address as hash.  */
-         hash = XHASH (obj);
+         return XHASH (obj);
       }
-      break;
 
     case Lisp_Cons:
-      hash = sxhash_list (obj, depth);
-      break;
+      return sxhash_list (obj, depth);
 
     case Lisp_Float:
-      hash = sxhash_float (XFLOAT_DATA (obj));
-      break;
+      return sxhash_float (XFLOAT_DATA (obj));
 
     default:
       emacs_abort ();
     }
-
-  return hash;
 }
 
 



reply via email to

[Prev in Thread] Current Thread [Next in Thread]