Skip to content

Fix golangci-lint warnings#49

Merged
anfragment merged 4 commits intomasterfrom
anfragment/golint-fix
Feb 24, 2026
Merged

Fix golangci-lint warnings#49
anfragment merged 4 commits intomasterfrom
anfragment/golint-fix

Conversation

@anfragment
Copy link
Member

What does this PR do?

Fixes golangci-lint errors:

  • Adds nosec comments for false positive gosec warnings
  • Addresses QF1012 by replacing WriteString(fmt.Sprintf(...)) with fmt.Fprintf

How did you verify your code works?

golangci-lint run

What are the relevant issues?

@anfragment anfragment self-assigned this Feb 24, 2026
@coderabbitai
Copy link

coderabbitai bot commented Feb 24, 2026

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 523c0ef and e675752.

📒 Files selected for processing (4)
  • .golangci.yml
  • asset/server.go
  • filterliststore/filterliststore.go
  • proxy/proxy.go
🚧 Files skipped from review as they are similar to previous changes (3)
  • proxy/proxy.go
  • asset/server.go
  • filterliststore/filterliststore.go
📜 Recent review details
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (2)
  • GitHub Check: Lint Go (macos-latest)
  • GitHub Check: Lint Go (windows-latest)
🔇 Additional comments (1)
.golangci.yml (1)

28-30: LGTM: gosec exclusion is clear and localized.

The added excludes entry under gosec settings is concise and consistent with the existing configuration structure.


Walkthrough

This pull request adds security linting annotations across multiple files to suppress false positives from gosec, refactors a cosmetic CSS injector using fmt.Fprintf, clarifies Windows API variable types as uintptr, and updates the golangci.yml configuration to exclude the G706 lint rule.

Changes

Cohort / File(s) Summary
Security Lint Annotations
asset/server.go, certstore/truststore_darwin.go, filterliststore/filterliststore.go, proxy/proxy.go
Added #nosec comments to suppress gosec false positives (G702, G703, G704) on internal asset reads, certificate operations, and proxy forwarding calls.
Code Refactoring
internal/asset/cosmetic/injector.go
Replaced fmt.Sprintf with builder.WriteString pattern with direct fmt.Fprintf call to the builder for generating CSS selectors.
Windows API Type Refinement
sysproxy/system_windows.go
Changed internetOptionSettingsChanged and internetOptionRefresh variables to explicit uintptr type; updated callInternetSetOption function signature to accept uintptr instead of int.
Linting Configuration
.golangci.yml
Added gosec exclusion for G706 (log injection) rule to suppress false positives in linters.settings.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~10 minutes

Suggested reviewers

  • spellcascade
🚥 Pre-merge checks | ✅ 2 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 33.33% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Title check ✅ Passed The title 'Fix golangci-lint warnings' accurately summarizes the main purpose of the PR, which is addressing linting errors and warnings.
Description check ✅ Passed The PR description covers all required template sections with relevant details: explains the purpose (fixing golangci-lint errors), describes verification method (golangci-lint run), and includes a relevant issues section.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
  • 📝 Generate docstrings (stacked PR)
  • 📝 Generate docstrings (commit on current branch)
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch anfragment/golint-fix

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick comments (2)
filter/filter.go (1)

165-165: Slightly inaccurate justification comment on line 165.

The err here comes from resolveInclude(base, after), where after is parsed from filter list body content — which is downloaded from external URLs, making it technically external input (not just "URL parsing"). The err.Error() string may embed the raw after value.

The suppression itself is still correct (log injection via error messages from URL parsing is a very low-severity concern in this context), but the comment could be more accurate:

-log.Printf("filter: error resolving include: %v", err) // `#nosec` G706 -- err is from URL parsing, not arbitrary user input
+log.Printf("filter: error resolving include: %v", err) // `#nosec` G706 -- err is from URL resolution of a filter list include directive; not from web request input
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@filter/filter.go` at line 165, Update the justification comment on the log
line that logs errors from resolveInclude(base, after) to accurately state that
`after` is derived from filter list body content downloaded from external URLs
(i.e., external input) and that `err.Error()` may embed that raw input; keep the
// `#nosec` G706 suppression but change the text to note the source and why the
log is still acceptable (low-severity risk), referencing the call to
resolveInclude and the log.Printf("filter: error resolving include: %v", err)
site so reviewers can verify the reasoning.
asset/server.go (1)

157-157: G705 suppression is correct, but the comment could be more precise.

body is the content of an internal asset (CSS/JS), which is correct. However, the selection key (refererURL.Hostname()) does originate from the Referer/Origin request header, which is user-controlled. The XSS risk is still absent because the asset content is authored internally—the hostname only acts as a lookup key—but the comment "body is from internal asset storage, not user input" doesn't acknowledge this nuance.

Consider refining to something like:

-w.Write(body) // `#nosec` G705 -- body is from internal asset storage, not user input
+w.Write(body) // `#nosec` G705 -- body content is from internal asset storage; hostname is user-supplied but only used as a lookup key, not reflected in the response
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@asset/server.go` at line 157, Update the G705 suppression comment next to the
w.Write(body) call to clearly state that the written `body` is internal asset
content (CSS/JS) authored by the application and not user input, and also note
that the lookup key (`refererURL.Hostname()` derived from the Referer/Origin
header) is user-controlled but only used to select the asset and never
incorporated into the response body or rendered without validation; place this
clarified comment adjacent to the `w.Write(body)` line and, if present, near the
code that computes `refererURL.Hostname()` so reviewers can see the distinction
between the internal asset content and the external lookup key.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Nitpick comments:
In `@asset/server.go`:
- Line 157: Update the G705 suppression comment next to the w.Write(body) call
to clearly state that the written `body` is internal asset content (CSS/JS)
authored by the application and not user input, and also note that the lookup
key (`refererURL.Hostname()` derived from the Referer/Origin header) is
user-controlled but only used to select the asset and never incorporated into
the response body or rendered without validation; place this clarified comment
adjacent to the `w.Write(body)` line and, if present, near the code that
computes `refererURL.Hostname()` so reviewers can see the distinction between
the internal asset content and the external lookup key.

In `@filter/filter.go`:
- Line 165: Update the justification comment on the log line that logs errors
from resolveInclude(base, after) to accurately state that `after` is derived
from filter list body content downloaded from external URLs (i.e., external
input) and that `err.Error()` may embed that raw input; keep the // `#nosec` G706
suppression but change the text to note the source and why the log is still
acceptable (low-severity risk), referencing the call to resolveInclude and the
log.Printf("filter: error resolving include: %v", err) site so reviewers can
verify the reasoning.

ℹ️ Review info

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 1164417 and 38beb08.

📒 Files selected for processing (8)
  • asset/server.go
  • certstore/truststore_darwin.go
  • filter/filter.go
  • filterliststore/filterliststore.go
  • internal/asset/cosmetic/injector.go
  • networkrules/rulemodifiers/removejsconstant/removejsconstant.go
  • proxy/proxy.go
  • proxy/websocket.go
📜 Review details
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: Lint Go (macos-latest)
🧰 Additional context used
🧠 Learnings (1)
📚 Learning: 2026-01-29T18:08:36.912Z
Learnt from: anfragment
Repo: ZenPrivacy/zen-core PR: 40
File: filter/filter.go:209-212
Timestamp: 2026-01-29T18:08:36.912Z
Learning: Filter list rules in ad-blocking filter lists (e.g., EasyList, uBlock Origin lists) are typically short and don't exceed 300 characters in length. The default bufio.Scanner buffer size (64KB) is sufficient for parsing these rules without needing to be increased.

Applied to files:

  • filter/filter.go
🧬 Code graph analysis (3)
proxy/proxy.go (2)
internal/redacted/redacted_nonprod.go (1)
  • Redacted (10-12)
internal/redacted/redacted_prod.go (1)
  • Redacted (8-10)
filter/filter.go (2)
internal/redacted/redacted_nonprod.go (1)
  • Redacted (10-12)
internal/redacted/redacted_prod.go (1)
  • Redacted (8-10)
proxy/websocket.go (2)
internal/redacted/redacted_nonprod.go (1)
  • Redacted (10-12)
internal/redacted/redacted_prod.go (1)
  • Redacted (8-10)
🔇 Additional comments (15)
proxy/websocket.go (1)

18-77: LGTM — all G706 suppressions are correctly applied.

Each annotated log.Printf passes user-controlled host data exclusively through redacted.Redacted(), which in production always returns "[REDACTED]", eliminating the log-injection risk that G706 flags.

networkrules/rulemodifiers/removejsconstant/removejsconstant.go (2)

117-117: LGTM — G706 suppression is accurate.

Using %q for res.Request.URL correctly escapes all special characters (newlines, ANSI codes) that would otherwise enable log injection.


134-134: LGTM — same rationale as line 117.

internal/asset/cosmetic/injector.go (1)

80-82: LGTM — fmt.Fprintf refactor is correct.

strings.Builder.Write never returns an error, so discarding fmt.Fprintf's return values is safe. The change is semantically identical to the previous builder.WriteString(fmt.Sprintf(...)) and correctly addresses QF1012.

filterliststore/filterliststore.go (2)

55-55: LGTM — G704 (SSRF) suppression is well-justified.

The URL originates from configured filter list entries, not from arbitrary incoming request parameters, making SSRF a non-concern here.


107-107: LGTM — G706 suppression is accurate.

%q applied to the []byte line produces a double-quoted, escape-encoded Go string, neutralising any embedded newlines or control characters.

asset/server.go (2)

110-110: LGTM — G706 suppression is correct.


142-142: LGTM.

proxy/proxy.go (5)

142-142: LGTM — G706 suppression correct.


160-165: LGTM — G704 (SSRF) suppression is appropriate for the proxy use-case.

The rationale — forwarding arbitrary requests is the proxy's core purpose — correctly distinguishes this from an inadvertent SSRF.


196-329: LGTM — all remaining G706 annotations in proxyConnect are correctly applied.

Every annotated log.Printf passes user-controlled values exclusively through redacted.Redacted(), eliminating the log-injection surface. The repeated use of the same suppression pattern is consistent with the rest of the codebase.


363-372: LGTM — G704 suppression at net.Dial is appropriate.


295-295: Add G704 suppression for consistency with line 160.

p.requestTransport.RoundTrip(req) at line 295 forwards the same category of proxy traffic as p.requestClient.Do(r) at line 160, which carries // #nosec G704 -- this is a proxy; forwarding requests is its purpose. For consistency and to guard against future gosec taint analysis changes, add the same suppression to line 295.

certstore/truststore_darwin.go (1)

97-140: LGTM — all four suppressions are correctly justified.

  • G204/G702 on both exec.Command calls: all arguments are either hardcoded or plistFile.Name() from os.CreateTemp — not user-controlled input.
  • G703 on os.ReadFile/os.WriteFile: path comes from os.CreateTemp, not from any request or user input.
filter/filter.go (1)

133-177: LGTM — all G706 suppressions in parseURL are correctly applied.

%q format on currentURL values escapes all special characters. The redacted.Redacted() calls at lines 243 and 285 eliminate user-controlled data from logs in production.

@anfragment anfragment merged commit 7d08925 into master Feb 24, 2026
15 checks passed
@anfragment anfragment deleted the anfragment/golint-fix branch February 24, 2026 16:29
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant