From 861fb0d7d53e78304318700a77f934ae13d015d9 Mon Sep 17 00:00:00 2001 From: Peter Bourgon Date: Wed, 16 Sep 2015 22:28:18 +0200 Subject: [PATCH 1/3] common: cursor.Parse("123A") should not fail Fixes #37 --- common/cursor.go | 18 ++++++++++-------- common/cursor_test.go | 10 ++++++++++ 2 files changed, 20 insertions(+), 8 deletions(-) diff --git a/common/cursor.go b/common/cursor.go index c0bede3..e825445 100644 --- a/common/cursor.go +++ b/common/cursor.go @@ -7,6 +7,8 @@ import ( "io" "io/ioutil" "math" + "strconv" + "strings" ) // Cursor is used as part of SelectRange. @@ -50,19 +52,19 @@ func (c Cursor) Encode(w io.Writer) { // Parse parses the cursor string into the Cursor object. func (c *Cursor) Parse(s string) error { - var ( - score uint64 - member string - ) + fields := strings.SplitN(s, "A", 2) + if len(fields) != 2 { + return fmt.Errorf("invalid cursor string (%s)", s) + } - _, err := fmt.Fscanf(bytes.NewReader([]byte(s)), cursorFormat, &score, &member) + score, err := strconv.ParseUint(fields[0], 10, 64) if err != nil { - return fmt.Errorf("invalid cursor string (%s)", err) + return fmt.Errorf("invalid score in cursor string (%s)", err) } - decoded, err := ioutil.ReadAll(base64.NewDecoder(base64.URLEncoding, bytes.NewReader([]byte(member)))) + decoded, err := ioutil.ReadAll(base64.NewDecoder(base64.URLEncoding, bytes.NewReader([]byte(fields[1])))) if err != nil { - return fmt.Errorf("invalid cursor string (%s)", err) + return fmt.Errorf("invalid member in cursor string (%s)", err) } c.Score = math.Float64frombits(score) diff --git a/common/cursor_test.go b/common/cursor_test.go index 990b383..3d3e484 100644 --- a/common/cursor_test.go +++ b/common/cursor_test.go @@ -70,6 +70,16 @@ func TestCursorSafety(t *testing.T) { } } +func TestIssue37(t *testing.T) { + c := Cursor{} + if err := c.Parse("4743834931740803072A"); err != nil { + t.Fatal(err) + } + if want, have := "", c.Member; want != have { + t.Errorf("want %q, have %q", want, have) + } +} + func BenchmarkCursorString(b *testing.B) { var cursor = Cursor{Score: 1.23, Member: "abcdefg"} From 983baece6c3e3c74d386fb9afd3ab9d6fe21e5cc Mon Sep 17 00:00:00 2001 From: Peter Bourgon Date: Wed, 16 Sep 2015 22:34:14 +0200 Subject: [PATCH 2/3] .travis.yml: test on tip, 1.5, and 1.4; drop 1.2 --- .travis.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.travis.yml b/.travis.yml index 0da9483..db09fe7 100644 --- a/.travis.yml +++ b/.travis.yml @@ -2,8 +2,8 @@ language: go go: - tip - - 1.3 - - 1.2 + - 1.5 + - 1.4 services: - redis-server From 8c835b0ab1cb9bce102621ebe7424a64c5dfcd87 Mon Sep 17 00:00:00 2001 From: Peter Bourgon Date: Thu, 17 Sep 2015 09:54:36 +0200 Subject: [PATCH 3/3] tip needs this, I don't know why --- farm/repair_strategies_test.go | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/farm/repair_strategies_test.go b/farm/repair_strategies_test.go index d1e2e30..0afdad2 100644 --- a/farm/repair_strategies_test.go +++ b/farm/repair_strategies_test.go @@ -29,8 +29,14 @@ func TestAllRepairs(t *testing.T) { if i == 0 { expected = second } - if got := <-clusters[i].SelectOffset([]string{"foo"}, 0, 10); !reflect.DeepEqual(expected, got.KeyScoreMembers[0]) { + got := <-clusters[i].SelectOffset([]string{"foo"}, 0, 10) + if len(got.KeyScoreMembers) <= 0 { + t.Errorf("pre-repair: cluster %d: only got %d responses", i, len(got.KeyScoreMembers)) + continue + } + if !reflect.DeepEqual(expected, got.KeyScoreMembers[0]) { t.Errorf("pre-repair: cluster %d: expected %+v, got %+v", i, expected, got.KeyScoreMembers[0]) + continue } }