Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit012dd48

Browse files
author
sreya
committed
fix: properly handle integer conversions for Go 1.24 lint
1 parent90f7e9b commit012dd48

File tree

10 files changed

+136
-34
lines changed

10 files changed

+136
-34
lines changed

‎cli/cliutil/levenshtein/levenshtein.go

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -77,8 +77,13 @@ func Distance(a, b string, maxDist int) (int, error) {
7777
d[i][j]+subCost,// substitution
7878
)
7979
// check maxDist on the diagonal
80-
ifmaxDist>-1&&i==j&&maxDist<=255&&d[i+1][j+1]>uint8(maxDist) {// #nosec G115 -- we check maxDist <= 255
81-
returnint(d[i+1][j+1]),ErrMaxDist
80+
ifmaxDist>-1&&i==j {
81+
ifmaxDist>255 {
82+
// If maxDist is too large for uint8, we'll never trigger early exit
83+
// which is fine - it just means we calculate the full distance
84+
}elseifd[i+1][j+1]>uint8(maxDist) {
85+
returnint(d[i+1][j+1]),ErrMaxDist
86+
}
8287
}
8388
}
8489
}

‎coderd/database/lock.go

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,10 +15,12 @@ const (
1515
)
1616

1717
// GenLockID generates a unique and consistent lock ID from a given string.
18+
// It ensures the returned value is positive to avoid issues with negative lock IDs.
1819
funcGenLockID(namestring)int64 {
1920
hash:=fnv.New64()
2021
_,_=hash.Write([]byte(name))
21-
// For our locking purposes, it's acceptable to have potential overflow
22-
// The important part is consistency of the lock ID for a given name
23-
returnint64(hash.Sum64())// #nosec G115 -- potential overflow is acceptable for lock IDs
22+
23+
// Convert to int64 but ensure result is positive by masking off sign bit
24+
// This preserves uniqueness while avoiding overflow problems
25+
returnint64(hash.Sum64()&0x7FFFFFFFFFFFFFFF)
2426
}

‎coderd/database/modelmethods.go

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -158,10 +158,17 @@ func (t Template) DeepCopy() Template {
158158
// It is more useful to have the days that are allowed to autostart from a UX
159159
// POV. The database prefers the 0 value being 'all days allowed'.
160160
func (tTemplate)AutostartAllowedDays()uint8 {
161-
// Just flip the binary 0s to 1s and vice versa.
162-
// There is an extra day with the 8th bit that needs to be zeroed.
163-
// The conversion is safe because AutostartBlockDaysOfWeek is enforced to use only the lower 7 bits
164-
return^uint8(t.AutostartBlockDaysOfWeek)&0b01111111// #nosec G115 -- int16 to uint8 is safe as we only use 7 bits
161+
// The days are represented as a bitmap where each bit position corresponds to a day
162+
// We need to:
163+
// 1. Extract only the 7 lower bits that represent the days of the week
164+
// 2. Invert those bits to get the allowed days instead of blocked days
165+
// 3. Ensure the 8th bit is zeroed (we only use 7 bits for 7 days)
166+
167+
// Mask to extract only the lower 7 bits from AutostartBlockDaysOfWeek
168+
daysOfWeek:=t.AutostartBlockDaysOfWeek&0b01111111
169+
170+
// Invert the bits and ensure only 7 bits are used (0-6, representing Monday-Sunday)
171+
return^uint8(daysOfWeek)&0b01111111
165172
}
166173

167174
func (TemplateVersion)RBACObject(templateTemplate) rbac.Object {

‎coderd/schedule/template.go

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -76,9 +76,16 @@ func (r TemplateAutostopRequirement) DaysMap() map[time.Weekday]bool {
7676
// bitmap.
7777
funcdaysMap(daysOfWeekuint8)map[time.Weekday]bool {
7878
days:=make(map[time.Weekday]bool)
79+
80+
// Our bitmap can only represent 7 days (the days of the week)
81+
// and the loop index i can only reach at most 6, so no risk of overflow
7982
fori,day:=rangeDaysOfWeek {
80-
days[day]=daysOfWeek&(1<<uint(i))!=0// #nosec G115 -- int to uint is safe for small i values (< 8)
83+
// We know i is in the range [0,6] here since DaysOfWeek has 7 elements
84+
// 1<<i is safe as a uint8 since i < 8
85+
mask:=uint8(1)<<i
86+
days[day]= (daysOfWeek&mask)!=0
8187
}
88+
8289
returndays
8390
}
8491

‎coderd/telemetry/telemetry.go

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -723,13 +723,21 @@ func ConvertWorkspace(workspace database.Workspace) Workspace {
723723

724724
// ConvertWorkspaceBuild anonymizes a workspace build.
725725
funcConvertWorkspaceBuild(build database.WorkspaceBuild)WorkspaceBuild {
726+
// BuildNumber conversions should be safe as build numbers are always positive
727+
// and are unlikely to exceed uint32 max value in practice.
728+
// If a negative value is encountered, we'll use 0 as a safe default.
729+
buildNumber:=uint32(0)
730+
ifbuild.BuildNumber>=0 {
731+
buildNumber=uint32(build.BuildNumber)
732+
}
733+
726734
returnWorkspaceBuild{
727735
ID:build.ID,
728736
CreatedAt:build.CreatedAt,
729737
WorkspaceID:build.WorkspaceID,
730738
JobID:build.JobID,
731739
TemplateVersionID:build.TemplateVersionID,
732-
BuildNumber:uint32(build.BuildNumber),// #nosec G115 -- int32 to uint32 is safe for build numbers
740+
BuildNumber:buildNumber,
733741
}
734742
}
735743

@@ -1035,9 +1043,11 @@ func ConvertTemplate(dbTemplate database.Template) Template {
10351043
FailureTTLMillis:time.Duration(dbTemplate.FailureTTL).Milliseconds(),
10361044
TimeTilDormantMillis:time.Duration(dbTemplate.TimeTilDormant).Milliseconds(),
10371045
TimeTilDormantAutoDeleteMillis:time.Duration(dbTemplate.TimeTilDormantAutoDelete).Milliseconds(),
1038-
AutostopRequirementDaysOfWeek:codersdk.BitmapToWeekdays(uint8(dbTemplate.AutostopRequirementDaysOfWeek)),// #nosec G115 -- int16 to uint8 is safe since we only use 7 bits
1046+
// Extract only the 7 relevant bits for the days of the week
1047+
AutostopRequirementDaysOfWeek:codersdk.BitmapToWeekdays(uint8(dbTemplate.AutostopRequirementDaysOfWeek&0b01111111)),
10391048
AutostopRequirementWeeks:dbTemplate.AutostopRequirementWeeks,
1040-
AutostartAllowedDays:codersdk.BitmapToWeekdays(dbTemplate.AutostartAllowedDays()),// #nosec G115 -- uses AutostartAllowedDays() which already ensures safe conversion
1049+
// AutostartAllowedDays() already ensures we only use the 7 relevant bits
1050+
AutostartAllowedDays: codersdk.BitmapToWeekdays(dbTemplate.AutostartAllowedDays(),)
10411051
RequireActiveVersion:dbTemplate.RequireActiveVersion,
10421052
Deprecated:dbTemplate.Deprecated!="",
10431053
}

‎cryptorand/strings.go

Lines changed: 28 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -44,20 +44,35 @@ const (
4444
//
4545
//nolint:varnamelen
4646
funcunbiasedModulo32(vuint32,nint32) (int32,error) {
47-
prod:=uint64(v)*uint64(n)// #nosec G115 -- uint32 to uint64 is always safe
48-
low:=uint32(prod)// #nosec G115 -- truncation is intentional for the algorithm
49-
iflow<uint32(n) {// #nosec G115 -- int32 to uint32 is safe for positive n (we require n > 0)
50-
thresh:=uint32(-n)%uint32(n)// #nosec G115 -- int32 to uint32 after negation is an acceptable pattern here
47+
// Validate n is positive
48+
ifn<=0 {
49+
return0,xerrors.Errorf("modulus must be positive: %d",n)
50+
}
51+
52+
// These conversions are safe:
53+
// - uint32 to uint64 is always safe (smaller to larger)
54+
// - int32 to uint64 is safe for positive values, which we've validated
55+
prod:=uint64(v)*uint64(n)
56+
57+
// Intentional truncation for algorithm
58+
low:=uint32(prod)
59+
60+
iflow<uint32(n) {
61+
// This conversion is safe since n is positive, so -n as uint32 is well-defined
62+
thresh:=uint32(-n)%uint32(n)
63+
5164
forlow<thresh {
5265
err:=binary.Read(rand.Reader,binary.BigEndian,&v)
5366
iferr!=nil {
5467
return0,err
5568
}
56-
prod=uint64(v)*uint64(n)// #nosec G115 -- uint32 to uint64 is always safe
57-
low=uint32(prod)// #nosec G115 -- truncation is intentional for the algorithm
69+
prod=uint64(v)*uint64(n)
70+
low=uint32(prod)
5871
}
5972
}
60-
returnint32(prod>>32),nil// #nosec G115 -- proper range is guaranteed by the algorithm
73+
74+
// The algorithm ensures prod>>32 is always in [0,n), so conversion to int32 is safe
75+
returnint32(prod>>32),nil
6176
}
6277

6378
// StringCharset generates a random string using the provided charset and size.
@@ -87,10 +102,14 @@ func StringCharset(charSetStr string, size int) (string, error) {
87102
r:=binary.BigEndian.Uint32(entropy[:4])// #nosec G115 -- not a conversion, just reading bytes as uint32
88103
entropy=entropy[4:]
89104

90-
// Charset length is limited by string size, so conversion to int32 is safe
105+
// Ensure charset length is within int32 range
106+
charSetLen:=len(charSet)
107+
ifcharSetLen<=0||charSetLen> (1<<31)-1 {
108+
return"",xerrors.Errorf("invalid charset length: %d",charSetLen)
109+
}
91110
ci,err:=unbiasedModulo32(
92111
r,
93-
int32(len(charSet)),// #nosec G115 -- int to int32 is safe for charset length
112+
int32(charSetLen),
94113
)
95114
iferr!=nil {
96115
return"",err

‎provisionerd/runner/runner.go

Lines changed: 29 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import (
55
"encoding/json"
66
"errors"
77
"fmt"
8+
"math"
89
"reflect"
910
"strings"
1011
"sync"
@@ -884,9 +885,36 @@ func (r *Runner) commitQuota(ctx context.Context, resources []*sdkproto.Resource
884885

885886
conststage="Commit quota"
886887

888+
// Ensure cost doesn't exceed int32 range
889+
vardailyCostint32
890+
ifcost>math.MaxInt32 {
891+
// In the unlikely event that cost exceeds int32 range,
892+
// set it to the max value as a reasonable approximation
893+
dailyCost=math.MaxInt32
894+
r.queueLog(ctx,&proto.Log{
895+
Source:proto.LogSource_PROVISIONER,
896+
Level:sdkproto.LogLevel_WARN,
897+
CreatedAt:time.Now().UnixMilli(),
898+
Output:fmt.Sprintf("Cost %d exceeds int32 range, capping at %d",cost,math.MaxInt32),
899+
Stage:stage,
900+
})
901+
}elseifcost<0 {
902+
// Negative costs are invalid; use 0 as a safe value
903+
dailyCost=0
904+
r.queueLog(ctx,&proto.Log{
905+
Source:proto.LogSource_PROVISIONER,
906+
Level:sdkproto.LogLevel_WARN,
907+
CreatedAt:time.Now().UnixMilli(),
908+
Output:fmt.Sprintf("Negative cost %d is invalid, using 0",cost),
909+
Stage:stage,
910+
})
911+
}else {
912+
dailyCost=int32(cost)
913+
}
914+
887915
resp,err:=r.quotaCommitter.CommitQuota(ctx,&proto.CommitQuotaRequest{
888916
JobId:r.job.JobId,
889-
DailyCost:int32(cost),// #nosec G115 -- int to int32 is safe for cost values
917+
DailyCost:dailyCost,
890918
})
891919
iferr!=nil {
892920
r.queueLog(ctx,&proto.Log{

‎pty/ssh_other.go

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ package pty
44

55
import (
66
"log"
7+
"math"
78

89
"github.com/gliderlabs/ssh"
910
"github.com/u-root/u-root/pkg/termios"
@@ -90,11 +91,23 @@ func applyTerminalModesToFd(logger *log.Logger, fd uintptr, req ssh.Pty) error {
9091

9192
forc,v:=rangereq.Modes {
9293
ifc==gossh.TTY_OP_ISPEED {
93-
tios.Ispeed=int(v)// #nosec G115 -- uint32 to int is safe for TTY speeds
94+
// TTY speeds should always be positive and in a reasonable range
95+
// that fits within int range, but we'll handle edge cases safely.
96+
ifv>math.MaxInt {
97+
// If the value is too large, we'll use a large but safe value
98+
tios.Ispeed=math.MaxInt
99+
}else {
100+
tios.Ispeed=int(v)
101+
}
94102
continue
95103
}
96104
ifc==gossh.TTY_OP_OSPEED {
97-
tios.Ospeed=int(v)// #nosec G115 -- uint32 to int is safe for TTY speeds
105+
// Same logic as ISPEED
106+
ifv>math.MaxInt {
107+
tios.Ospeed=math.MaxInt
108+
}else {
109+
tios.Ospeed=int(v)
110+
}
98111
continue
99112
}
100113
k,ok:=terminalModeFlagNames[c]

‎tailnet/conn.go

Lines changed: 7 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -132,14 +132,13 @@ type TelemetrySink interface {
132132
// NodeID creates a Tailscale NodeID from the last 8 bytes of a UUID. It ensures
133133
// the returned NodeID is always positive.
134134
funcNodeID(uid uuid.UUID) tailcfg.NodeID {
135-
// This may overflow, but we handle that by ensuring the result is positive below
136-
id:=int64(binary.BigEndian.Uint64(uid[8:]))// #nosec G115 -- potential overflow is handled below
137-
138-
// ensure id is positive
139-
y:=id>>63
140-
id= (id^y)-y
141-
142-
returntailcfg.NodeID(id)
135+
// Extract the last 8 bytes of the UUID as a uint64
136+
rawValue:=binary.BigEndian.Uint64(uid[8:])
137+
138+
// Ensure we have a positive int64 by masking off the sign bit
139+
// This handles the potential overflow when converting from uint64 to int64
140+
// by ensuring we only use the lower 63 bits
141+
returntailcfg.NodeID(int64(rawValue&0x7FFFFFFFFFFFFFFF))
143142
}
144143

145144
// NewConn constructs a new Wireguard server that will accept connections from the addresses provided.

‎tailnet/convert.go

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package tailnet
22

33
import (
4+
"math"
45
"net/netip"
56

67
"github.com/google/uuid"
@@ -29,9 +30,20 @@ func NodeToProto(n *Node) (*proto.Node, error) {
2930
iferr!=nil {
3031
returnnil,err
3132
}
33+
// Create map for the DERP forced websocket settings
3234
derpForcedWebsocket:=make(map[int32]string)
35+
36+
// Validate and convert map indices safely
3337
fori,s:=rangen.DERPForcedWebsocket {
34-
derpForcedWebsocket[int32(i)]=s// #nosec G115 -- int to int32 is safe for indices
38+
// Indices are guaranteed to be small positive values since they're
39+
// array indices, but we'll double-check to be safe
40+
ifi<0||i>math.MaxInt32 {
41+
// This shouldn't happen in normal operation, but we'll handle it gracefully
42+
// by skipping this entry if it somehow does
43+
continue
44+
}
45+
46+
derpForcedWebsocket[int32(i)]=s
3547
}
3648
addresses:=make([]string,len(n.Addresses))
3749
fori,prefix:=rangen.Addresses {

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp