Skip to content

Commit

Permalink
Revert "fixes #20285; prevent oid time overflow at year 2038 (#20338)"
Browse files Browse the repository at this point in the history
This reverts commit db8a62d.
  • Loading branch information
ringabout authored Sep 22, 2022
1 parent db8a62d commit 2843f27
Show file tree
Hide file tree
Showing 3 changed files with 26 additions and 26 deletions.
2 changes: 0 additions & 2 deletions changelog.md
Original file line number Diff line number Diff line change
Expand Up @@ -65,8 +65,6 @@
- `strutils.find` now uses and defaults to `last = -1` for whole string searches,
making limiting it to just the first char (`last = 0`) valid.
- `random.rand` now works with `Ordinal`s.
- `std/oids` now uses `int64` to store time internally (before it was int32), the length of
the string form of `Oid` changes from 24 to 32.

[//]: # "Additions:"
- Added ISO 8601 week date utilities in `times`:
Expand Down
39 changes: 25 additions & 14 deletions lib/pure/oids.nim
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,8 @@

## Nim OID support. An OID is a global ID that consists of a timestamp,
## a unique counter and a random value. This combination should suffice to
## produce a globally distributed unique ID.
## produce a globally distributed unique ID. This implementation was extracted
## from the MongoDB interface and is thus binary compatible with a MongoDB OID.
##
## This implementation calls `initRand()` for the first call of
## `genOid`.
Expand All @@ -19,7 +20,7 @@ from std/private/decode_helpers import handleHexChar

type
Oid* = object ## An OID.
time: int64
time: int32
fuzz: int32
count: int32

Expand All @@ -43,27 +44,37 @@ proc parseOid*(str: cstring): Oid =
## Parses an OID.
var bytes = cast[cstring](addr(result.time))
var i = 0
while i < 16:
while i < 12:
bytes[i] = chr((hexbyte(str[2 * i]) shl 4) or hexbyte(str[2 * i + 1]))
inc(i)

proc `$`*(oid: Oid): string =
## Converts an OID to a string.
template toStringImpl[T: string | cstring](result: var T, oid: Oid) =
## Stringifies `oid`.
const hex = "0123456789abcdef"
const N = 24

result.setLen 32
when T is string:
result.setLen N

var o = oid
var bytes = cast[cstring](addr(o))
var i = 0
while i < 16:
while i < 12:
let b = bytes[i].ord
result[2 * i] = hex[(b and 0xF0) shr 4]
result[2 * i + 1] = hex[b and 0xF]
inc(i)
when T is cstring:
result[N] = '\0'


proc `$`*(oid: Oid): string =
## Converts an OID to a string.
toStringImpl(result, oid)


let
t = getTime().toUnix
t = getTime().toUnix.int32

var
seed = initRand(t)
Expand All @@ -73,24 +84,24 @@ let fuzz = cast[int32](seed.rand(high(int)))


template genOid(result: var Oid, incr: var int, fuzz: int32) =
var time = getTime().toUnix
var time = getTime().toUnix.int32
var i = cast[int32](atomicInc(incr))

bigEndian64(addr result.time, addr(time))
bigEndian32(addr result.time, addr(time))
result.fuzz = fuzz
bigEndian32(addr result.count, addr(i))

proc genOid*(): Oid =
## Generates a new OID.
runnableExamples:
doAssert ($genOid()).len == 32
doAssert ($genOid()).len == 24
runnableExamples("-r:off"):
echo $genOid() # for example, "00000000632c452db08c3d19ee9073e5"
echo $genOid() # for example, "5fc7f546ddbbc84800006aaf"
genOid(result, incr, fuzz)

proc generatedTime*(oid: Oid): Time =
## Returns the generated timestamp of the OID.
var tmp: int64
var tmp: int32
var dummy = oid.time
bigEndian64(addr(tmp), addr(dummy))
bigEndian32(addr(tmp), addr(dummy))
result = fromUnix(tmp)
11 changes: 1 addition & 10 deletions tests/stdlib/toids.nim
Original file line number Diff line number Diff line change
@@ -1,15 +1,6 @@
discard """
matrix: "--mm:refc; --mm:orc"
"""

import std/oids


block: # genOid
let x = genOid()
doAssert ($x).len == 32

block:
let x = genOid()
let y = parseOid(cstring($x))
doAssert x == y
doAssert ($x).len == 24

0 comments on commit 2843f27

Please sign in to comment.