Skip to content

Commit e5a4341

Browse files
committed
Add support for (u)int type conversion overflow detection
1 parent d598466 commit e5a4341

File tree

5 files changed

+1047
-3
lines changed

5 files changed

+1047
-3
lines changed

README.md

Lines changed: 30 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[![Build Status](https://travis-ci.org/JohnCGriffin/overflow.png)](https://travis-ci.org/JohnCGriffin/overflow)
22
# overflow
3-
Check for integer overflow in Golang arithmetic.
3+
Check for integer overflow in Golang arithmetic and type conversion.
44
### Install
55
```
66
go get github.com/johncgriffin/overflow
@@ -13,6 +13,7 @@ go generate
1313
```
1414
### Synopsis
1515

16+
#### Arithmetic overflow detection
1617
```
1718
package main
1819
@@ -48,6 +49,34 @@ yields the output
4849

4950
For (u)int types, provide (U)Add, (U)Sub, (U)Mul, (U)Div, (U)Quotient, etc.
5051

52+
53+
#### Type conversion overflow detection
54+
```
55+
func main() {
56+
var i uint
57+
for i = math.MaxInt - 5; i <= math.MaxInt+5; i++ {
58+
ret, ok := overflow.UintToInt(i)
59+
fmt.Printf("%v -> (%v,%v)\n",
60+
i, ret, ok)
61+
}
62+
}
63+
```
64+
yields the output
65+
```
66+
9223372036854775802 -> (9223372036854775802,true)
67+
9223372036854775803 -> (9223372036854775803,true)
68+
9223372036854775804 -> (9223372036854775804,true)
69+
9223372036854775805 -> (9223372036854775805,true)
70+
9223372036854775806 -> (9223372036854775806,true)
71+
9223372036854775807 -> (9223372036854775807,true)
72+
9223372036854775808 -> (-9223372036854775808,false)
73+
9223372036854775809 -> (-9223372036854775807,false)
74+
9223372036854775810 -> (-9223372036854775806,false)
75+
9223372036854775811 -> (-9223372036854775805,false)
76+
9223372036854775812 -> (-9223372036854775804,false)
77+
```
78+
Provide UintToInt, IntToUint, Uint64ToInt32, Int32ToUint64, etc.
79+
5180
### Stay calm and panic
5281

5382
There's a good case to be made that a panic is an unidiomatic but proper response. Iff you
@@ -80,4 +109,3 @@ SOFTWARE.
80109

81110

82111

83-

overflow.go

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -142,6 +142,28 @@ func UQuotient(a, b uint) (uint, uint, bool) {
142142
return uint(uq32), uint(ur32), ok
143143
}
144144

145+
// IntToUint converts an int value to uint.
146+
// returning a converted value and a bool value indicating whether the operation is safe.
147+
func IntToUint(x int) (uint, bool) {
148+
if _is64Bit() {
149+
y64, ok := Int64ToUint64(int64(x))
150+
return uint(y64), ok
151+
}
152+
y32, ok := Int32ToUint32(int32(x))
153+
return uint(y32), ok
154+
}
155+
156+
// UintToInt converts an uint value to int.
157+
// returning a converted value and a bool value indicating whether the operation is safe.
158+
func UintToInt(x uint) (int, bool) {
159+
if _is64Bit() {
160+
y64, ok := Uint64ToInt64(uint64(x))
161+
return int(y64), ok
162+
}
163+
y32, ok := Uint32ToInt32(uint32(x))
164+
return int(y32), ok
165+
}
166+
145167
/************* Panic versions for int ****************/
146168

147169
// Addp returns the sum of two ints, panicking on overflow
@@ -215,3 +237,21 @@ func UDivp(a, b uint) uint {
215237
}
216238
return r
217239
}
240+
241+
// IntToUintp converts an uint value to int, panicking on overflow.
242+
func IntToUintp(x int) uint {
243+
r, ok := IntToUint(x)
244+
if !ok {
245+
panic("conversion failure")
246+
}
247+
return r
248+
}
249+
250+
// UintToIntp converts an uint value to int, panicking on overflow.
251+
func UintToIntp(x uint) int {
252+
r, ok := UintToInt(x)
253+
if !ok {
254+
panic("conversion failure")
255+
}
256+
return r
257+
}

0 commit comments

Comments
 (0)