Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Don't panic on indexed int64 fields #23

Merged
merged 8 commits into from
Sep 11, 2017
4 changes: 3 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,8 @@ Further PR's (with tests) are welcome, but please maintain backwards compatibili
* Improved multi-document transaction performance ([details](https://github.com/globalsign/mgo/pull/10), [more](https://github.com/globalsign/mgo/pull/11), [more](https://github.com/globalsign/mgo/pull/16))
* Fixes cursor timeouts ([details](https://jira.mongodb.org/browse/SERVER-24899))
* Support index hints and timeouts for count queries ([details](https://github.com/globalsign/mgo/pull/17))
* Allow dropping all indexes on a collection ([details](https://github.com/globalsign/mgo/pull/25))
* Don't panic when handling indexed `int64` fields ([detials](https://github.com/go-mgo/mgo/issues/475))
* Supports dropping all indexes on a collection ([details](https://github.com/globalsign/mgo/pull/25))
* Annotates log entries/profiler output with optional appName on 3.4+ ([details](https://github.com/globalsign/mgo/pull/28))

---
Expand All @@ -35,6 +36,7 @@ Further PR's (with tests) are welcome, but please maintain backwards compatibili
* @feliixx
* @fmpwizard
* @jameinel
* @mapete94
* @Reenjii
* @smoya
* @wgallagher
21 changes: 15 additions & 6 deletions session.go
Original file line number Diff line number Diff line change
Expand Up @@ -1659,12 +1659,25 @@ func (idxs indexSlice) Swap(i, j int) { idxs[i], idxs[j] = idxs[j], idxs[i]

func simpleIndexKey(realKey bson.D) (key []string) {
for i := range realKey {
var vi int
field := realKey[i].Name
vi, ok := realKey[i].Value.(int)
if !ok {

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I haven't checked the call site, but is downcasting int64 to in really necessary ? Mongo itself does handle 64bit integers IIRC.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For compatibility on 32 bit architectures I assume.

int is an int64 on 64 bit systems.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

After looking at the code properly, the only valid values are "1" and "-1" so casting isn't an issue.

switch realKey[i].Value.(type) {
case int64:
vf, _ := realKey[i].Value.(int64)
vi = int(vf)
case float64:
vf, _ := realKey[i].Value.(float64)
vi = int(vf)
case string:
if vs, ok := realKey[i].Value.(string); ok {
key = append(key, "$"+vs+":"+field)
continue
}
case int:
vi = realKey[i].Value.(int)
}

if vi == 1 {
key = append(key, field)
continue
Expand All @@ -1673,10 +1686,6 @@ func simpleIndexKey(realKey bson.D) (key []string) {
key = append(key, "-"+field)
continue
}
if vs, ok := realKey[i].Value.(string); ok {
key = append(key, "$"+vs+":"+field)
continue
}
panic("Got unknown index key type for field " + field)
}
return
Expand Down
24 changes: 24 additions & 0 deletions session_internal_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
package mgo

import (
"testing"

"github.com/globalsign/mgo/bson"
)

// This file is for testing functions that are not exported outside the mgo
// package - avoid doing so if at all possible.

// Ensures indexed int64 fields do not cause mgo to panic.
//
// See https://github.com/globalsign/mgo/pull/23
func TestIndexedInt64FieldsBug(t *testing.T) {
input := bson.D{
{Name: "testkey", Value: int(1)},
{Name: "testkey", Value: int64(1)},
{Name: "testkey", Value: "test"},
{Name: "testkey", Value: float64(1)},
}

_ = simpleIndexKey(input)
}