diff --git a/Gopkg.lock b/Gopkg.lock index fffbef5..81e1f69 100644 --- a/Gopkg.lock +++ b/Gopkg.lock @@ -85,12 +85,12 @@ version = "v1.4.1" [[projects]] - digest = "1:274f67cb6fed9588ea2521ecdac05a6d62a8c51c074c1fccc6a49a40ba80e925" + branch = "master" + digest = "1:a3b8912deeef29007fab9a13a9f21b9e9b59c621a2ed61e2fe7b37320a71fbd5" name = "github.com/satori/go.uuid" packages = ["."] pruneopts = "UT" - revision = "f58768cc1a7a7e77a3bd49e98cdd21419399b6a3" - version = "v1.2.0" + revision = "b2ce2384e17bbe0c6d34077efa39dbab3e09123b" [[projects]] digest = "1:2cab41f59638fdb77dda96ab4f9b5860ef30f48967557254eba127e43c756f2e" diff --git a/Gopkg.toml b/Gopkg.toml index 6e6ea9d..09e25f8 100644 --- a/Gopkg.toml +++ b/Gopkg.toml @@ -50,6 +50,10 @@ name = "github.com/tidwall/gjson" version = "1.1.3" +[[override]] + name = "github.com/satori/go.uuid" + branch = "master" + [prune] go-tests = true unused-packages = true diff --git a/article/vendor b/article/vendor new file mode 120000 index 0000000..9c39cc9 --- /dev/null +++ b/article/vendor @@ -0,0 +1 @@ +../vendor \ No newline at end of file diff --git a/vendor/github.com/satori/go.uuid/.travis.yml b/vendor/github.com/satori/go.uuid/.travis.yml index 20dd53b..acf8201 100644 --- a/vendor/github.com/satori/go.uuid/.travis.yml +++ b/vendor/github.com/satori/go.uuid/.travis.yml @@ -1,14 +1,12 @@ language: go sudo: false go: - - 1.2 - - 1.3 - - 1.4 - - 1.5 - - 1.6 - - 1.7 - - 1.8 - - 1.9 + - 1.6.x + - 1.7.x + - 1.8.x + - 1.9.x + - 1.10.x + - 1.11.x - tip matrix: allow_failures: diff --git a/vendor/github.com/satori/go.uuid/README.md b/vendor/github.com/satori/go.uuid/README.md index 7b1a722..362b270 100644 --- a/vendor/github.com/satori/go.uuid/README.md +++ b/vendor/github.com/satori/go.uuid/README.md @@ -1,8 +1,8 @@ # UUID package for Go language -[![Build Status](https://travis-ci.org/satori/go.uuid.png?branch=master)](https://travis-ci.org/satori/go.uuid) +[![Build Status](https://travis-ci.org/satori/go.uuid.svg?branch=master)](https://travis-ci.org/satori/go.uuid) [![Coverage Status](https://coveralls.io/repos/github/satori/go.uuid/badge.svg?branch=master)](https://coveralls.io/github/satori/go.uuid) -[![GoDoc](http://godoc.org/github.com/satori/go.uuid?status.png)](http://godoc.org/github.com/satori/go.uuid) +[![GoDoc](http://godoc.org/github.com/satori/go.uuid?status.svg)](http://godoc.org/github.com/satori/go.uuid) This package provides pure Go implementation of Universally Unique Identifier (UUID). Supported both creation and parsing of UUIDs. @@ -23,7 +23,7 @@ Use the `go` command: ## Requirements -UUID package requires Go >= 1.2. +UUID package tested against Go >= 1.6. ## Example @@ -37,13 +37,23 @@ import ( func main() { // Creating UUID Version 4 - u1 := uuid.NewV4() + // panic on error + u1 := uuid.Must(uuid.NewV4()) fmt.Printf("UUIDv4: %s\n", u1) + // or error handling + u2, err := uuid.NewV4() + if err != nil { + fmt.Printf("Something went wrong: %s", err) + return + } + fmt.Printf("UUIDv4: %s\n", u2) + // Parsing UUID from string input u2, err := uuid.FromString("6ba7b810-9dad-11d1-80b4-00c04fd430c8") if err != nil { - fmt.Printf("Something gone wrong: %s", err) + fmt.Printf("Something went wrong: %s", err) + return } fmt.Printf("Successfully parsed: %s", u2) } diff --git a/vendor/github.com/satori/go.uuid/generator.go b/vendor/github.com/satori/go.uuid/generator.go index 3f2f1da..c50d33c 100644 --- a/vendor/github.com/satori/go.uuid/generator.go +++ b/vendor/github.com/satori/go.uuid/generator.go @@ -26,7 +26,9 @@ import ( "crypto/rand" "crypto/sha1" "encoding/binary" + "fmt" "hash" + "io" "net" "os" "sync" @@ -37,21 +39,23 @@ import ( // UUID epoch (October 15, 1582) and Unix epoch (January 1, 1970). const epochStart = 122192928000000000 -var ( - global = newDefaultGenerator() +type epochFunc func() time.Time +type hwAddrFunc func() (net.HardwareAddr, error) - epochFunc = unixTimeFunc - posixUID = uint32(os.Getuid()) - posixGID = uint32(os.Getgid()) +var ( + global = newRFC4122Generator() + + posixUID = uint32(os.Getuid()) + posixGID = uint32(os.Getgid()) ) // NewV1 returns UUID based on current timestamp and MAC address. -func NewV1() UUID { +func NewV1() (UUID, error) { return global.NewV1() } // NewV2 returns DCE Security UUID based on POSIX UID/GID. -func NewV2(domain byte) UUID { +func NewV2(domain byte) (UUID, error) { return global.NewV2(domain) } @@ -61,7 +65,7 @@ func NewV3(ns UUID, name string) UUID { } // NewV4 returns random generated UUID. -func NewV4() UUID { +func NewV4() (UUID, error) { return global.NewV4() } @@ -72,74 +76,85 @@ func NewV5(ns UUID, name string) UUID { // Generator provides interface for generating UUIDs. type Generator interface { - NewV1() UUID - NewV2(domain byte) UUID + NewV1() (UUID, error) + NewV2(domain byte) (UUID, error) NewV3(ns UUID, name string) UUID - NewV4() UUID + NewV4() (UUID, error) NewV5(ns UUID, name string) UUID } // Default generator implementation. -type generator struct { - storageOnce sync.Once - storageMutex sync.Mutex +type rfc4122Generator struct { + clockSequenceOnce sync.Once + hardwareAddrOnce sync.Once + storageMutex sync.Mutex + rand io.Reader + + epochFunc epochFunc + hwAddrFunc hwAddrFunc lastTime uint64 clockSequence uint16 hardwareAddr [6]byte } -func newDefaultGenerator() Generator { - return &generator{} +func newRFC4122Generator() Generator { + return &rfc4122Generator{ + epochFunc: time.Now, + hwAddrFunc: defaultHWAddrFunc, + rand: rand.Reader, + } } // NewV1 returns UUID based on current timestamp and MAC address. -func (g *generator) NewV1() UUID { +func (g *rfc4122Generator) NewV1() (UUID, error) { u := UUID{} - timeNow, clockSeq, hardwareAddr := g.getStorage() - + timeNow, clockSeq, err := g.getClockSequence() + if err != nil { + return Nil, err + } binary.BigEndian.PutUint32(u[0:], uint32(timeNow)) binary.BigEndian.PutUint16(u[4:], uint16(timeNow>>32)) binary.BigEndian.PutUint16(u[6:], uint16(timeNow>>48)) binary.BigEndian.PutUint16(u[8:], clockSeq) + hardwareAddr, err := g.getHardwareAddr() + if err != nil { + return Nil, err + } copy(u[10:], hardwareAddr) u.SetVersion(V1) u.SetVariant(VariantRFC4122) - return u + return u, nil } // NewV2 returns DCE Security UUID based on POSIX UID/GID. -func (g *generator) NewV2(domain byte) UUID { - u := UUID{} - - timeNow, clockSeq, hardwareAddr := g.getStorage() +func (g *rfc4122Generator) NewV2(domain byte) (UUID, error) { + u, err := g.NewV1() + if err != nil { + return Nil, err + } switch domain { case DomainPerson: - binary.BigEndian.PutUint32(u[0:], posixUID) + binary.BigEndian.PutUint32(u[:], posixUID) case DomainGroup: - binary.BigEndian.PutUint32(u[0:], posixGID) + binary.BigEndian.PutUint32(u[:], posixGID) } - binary.BigEndian.PutUint16(u[4:], uint16(timeNow>>32)) - binary.BigEndian.PutUint16(u[6:], uint16(timeNow>>48)) - binary.BigEndian.PutUint16(u[8:], clockSeq) u[9] = domain - copy(u[10:], hardwareAddr) - u.SetVersion(V2) u.SetVariant(VariantRFC4122) - return u + return u, nil } // NewV3 returns UUID based on MD5 hash of namespace UUID and name. -func (g *generator) NewV3(ns UUID, name string) UUID { +func (g *rfc4122Generator) NewV3(ns UUID, name string) UUID { u := newFromHash(md5.New(), ns, name) u.SetVersion(V3) u.SetVariant(VariantRFC4122) @@ -148,17 +163,19 @@ func (g *generator) NewV3(ns UUID, name string) UUID { } // NewV4 returns random generated UUID. -func (g *generator) NewV4() UUID { +func (g *rfc4122Generator) NewV4() (UUID, error) { u := UUID{} - g.safeRandom(u[:]) + if _, err := io.ReadFull(g.rand, u[:]); err != nil { + return Nil, err + } u.SetVersion(V4) u.SetVariant(VariantRFC4122) - return u + return u, nil } // NewV5 returns UUID based on SHA-1 hash of namespace UUID and name. -func (g *generator) NewV5(ns UUID, name string) UUID { +func (g *rfc4122Generator) NewV5(ns UUID, name string) UUID { u := newFromHash(sha1.New(), ns, name) u.SetVersion(V5) u.SetVariant(VariantRFC4122) @@ -166,66 +183,61 @@ func (g *generator) NewV5(ns UUID, name string) UUID { return u } -func (g *generator) initStorage() { - g.initClockSequence() - g.initHardwareAddr() -} - -func (g *generator) initClockSequence() { - buf := make([]byte, 2) - g.safeRandom(buf) - g.clockSequence = binary.BigEndian.Uint16(buf) -} - -func (g *generator) initHardwareAddr() { - interfaces, err := net.Interfaces() - if err == nil { - for _, iface := range interfaces { - if len(iface.HardwareAddr) >= 6 { - copy(g.hardwareAddr[:], iface.HardwareAddr) - return - } +// Returns epoch and clock sequence. +func (g *rfc4122Generator) getClockSequence() (uint64, uint16, error) { + var err error + g.clockSequenceOnce.Do(func() { + buf := make([]byte, 2) + if _, err = io.ReadFull(g.rand, buf); err != nil { + return } + g.clockSequence = binary.BigEndian.Uint16(buf) + }) + if err != nil { + return 0, 0, err } - // Initialize hardwareAddr randomly in case - // of real network interfaces absence - g.safeRandom(g.hardwareAddr[:]) - - // Set multicast bit as recommended in RFC 4122 - g.hardwareAddr[0] |= 0x01 -} - -func (g *generator) safeRandom(dest []byte) { - if _, err := rand.Read(dest); err != nil { - panic(err) - } -} - -// Returns UUID v1/v2 storage state. -// Returns epoch timestamp, clock sequence, and hardware address. -func (g *generator) getStorage() (uint64, uint16, []byte) { - g.storageOnce.Do(g.initStorage) - g.storageMutex.Lock() defer g.storageMutex.Unlock() - timeNow := epochFunc() - // Clock changed backwards since last UUID generation. + timeNow := g.getEpoch() + // Clock didn't change since last UUID generation. // Should increase clock sequence. if timeNow <= g.lastTime { g.clockSequence++ } g.lastTime = timeNow - return timeNow, g.clockSequence, g.hardwareAddr[:] + return timeNow, g.clockSequence, nil +} + +// Returns hardware address. +func (g *rfc4122Generator) getHardwareAddr() ([]byte, error) { + var err error + g.hardwareAddrOnce.Do(func() { + if hwAddr, err := g.hwAddrFunc(); err == nil { + copy(g.hardwareAddr[:], hwAddr) + return + } + + // Initialize hardwareAddr randomly in case + // of real network interfaces absence. + if _, err = io.ReadFull(g.rand, g.hardwareAddr[:]); err != nil { + return + } + // Set multicast bit as recommended by RFC 4122 + g.hardwareAddr[0] |= 0x01 + }) + if err != nil { + return []byte{}, err + } + return g.hardwareAddr[:], nil } // Returns difference in 100-nanosecond intervals between // UUID epoch (October 15, 1582) and current time. -// This is default epoch calculation function. -func unixTimeFunc() uint64 { - return epochStart + uint64(time.Now().UnixNano()/100) +func (g *rfc4122Generator) getEpoch() uint64 { + return epochStart + uint64(g.epochFunc().UnixNano()/100) } // Returns UUID based on hashing of namespace UUID and name. @@ -237,3 +249,17 @@ func newFromHash(h hash.Hash, ns UUID, name string) UUID { return u } + +// Returns hardware address. +func defaultHWAddrFunc() (net.HardwareAddr, error) { + ifaces, err := net.Interfaces() + if err != nil { + return []byte{}, err + } + for _, iface := range ifaces { + if len(iface.HardwareAddr) >= 6 { + return iface.HardwareAddr, nil + } + } + return []byte{}, fmt.Errorf("uuid: no HW address found") +}