forked from mirror/go.uuid
Fix potential non-random UUIDs
Use ReadFull to fetch random bytes from crypto/rand instead of calling Read directly as Read may read less bytes than asked. Fix satori/go.uuid#73
This commit is contained in:
parent
36e9d2ebbd
commit
75cca531ea
|
@ -165,7 +165,7 @@ func (g *rfc4122Generator) NewV3(ns UUID, name string) UUID {
|
|||
// NewV4 returns random generated UUID.
|
||||
func (g *rfc4122Generator) NewV4() (UUID, error) {
|
||||
u := UUID{}
|
||||
if _, err := g.rand.Read(u[:]); err != nil {
|
||||
if _, err := io.ReadFull(g.rand, u[:]); err != nil {
|
||||
return Nil, err
|
||||
}
|
||||
u.SetVersion(V4)
|
||||
|
@ -188,7 +188,7 @@ func (g *rfc4122Generator) getClockSequence() (uint64, uint16, error) {
|
|||
var err error
|
||||
g.clockSequenceOnce.Do(func() {
|
||||
buf := make([]byte, 2)
|
||||
if _, err = g.rand.Read(buf); err != nil {
|
||||
if _, err = io.ReadFull(g.rand, buf); err != nil {
|
||||
return
|
||||
}
|
||||
g.clockSequence = binary.BigEndian.Uint16(buf)
|
||||
|
@ -222,7 +222,7 @@ func (g *rfc4122Generator) getHardwareAddr() ([]byte, error) {
|
|||
|
||||
// Initialize hardwareAddr randomly in case
|
||||
// of real network interfaces absence.
|
||||
if _, err = g.rand.Read(g.hardwareAddr[:]); err != nil {
|
||||
if _, err = io.ReadFull(g.rand, g.hardwareAddr[:]); err != nil {
|
||||
return
|
||||
}
|
||||
// Set multicast bit as recommended by RFC 4122
|
||||
|
|
|
@ -22,9 +22,11 @@
|
|||
package uuid
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"crypto/rand"
|
||||
"fmt"
|
||||
"net"
|
||||
"testing/iotest"
|
||||
"time"
|
||||
|
||||
. "gopkg.in/check.v1"
|
||||
|
@ -195,6 +197,20 @@ func (s *genTestSuite) TestNewV4FaultyRand(c *C) {
|
|||
c.Assert(u1, Equals, Nil)
|
||||
}
|
||||
|
||||
func (s *genTestSuite) TestNewV4PartialRead(c *C) {
|
||||
g := &rfc4122Generator{
|
||||
epochFunc: time.Now,
|
||||
hwAddrFunc: defaultHWAddrFunc,
|
||||
rand: iotest.OneByteReader(rand.Reader),
|
||||
}
|
||||
u1, err := g.NewV4()
|
||||
zeros := bytes.Count(u1.Bytes(), []byte{0})
|
||||
mostlyZeros := zeros >= 10
|
||||
|
||||
c.Assert(err, IsNil)
|
||||
c.Assert(mostlyZeros, Equals, false)
|
||||
}
|
||||
|
||||
func (s *genTestSuite) BenchmarkNewV4(c *C) {
|
||||
for i := 0; i < c.N; i++ {
|
||||
NewV4()
|
||||
|
|
Loading…
Reference in New Issue