aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorStefan Monnier2020-01-18 13:13:21 -0500
committerStefan Monnier2020-01-18 13:13:21 -0500
commita4610c3dca09c526d7ca0647fe4a2abd08d081e7 (patch)
tree158d82d260256b8fba2ac2bce8e583272c5d8ea5
parent1787b86b89b8973151980cbef115a6584f477509 (diff)
downloademacs-a4610c3dca09c526d7ca0647fe4a2abd08d081e7.tar.gz
emacs-a4610c3dca09c526d7ca0647fe4a2abd08d081e7.zip
* src/fns.c (sxhash_obj): Fix crash on sub-char-tables
Also, look inside overlays, like `internal_equal`. (internal_equal): Cosmetic tweak.
-rw-r--r--src/fns.c69
1 files changed, 31 insertions, 38 deletions
diff --git a/src/fns.c b/src/fns.c
index 4a463a8feb2..436ef1c7b74 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,
2460 if (BOOL_VECTOR_P (o1)) 2460 if (BOOL_VECTOR_P (o1))
2461 { 2461 {
2462 EMACS_INT size = bool_vector_size (o1); 2462 EMACS_INT size = bool_vector_size (o1);
2463 if (size != bool_vector_size (o2)) 2463 return (size == bool_vector_size (o2)
2464 return false; 2464 && !memcmp (bool_vector_data (o1), bool_vector_data (o2),
2465 if (memcmp (bool_vector_data (o1), bool_vector_data (o2), 2465 bool_vector_bytes (size)));
2466 bool_vector_bytes (size)))
2467 return false;
2468 return true;
2469 } 2466 }
2470 2467
2471 /* Aside from them, only true vectors, char-tables, compiled 2468 /* 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,
2491 break; 2488 break;
2492 2489
2493 case Lisp_String: 2490 case Lisp_String:
2494 if (SCHARS (o1) != SCHARS (o2)) 2491 return (SCHARS (o1) == SCHARS (o2)
2495 return false; 2492 && SBYTES (o1) == SBYTES (o2)
2496 if (SBYTES (o1) != SBYTES (o2)) 2493 && !memcmp (SDATA (o1), SDATA (o2), SBYTES (o1))
2497 return false; 2494 && (equal_kind != EQUAL_INCLUDING_PROPERTIES
2498 if (memcmp (SDATA (o1), SDATA (o2), SBYTES (o1))) 2495 || compare_string_intervals (o1, o2)));
2499 return false;
2500 if (equal_kind == EQUAL_INCLUDING_PROPERTIES
2501 && !compare_string_intervals (o1, o2))
2502 return false;
2503 return true;
2504 2496
2505 default: 2497 default:
2506 break; 2498 break;
@@ -4681,24 +4673,19 @@ sxhash (Lisp_Object obj)
4681static EMACS_UINT 4673static EMACS_UINT
4682sxhash_obj (Lisp_Object obj, int depth) 4674sxhash_obj (Lisp_Object obj, int depth)
4683{ 4675{
4684 EMACS_UINT hash;
4685
4686 if (depth > SXHASH_MAX_DEPTH) 4676 if (depth > SXHASH_MAX_DEPTH)
4687 return 0; 4677 return 0;
4688 4678
4689 switch (XTYPE (obj)) 4679 switch (XTYPE (obj))
4690 { 4680 {
4691 case_Lisp_Int: 4681 case_Lisp_Int:
4692 hash = XUFIXNUM (obj); 4682 return XUFIXNUM (obj);
4693 break;
4694 4683
4695 case Lisp_Symbol: 4684 case Lisp_Symbol:
4696 hash = XHASH (obj); 4685 return XHASH (obj);
4697 break;
4698 4686
4699 case Lisp_String: 4687 case Lisp_String:
4700 hash = sxhash_string (SSDATA (obj), SBYTES (obj)); 4688 return sxhash_string (SSDATA (obj), SBYTES (obj));
4701 break;
4702 4689
4703 case Lisp_Vectorlike: 4690 case Lisp_Vectorlike:
4704 { 4691 {
@@ -4710,40 +4697,46 @@ sxhash_obj (Lisp_Object obj, int depth)
4710 Emacs, this works differently. We have to compare element 4697 Emacs, this works differently. We have to compare element
4711 by element. Same for pseudovectors that internal_equal 4698 by element. Same for pseudovectors that internal_equal
4712 examines the Lisp contents of. */ 4699 examines the Lisp contents of. */
4713 hash = sxhash_vector (obj, depth); 4700 return (SUB_CHAR_TABLE_P (obj)
4714 break; 4701 /* 'sxhash_vector' can't be applies to a sub-char-table and
4702 it's probably not worth looking into them anyway! */
4703 ? 42
4704 : sxhash_vector (obj, depth));
4715 } 4705 }
4716 else if (pvec_type == PVEC_BIGNUM) 4706 else if (pvec_type == PVEC_BIGNUM)
4717 hash = sxhash_bignum (obj); 4707 return sxhash_bignum (obj);
4718 else if (pvec_type == PVEC_MARKER) 4708 else if (pvec_type == PVEC_MARKER)
4719 { 4709 {
4720 ptrdiff_t bytepos 4710 ptrdiff_t bytepos
4721 = XMARKER (obj)->buffer ? XMARKER (obj)->bytepos : 0; 4711 = XMARKER (obj)->buffer ? XMARKER (obj)->bytepos : 0;
4722 hash = sxhash_combine ((intptr_t) XMARKER (obj)->buffer, bytepos); 4712 EMACS_UINT hash
4723 hash = SXHASH_REDUCE (hash); 4713 = sxhash_combine ((intptr_t) XMARKER (obj)->buffer, bytepos);
4714 return SXHASH_REDUCE (hash);
4724 } 4715 }
4725 else if (pvec_type == PVEC_BOOL_VECTOR) 4716 else if (pvec_type == PVEC_BOOL_VECTOR)
4726 hash = sxhash_bool_vector (obj); 4717 return sxhash_bool_vector (obj);
4718 else if (pvec_type == PVEC_OVERLAY)
4719 {
4720 EMACS_UINT hash = sxhash_obj (OVERLAY_START (obj), depth);
4721 hash = sxhash_combine (hash, sxhash_obj (OVERLAY_END (obj), depth));
4722 hash = sxhash_combine (hash, sxhash_obj (XOVERLAY (obj)->plist, depth));
4723 return SXHASH_REDUCE (hash);
4724 }
4727 else 4725 else
4728 /* Others are 'equal' if they are 'eq', so take their 4726 /* Others are 'equal' if they are 'eq', so take their
4729 address as hash. */ 4727 address as hash. */
4730 hash = XHASH (obj); 4728 return XHASH (obj);
4731 } 4729 }
4732 break;
4733 4730
4734 case Lisp_Cons: 4731 case Lisp_Cons:
4735 hash = sxhash_list (obj, depth); 4732 return sxhash_list (obj, depth);
4736 break;
4737 4733
4738 case Lisp_Float: 4734 case Lisp_Float:
4739 hash = sxhash_float (XFLOAT_DATA (obj)); 4735 return sxhash_float (XFLOAT_DATA (obj));
4740 break;
4741 4736
4742 default: 4737 default:
4743 emacs_abort (); 4738 emacs_abort ();
4744 } 4739 }
4745
4746 return hash;
4747} 4740}
4748 4741
4749 4742