Skip to content

Commit 5262a76

Browse files
author
Divjot Arora
authored
GODRIVER-1506 Fix error checking for invalid extjson timestamp values (mongodb#337)
1 parent a794f53 commit 5262a76

File tree

2 files changed

+53
-6
lines changed

2 files changed

+53
-6
lines changed

bson/bsonrw/extjson_wrappers.go

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -430,17 +430,20 @@ func (ejv *extJSONValue) parseTimestamp() (t, i uint32, err error) {
430430

431431
switch val.t {
432432
case bsontype.Int32:
433-
if val.v.(int32) < 0 {
434-
return 0, fmt.Errorf("$timestamp %s number should be uint32: %s", key, string(val.v.(int32)))
433+
value := val.v.(int32)
434+
435+
if value < 0 {
436+
return 0, fmt.Errorf("$timestamp %s number should be uint32: %d", key, value)
435437
}
436438

437-
return uint32(val.v.(int32)), nil
439+
return uint32(value), nil
438440
case bsontype.Int64:
439-
if val.v.(int64) < 0 || uint32(val.v.(int64)) > math.MaxUint32 {
440-
return 0, fmt.Errorf("$timestamp %s number should be uint32: %s", key, string(val.v.(int32)))
441+
value := val.v.(int64)
442+
if value < 0 || value > int64(math.MaxUint32) {
443+
return 0, fmt.Errorf("$timestamp %s number should be uint32: %d", key, value)
441444
}
442445

443-
return uint32(val.v.(int64)), nil
446+
return uint32(value), nil
444447
default:
445448
return 0, fmt.Errorf("$timestamp %s value should be uint32, but instead is %s", key, val.t)
446449
}

bson/extjson_prose_test.go

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
// Copyright (C) MongoDB, Inc. 2017-present.
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License"); you may
4+
// not use this file except in compliance with the License. You may obtain
5+
// a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
6+
7+
package bson
8+
9+
import (
10+
"fmt"
11+
"testing"
12+
13+
"go.mongodb.org/mongo-driver/internal/testutil/assert"
14+
)
15+
16+
func TestExtJSON(t *testing.T) {
17+
timestampNegativeInt32Err := fmt.Errorf("$timestamp i number should be uint32: -1")
18+
timestampNegativeInt64Err := fmt.Errorf("$timestamp i number should be uint32: -2147483649")
19+
timestampLargeValueErr := fmt.Errorf("$timestamp i number should be uint32: 4294967296")
20+
21+
testCases := []struct {
22+
name string
23+
input string
24+
canonical bool
25+
err error
26+
}{
27+
{"timestamp - negative int32 value", `{"":{"$timestamp":{"t":0,"i":-1}}}`, false, timestampNegativeInt32Err},
28+
{"timestamp - negative int64 value", `{"":{"$timestamp":{"t":0,"i":-2147483649}}}`, false, timestampNegativeInt64Err},
29+
{"timestamp - value overflows uint32", `{"":{"$timestamp":{"t":0,"i":4294967296}}}`, false, timestampLargeValueErr},
30+
}
31+
for _, tc := range testCases {
32+
t.Run(tc.name, func(t *testing.T) {
33+
var res Raw
34+
err := UnmarshalExtJSON([]byte(tc.input), tc.canonical, &res)
35+
if tc.err == nil {
36+
assert.Nil(t, err, "UnmarshalExtJSON error: %v", err)
37+
return
38+
}
39+
40+
assert.NotNil(t, err, "expected error %v, got nil", tc.err)
41+
assert.Equal(t, tc.err.Error(), err.Error(), "expected error %v, got %v", tc.err, err)
42+
})
43+
}
44+
}

0 commit comments

Comments
 (0)