Fix gosec bounds in the byte swizzle, drop the now-unused releaseCapture, and make the SSH and approval-reuse tests actually exercise their paths

This commit is contained in:
Viktor Liu
2026-09-22 21:03:30 +02:00
parent 65bb3ae4f5
commit 8f06a43d93
4 changed files with 17 additions and 16 deletions
-10
View File
@@ -370,16 +370,6 @@ func (s *Server) evictActiveCaptureLocked() func() {
}
}
// releaseCapture clears the active-capture owner if it still matches sess.
func (s *Server) releaseCapture(sess *capture.Session) {
s.mutex.Lock()
defer s.mutex.Unlock()
if s.activeCapture == sess {
s.activeCapture = nil
s.activeCaptureCancel = nil
}
}
// clearCaptureIfOwner clears engine's capture slot only if sess still owns it.
func (s *Server) clearCaptureIfOwner(sess *capture.Session, engine *internal.Engine) {
s.mutex.Lock()
@@ -43,10 +43,16 @@ export default function ApprovalDialog() {
const peerPubKey = params.get("peer_pubkey") ?? "";
const expiresAt = params.get("expires_at") ?? "";
// requestID is a dependency because the window is reused across prompts. A
// request that carries no usable expires_at falls back to a deadline
// measured from now, and without recomputing it here the next prompt
// inherits the previous request's deadline and can close the moment it
// opens.
const deadline = useMemo(() => {
const parsed = Date.parse(expiresAt);
return Number.isFinite(parsed) ? parsed : Date.now() + FALLBACK_SECONDS * 1000;
}, [expiresAt]);
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [expiresAt, requestID]);
const title = useMemo(() => {
switch (kind) {
@@ -125,9 +131,11 @@ export default function ApprovalDialog() {
setBusy(false);
setArmed(false);
closedRef.current = false;
setRemaining(secondsLeft());
const id = globalThis.setTimeout(() => setArmed(true), ARMING_MS);
return () => globalThis.clearTimeout(id);
}, [requestID]);
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [requestID, deadline]);
useEffect(() => {
const id = globalThis.setInterval(() => {
const left = secondsLeft();
+5 -4
View File
@@ -44,10 +44,11 @@ func swizzleBGRAtoRGBA(dst, src []byte) {
}
// swizzleBGRAtoRGBABytes is the byte-order-independent form, used on big-endian
// targets. dst and src must be the same length and a multiple of 4.
// targets. It converts whole pixels for as long as both sides have one left.
func swizzleBGRAtoRGBABytes(dst, src []byte) {
for i := 0; i < len(src); i += 4 {
b, g, r := src[i], src[i+1], src[i+2]
dst[i], dst[i+1], dst[i+2], dst[i+3] = r, g, b, 0xFF
for i := 0; i+4 <= len(src) && i+4 <= len(dst); i += 4 {
s := src[i : i+4 : i+4]
d := dst[i : i+4 : i+4]
d[0], d[1], d[2], d[3] = s[2], s[1], s[0], 0xFF
}
}
@@ -101,6 +101,7 @@ func TestApplyResolvedRule_SSHSkipsSourcePeer(t *testing.T) {
}
rule := &nmdata.PolicyRule{
Protocol: string(PolicyRuleProtocolNetbirdSSH),
Action: string(PolicyTrafficActionAccept),
Bidirectional: bidirectional,
}
state := NewPeerConnResolveState()
@@ -153,6 +154,7 @@ func TestApplyResolvedRule_SSHEnablesDestinationPeer(t *testing.T) {
func TestApplyResolvedRule_LegacySSHSkipsSourcePeer(t *testing.T) {
rule := &nmdata.PolicyRule{
Protocol: string(PolicyRuleProtocolTCP),
Action: string(PolicyTrafficActionAccept),
Ports: []string{"22"},
Bidirectional: true,
}