undf: assign 847-849; stamp freecad/retroarch patches
This commit is contained in:
parent
e06902c99a
commit
4cc47349a5
26 changed files with 931 additions and 1 deletions
|
|
@ -0,0 +1,81 @@
|
|||
# UNDF: UNDF-2026-000000850
|
||||
# UNDF: (leave blank)
|
||||
# CWE-407: Algorithmic Complexity — deviceFolderFileDownloadState.blockIndexes linear scan
|
||||
#
|
||||
# File: lib/model/devicedownloadstate.go
|
||||
# Defect: blockIndexes stored as []int with slices.Contains() O(B) lookup
|
||||
# Called from blockAvailabilityFromTemporaryRLocked per device per block
|
||||
# Total complexity per file pull: O(D * B^2) where D=devices, B=blocks
|
||||
# Fix: Replace []int with map[int]struct{} for O(1) membership test
|
||||
# Severity: MEDIUM — large files (100MB+ with 128KB blocks = 800+ blocks) across
|
||||
# multiple devices trigger quadratic behavior in the sync hot path
|
||||
# Overhead: ~250x at B=500 blocks (realistic for 64MB file with 128KB block size)
|
||||
|
||||
--- a/lib/model/devicedownloadstate.go
|
||||
+++ b/lib/model/devicedownloadstate.go
|
||||
@@ -7,14 +7,13 @@
|
||||
package model
|
||||
|
||||
import (
|
||||
- "slices"
|
||||
"sync"
|
||||
|
||||
"github.com/syncthing/syncthing/lib/protocol"
|
||||
)
|
||||
|
||||
// deviceFolderFileDownloadState holds current download state of a file that
|
||||
// a remote device has advertised. blockIndexes represents indexes within
|
||||
// FileInfo.Blocks that the remote device already has, and version represents
|
||||
// the version of the file that the remote device is downloading.
|
||||
type deviceFolderFileDownloadState struct {
|
||||
- blockIndexes []int
|
||||
+ blockIndexes map[int]struct{}
|
||||
version protocol.Vector
|
||||
blockSize int
|
||||
}
|
||||
@@ -35,7 +34,8 @@ func (p *deviceFolderDownloadState) Has(file string, version protocol.Vector, in
|
||||
if !ok || !local.version.Equal(version) {
|
||||
return false
|
||||
}
|
||||
- return slices.Contains(local.blockIndexes, index)
|
||||
+ _, found := local.blockIndexes[index]
|
||||
+ return found
|
||||
}
|
||||
|
||||
// Update updates internal state of what has been downloaded into the temporary
|
||||
@@ -50,22 +50,28 @@ func (p *deviceFolderDownloadState) Update(updates []protocol.FileDownloadProgre
|
||||
} else if update.UpdateType == protocol.FileDownloadProgressUpdateTypeAppend {
|
||||
switch {
|
||||
case !ok:
|
||||
+ m := make(map[int]struct{}, len(update.BlockIndexes))
|
||||
+ for _, idx := range update.BlockIndexes {
|
||||
+ m[idx] = struct{}{}
|
||||
+ }
|
||||
local = deviceFolderFileDownloadState{
|
||||
- blockIndexes: update.BlockIndexes,
|
||||
+ blockIndexes: m,
|
||||
version: update.Version,
|
||||
blockSize: update.BlockSize,
|
||||
}
|
||||
case !local.version.Equal(update.Version):
|
||||
- local.blockIndexes = append(local.blockIndexes[:0], update.BlockIndexes...)
|
||||
+ local.blockIndexes = make(map[int]struct{}, len(update.BlockIndexes))
|
||||
+ for _, idx := range update.BlockIndexes {
|
||||
+ local.blockIndexes[idx] = struct{}{}
|
||||
+ }
|
||||
local.version = update.Version
|
||||
local.blockSize = update.BlockSize
|
||||
default:
|
||||
- local.blockIndexes = append(local.blockIndexes, update.BlockIndexes...)
|
||||
+ for _, idx := range update.BlockIndexes {
|
||||
+ local.blockIndexes[idx] = struct{}{}
|
||||
+ }
|
||||
}
|
||||
p.files[update.Name] = local
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (p *deviceFolderDownloadState) BytesDownloaded() int64 {
|
||||
p.mut.RLock()
|
||||
defer p.mut.RUnlock()
|
||||
Loading…
Add table
Add a link
Reference in a new issue