Skip to content

Commit a63c5d7

Browse files
authored
fix: resolve G115 integer overflow and exhaustive warnings (#365)
1 parent e529380 commit a63c5d7

File tree

7 files changed

+40
-4
lines changed

7 files changed

+40
-4
lines changed

field/bitmap.go

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,8 @@ import (
1010

1111
var _ Field = (*Bitmap)(nil)
1212

13-
// Bitmap is a 1-indexed big endian bitmap field.
13+
// Bitmap represents an ISO 8583–style bitmap.
14+
// Bits are 1-indexed from left to right (ISO bit 1 → MSB of byte 0, ISO bit 8 → LSB of byte 0, and so on).
1415
type Bitmap struct {
1516
spec *Spec
1617
data []byte
@@ -19,7 +20,8 @@ type Bitmap struct {
1920

2021
const defaultBitmapLength = 8
2122

22-
const firstBitOn = 0b10000000 // big endian
23+
// first bit of the bitmap
24+
const firstBitOn = 0b10000000
2325

2426
func NewBitmap(spec *Spec) *Bitmap {
2527
length := spec.Length
@@ -195,16 +197,26 @@ func (f *Bitmap) Set(n int) {
195197
}
196198
}
197199

200+
bitIndex := n - 1 // convert to 0-indexed
201+
byteIndex := bitIndex / 8
202+
bitInByte := bitIndex % 8
203+
offset := 7 - bitInByte // reverse order for MSB=bit 1 convention (0..7)
204+
198205
// set bit
199-
f.data[(n-1)/8] |= 1 << (uint(7-(n-1)) % 8)
206+
f.data[byteIndex] |= (1 << offset)
200207
}
201208

202209
func (f *Bitmap) IsSet(n int) bool {
203210
if n <= 0 || n > len(f.data)*8 {
204211
return false
205212
}
206213

207-
return f.data[(n-1)/8]&(1<<(uint(7-(n-1))%8)) != 0
214+
bitIndex := n - 1
215+
byteIndex := bitIndex / 8
216+
bitInByte := bitIndex % 8
217+
offset := 7 - bitInByte // reverse order for MSB=bit 1 convention (0..7)
218+
219+
return f.data[byteIndex]&(1<<offset) != 0
208220
}
209221

210222
func (f *Bitmap) Len() int {

field/string.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -192,6 +192,7 @@ func (f *String) Marshal(v interface{}) error {
192192
kind = rv.Kind()
193193
}
194194

195+
//nolint:exhaustive
195196
switch kind {
196197
case reflect.String:
197198
f.value = rv.String()

network/binary_2bytes.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ func (h *Binary2Bytes) SetLength(length int) error {
2020
return fmt.Errorf("length %d exceeds max length for 2 bytes header %d", length, math.MaxUint16)
2121
}
2222

23+
// #nosec G115 -- length is validated to be within uint16 range above
2324
h.Len = uint16(length)
2425

2526
return nil

network/vml_header.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ func (h *VMLH) SetLength(length int) error {
3333
return fmt.Errorf("length %d exceeds max length for 2 bytes header %d", length, math.MaxUint16)
3434
}
3535

36+
// #nosec G115 -- length is validated to be within uint16 range above
3637
h.Len = uint16(length)
3738

3839
return nil

prefix/bertlv.go

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,13 @@ func (p *berTLVPrefixer) EncodeLength(maxLen, dataLen int) ([]byte, error) {
4343
if dataLen <= 127 {
4444
return buf, nil
4545
}
46+
47+
if len(buf) > 127 { // the maximum length of the long form
48+
return nil, fmt.Errorf("data length %d exceeds maximum length of 127 bytes to store it", dataLen)
49+
}
50+
51+
// set the most significant bit to indicate that this is a long form
52+
// #nosec G115 -- length of `buf` is validated above
4653
return append([]byte{setMSB(uint8(len(buf)))}, buf...), nil
4754
}
4855

prefix/binary.go

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import (
44
"bytes"
55
"encoding/binary"
66
"fmt"
7+
"math"
78
"strings"
89
)
910

@@ -45,6 +46,12 @@ func intToBytes(n int) ([]byte, error) {
4546
return nil, fmt.Errorf("negative number: %d", n)
4647
}
4748
buf := new(bytes.Buffer)
49+
50+
if n > math.MaxUint32 {
51+
return nil, fmt.Errorf("number %d exceeds maximum uint32 value", n)
52+
}
53+
54+
// #nosec G115 -- length is validated above
4855
err := binary.Write(buf, binary.BigEndian, uint32(n))
4956
if err != nil {
5057
return nil, fmt.Errorf("int to bytes: %w", err)

prefix/hex.go

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ package prefix
33
import (
44
"encoding/hex"
55
"fmt"
6+
"math"
67
"strconv"
78
"strings"
89
)
@@ -68,10 +69,16 @@ func (p *hexVarPrefixer) DecodeLength(maxLen int, data []byte) (int, int, error)
6869
return 0, 0, err
6970
}
7071

72+
if dataLen > math.MaxInt {
73+
return 0, 0, fmt.Errorf("data length %d exceeds maximum int value", dataLen)
74+
}
75+
76+
// #nosec G115 -- dataLen is validated to be within MaxInt range above
7177
if int(dataLen) > maxLen {
7278
return 0, 0, fmt.Errorf(dataLengthIsLargerThanMax, dataLen, maxLen)
7379
}
7480

81+
// #nosec G115 -- dataLen is validated to be within MaxInt range above
7582
return int(dataLen), length, nil
7683
}
7784

0 commit comments

Comments
 (0)