fix(#123): address all review findings from PR #129
PR Ready Gate / clear-labels (pull_request) Successful in 2s
CI / test (pull_request) Successful in 17s
CI / review (anthropic--claude-4.6-sonnet, sonnet, SONNET_REVIEW_TOKEN) (pull_request) Successful in 34s
CI / review (gpt-5, gpt, GPT_REVIEW_TOKEN) (pull_request) Successful in 1m25s
CI / review (gpt-5, security, ., rodin/security-patterns, SECURITY_REVIEW.md, SECURITY_REVIEW_TOKEN) (pull_request) Successful in 2m30s

MAJOR fixes:
- gitea/ipcheck.go: replace startup panic with init()+error list pattern
  Hard-coded CIDRs that fail to parse now recorded in blockedCIDRParseErrors
  instead of panicking. TestBlockedCIDRsValid catches programming errors
  in CI without violating CONVENTIONS.md 'never panic' rule.
- .gitea/actions/review/action.yml: re-validate SERVER_URL at start of
  'Install review-bot' step to close DNS rebinding window between
  'Determine version' and install-step curl calls.

MINOR fixes:
- gitea/client.go: add Timeout: 10*time.Second to net.Dialer per PLAN.md spec
- cmd/review-bot/validateurl.go: switch isValidateError to errors.As so
  wrapped *validateError values are also detected
- gitea/ipcheck_test.go: clarify 198.51.100.1 (RFC5737 TEST-NET-2) comment;
  add TestBlockedCIDRsValid to surface CIDR parse errors as test failures

NIT fixes:
- .gitea/actions/review/action.yml: refactor Python list comprehension in
  SSRF check to for-loop (avoids side-effect-only comprehension, runner compat)
- gitea/export_test.go: expand comment explaining white-box test pattern
  (why package gitea not gitea_test, Go stdlib precedent)

Remove PLAN.md (implementation complete)
This commit is contained in:
claw
2026-05-14 01:42:47 -07:00
parent 8c8f3ab4b3
commit f84cc3bbcf
7 changed files with 120 additions and 296 deletions
+4 -1
View File
@@ -136,7 +136,10 @@ func safeDialContext(ctx context.Context, network, addr string) (net.Conn, error
}
}
// Dial the first resolved IP directly to avoid a second lookup.
d := &net.Dialer{}
// Timeout: 10s per the design (PLAN.md); the outer http.Client has a 30s
// total timeout, but the dial itself needs an independent bound so a slow
// TCP connect does not consume the full 30s without cancellation.
d := &net.Dialer{Timeout: 10 * time.Second}
return d.DialContext(ctx, network, net.JoinHostPort(addrs[0].IP.String(), port))
}