From 17b31925feb6e14159c9583f4ac9d26c01f3e16c Mon Sep 17 00:00:00 2001 From: Trevor Pounds Date: Thu, 23 Apr 2015 09:23:33 -0700 Subject: [PATCH] Prevent negative hashcodes for all set operations. --- helper/schema/set.go | 18 ++++++++++++------ helper/schema/set_test.go | 4 ++++ 2 files changed, 16 insertions(+), 6 deletions(-) diff --git a/helper/schema/set.go b/helper/schema/set.go index a10c2b8d95..fbfd789874 100644 --- a/helper/schema/set.go +++ b/helper/schema/set.go @@ -34,7 +34,7 @@ func (s *Set) Add(item interface{}) { // Contains checks if the set has the given item. func (s *Set) Contains(item interface{}) bool { - _, ok := s.m[s.F(item)] + _, ok := s.m[s.hash(item)] return ok } @@ -122,10 +122,7 @@ func (s *Set) init() { func (s *Set) add(item interface{}) int { s.once.Do(s.init) - code := s.F(item) - if code < 0 { - code *= -1 - } + code := s.hash(item) if _, ok := s.m[code]; !ok { s.m[code] = item } @@ -133,8 +130,17 @@ func (s *Set) add(item interface{}) int { return code } +func (s *Set) hash(item interface{}) int { + code := s.F(item) + // Always return a nonnegative hashcode. + if code < 0 { + return -code + } + return code +} + func (s *Set) index(item interface{}) int { - return sort.SearchInts(s.listCode(), s.F(item)) + return sort.SearchInts(s.listCode(), s.hash(item)) } func (s *Set) listCode() []int { diff --git a/helper/schema/set_test.go b/helper/schema/set_test.go index 9688c5f715..8717735550 100644 --- a/helper/schema/set_test.go +++ b/helper/schema/set_test.go @@ -35,6 +35,7 @@ func TestSetAdd_negative(t *testing.T) { func TestSetContains(t *testing.T) { s := &Set{F: testSetInt} s.Add(5) + s.Add(-5) if s.Contains(2) { t.Fatal("should not contain") @@ -42,6 +43,9 @@ func TestSetContains(t *testing.T) { if !s.Contains(5) { t.Fatal("should contain") } + if !s.Contains(-5) { + t.Fatal("should contain") + } } func TestSetDifference(t *testing.T) {