java-topology/defects/forgejo-0003/patch/forgejo-0003.patch
russell@unturf.com cdff140a7c langchain: 1 CWE-407 defect; forgejo: 2 new CWE-407 defects, MOADs 0002-0005 CLEAN
langchain-0001: MultiVectorRetriever._get_relevant_documents() dedup
  IDs from vectorstore sub_docs uses list.contains() inside loop, O(k^2).
  k is unbounded in production RAG pipelines (configurable via search_kwargs).
  Fix: track seen IDs in a set, keep list for order. 499.5x at k=1000.

forgejo-0002: LoadRepoConfig() license sort O(P*L) where L=776 licenses.
  Two SliceContainsString calls in back-to-back loops iterate full license
  list for each preferred license and vice versa. Fix: build lookup sets
  before loops. 19.5x at P=20 preferred licenses.

forgejo-0003: synchronizePublicKeys() three O(N*M) scans per LDAP sync.
  Dedup of providedKeys is O(K^2), plus two O(P*G) set-difference loops.
  Runs per user per sync cycle. Fix: use maps for O(1) membership. 178.6x
  at K=G=500.

forgejo-0001 (search.go RepoIDs) already patched in prior scan.
MOADs 0002-0005 CLEAN for both targets.
2026-03-31 20:12:14 -04:00

47 lines
1.7 KiB
Diff

--- a/models/asymkey/ssh_key.go
+++ b/models/asymkey/ssh_key.go
@@ -378,19 +378,22 @@ func synchronizePublicKeys(ctx context.Context, s *auth.Source, usr *user_model.
// Process the provided keys to remove duplicates and name part
- var providedKeys []string
+ providedKeysSet := make(map[string]struct{})
+ var providedKeys []string
for _, v := range sshPublicKeys {
sshKeySplit := strings.Split(v, " ")
if len(sshKeySplit) > 1 {
key := strings.Join(sshKeySplit[:2], " ")
- if !util.SliceContainsString(providedKeys, key) {
+ if _, exists := providedKeysSet[key]; !exists {
+ providedKeysSet[key] = struct{}{}
providedKeys = append(providedKeys, key)
}
}
}
// Check if Public Key sync is needed
@@ -399,14 +402,16 @@ func synchronizePublicKeys(ctx context.Context, s *auth.Source, usr *user_model.
// Add new Public SSH Keys that doesn't already exist in DB
+ giteaKeysSet := make(map[string]struct{}, len(giteaKeys))
+ for _, k := range giteaKeys {
+ giteaKeysSet[k] = struct{}{}
+ }
var newKeys []string
for _, key := range providedKeys {
- if !util.SliceContainsString(giteaKeys, key) {
+ if _, exists := giteaKeysSet[key]; !exists {
newKeys = append(newKeys, key)
}
}
if AddPublicKeysBySource(ctx, usr, s, newKeys) {
sshKeysNeedUpdate = true
}
// Mark keys from DB that no longer exist in the source for deletion
var giteaKeysToDelete []string
for _, giteaKey := range giteaKeys {
- if !util.SliceContainsString(providedKeys, giteaKey) {
+ if _, exists := providedKeysSet[giteaKey]; !exists {
log.Trace("synchronizePublicKeys[%s]: Marking Public SSH Key for deletion for user %s: %v", s.Name, usr.Name, giteaKey)
giteaKeysToDelete = append(giteaKeysToDelete, giteaKey)
}
}