Skip to content
This repository has been archived by the owner on Dec 14, 2020. It is now read-only.

Commit

Permalink
Fix Incorrect time calculation for dates before the Unix epoch
Browse files Browse the repository at this point in the history
AMQP timestamp is a signed value, but decoded from buffer as unsigned.
The previous code took the remainder of the unsigned value before
converting to signed.
  • Loading branch information
alanconway authored and vcabbage committed Sep 20, 2019
1 parent 5f7db87 commit 7c41f1a
Show file tree
Hide file tree
Showing 2 changed files with 20 additions and 2 deletions.
4 changes: 2 additions & 2 deletions decode.go
Original file line number Diff line number Diff line change
Expand Up @@ -946,8 +946,8 @@ func readTimestamp(r *buffer) (time.Time, error) {
}

n, err := r.readUint64()
rem := n % 1000
return time.Unix(int64(n)/1000, int64(rem)*1000000).UTC(), err
ms := int64(n)
return time.Unix(ms/1000, (ms%1000)*1000000).UTC(), err
}

func readInt(r *buffer) (int, error) {
Expand Down
18 changes: 18 additions & 0 deletions marshal_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -212,6 +212,24 @@ func TestMarshalUnmarshal(t *testing.T) {
}
}

// Regression test for time calculation bug.
// https://github.com/vcabbage/amqp/issues/173
func TestIssue173(t *testing.T) {
var buf buffer
// NOTE: Dates after the Unix Epoch don't trigger the bug, only
// dates that negative Unix time show the problem.
want := time.Date(1969, 03, 21, 0, 0, 0, 0, time.UTC)
err := marshal(&buf, want)
if err != nil {
t.Fatal(err)
}
var got time.Time
err = unmarshal(&buf, &got)
if d := testDiff(want, got); d != "" {
t.Fatal(d)
}
}

func TestReadAny(t *testing.T) {
for _, type_ := range generalTypes {
t.Run(fmt.Sprintf("%T", type_), func(t *testing.T) {
Expand Down

0 comments on commit 7c41f1a

Please sign in to comment.