Skip to content

Commit

Permalink
doc: improve the README
Browse files Browse the repository at this point in the history
Fixes #22
  • Loading branch information
ccoVeille committed Sep 8, 2024
1 parent 3049cd5 commit 82383d5
Showing 1 changed file with 36 additions and 37 deletions.
73 changes: 36 additions & 37 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,69 +1,70 @@
# Go SafeCast
# 🪄 go-safecast: safe numbers conversion

[![Go Report Card](https://goreportcard.com/badge/github.com/ccoveille/go-safecast)](https://goreportcard.com/report/github.com/ccoveille/go-safecast)
[![GoDoc](https://godoc.org/github.com/ccoVeille/go-safecast?status.svg)](https://godoc.org/github.com/ccoVeille/go-safecast)
[![codecov](https://codecov.io/gh/ccoVeille/go-safecast/graph/badge.svg?token=VW0VO503U6)](https://codecov.io/gh/ccoVeille/go-safecast)
[![Code Climate](https://codeclimate.com/github/ccoVeille/go-safecast.png)](https://codeclimate.com/github/ccoVeille/go-safecast)

## Origin of this project
## Project purpose

In Go, integer type conversion can lead to unexpected behavior and errors if not handled carefully.
In Go, integer type conversion can lead to a silent and unexpected behavior and errors if not handled carefully.

Issues can happen when converting between signed and unsigned integers, or when converting to a smaller integer type.

The gosec project raised this to my attention when the gosec [G115 rule was added](https://github.com/securego/gosec/pull/1149)

> G115: Potential integer overflow when converting between integer types
This issue was way more complex than expected, and required multiple fixes.
This library is made to help converting any number to another and report an error when it fails

## Example
## Integer overflow

This code seems OK
Issues can happen when converting between signed and unsigned integers, or when converting to a smaller integer type.

```go
package main

import (
"fmt"
)
import "fmt"

func main() {
var a uint64
var a int64
a = 42
b := int32(a)
b := uint8(a)
fmt.Println(b) // 42

a = 255 // this is the math.MaxUint8
b = uint8(a)
fmt.Println(b) // 255

a = 255 + 1
b = uint8(a)
fmt.Println(b) // 0 integer overflow

a = -1
b = uint8(a)
fmt.Println(b) // 255 integer overflow
}
```

But the conversion to int32 will behave differently depending on the value
GoPlay: [https://go.dev/play/p/DHfNUcZBvVn](https://go.dev/play/p/DHfNUcZBvVn)

## Library

```go
package main

import (
"fmt"
)
import "fmt"

func main() {
var a uint64
a = 2147483647
b := int32(a)
fmt.Println(b) // 2147483647

a = 2147483647 + 1
b = int32(a)
fmt.Println(b) // -2147483648 integer overflow

c := -1
d := uint32(c)
fmt.Println(d) // 4294967295
_, err := safecast.ToInt8(uint16(1000))
fmt.Println(err) // integer overflow: 1000 (uint16) is greater than 127 (int8): exceed upper boundary for this type

_, err := safecast.ToUint16(float32(-1)
fmt.Println(err) // integer overflow: -1.0 (float32) is smaller than 0 (uint16): exceed lower boundary for this type
}
```

GoPlay: [https://go.dev/play/p/9PRWI7e0x1T](https://go.dev/play/p/9PRWI7e0x1T)
## Motivation

The gosec project raised this to my attention when the gosec [G115 rule was added](https://github.com/securego/gosec/pull/1149)

### What is the problem ?
> G115: Potential integer overflow when converting between integer types.
This issue was way more complex than expected, and required multiple fixes.

[CWE-190](https://cwe.mitre.org/data/definitions/190.html) explains in detail.

Expand All @@ -73,8 +74,6 @@ But to sum it up, you can face:
- access to wrong resource by id
- grant access to someone who exhausted their quota

## Motivation

The gosec G115 will now report issues in a lot of project.

## Alternatives
Expand Down

0 comments on commit 82383d5

Please sign in to comment.