Summary
CodeQL reports an unhandled writable file close in the in-process Moon+ capture fallback copy path. This is separate from path-injection/XSS work and can be fixed as a small reliability branch.
CodeQL alert
Affected code
internal/adapters/moon/capture.go: copyFile(src, dst string) error opens dst with os.OpenFile(..., os.O_CREATE|os.O_EXCL|os.O_WRONLY, 0o444), defers out.Close(), copies with io.Copy, and returns only the copy error.
- Existing tests:
internal/adapters/moon/moon_test.go, especially TestMoon_CaptureMode.
Suggested fix direction
- Make
copyFile return close/sync errors from the writable output file.
- Use the named-return-error defer pattern recommended by CodeQL, for example:
- close input separately, ignoring or preserving only relevant read-side close behavior;
- after
io.Copy, call out.Close() explicitly and return that error if copy succeeded;
- optionally call
out.Sync() before close if durability is important for fixture capture.
- Ensure errors from
out.Close() are not discarded. This is important because buffered filesystem write errors can surface only at close time.
- Keep semantics of capture mode best-effort:
captureUpload should log failures and not fail the WebDAV upload.
Documentation references
Required tests
- Add or update a unit test around
copyFile/capture fallback where practical.
- Preserve
TestMoon_CaptureMode behavior.
- Run
go test -count=1 ./internal/adapters/moon/....
- Run
pre-commit run --all-files.
Acceptance criteria
Summary
CodeQL reports an unhandled writable file close in the in-process Moon+ capture fallback copy path. This is separate from path-injection/XSS work and can be fixed as a small reliability branch.
CodeQL alert
go/unhandled-writable-file-close: alert Harden development tools for CodeQL path and log injection findings #23 —internal/adapters/moon/capture.go:137— https://github.com/JediRhymeTrix/readsync/security/code-scanning/23Affected code
internal/adapters/moon/capture.go:copyFile(src, dst string) erroropensdstwithos.OpenFile(..., os.O_CREATE|os.O_EXCL|os.O_WRONLY, 0o444), defersout.Close(), copies withio.Copy, and returns only the copy error.internal/adapters/moon/moon_test.go, especiallyTestMoon_CaptureMode.Suggested fix direction
copyFilereturn close/sync errors from the writable output file.io.Copy, callout.Close()explicitly and return that error if copy succeeded;out.Sync()before close if durability is important for fixture capture.out.Close()are not discarded. This is important because buffered filesystem write errors can surface only at close time.captureUploadshould log failures and not fail the WebDAV upload.Documentation references
os.File.Closedocumentation: https://pkg.go.dev/os#File.Closeio.Copydocumentation: https://pkg.go.dev/io#CopyRequired tests
copyFile/capture fallback where practical.TestMoon_CaptureModebehavior.go test -count=1 ./internal/adapters/moon/....pre-commit run --all-files.Acceptance criteria
copyFilereturns an error when output close fails.