pico
created pr with
94.1
cmds
checkout latest patchset:
ssh pr.pico.sh print 94 | git am -3checkout any patchset in a patch request:
ssh pr.pico.sh print 94.[rev] | git am -3add changes to patch request:
git format-patch main --stdout | ssh pr.pico.sh pr add 94
Patchset
94.1
fix(send): sftp memory leak
Eric Bower
2025-12-16T04:32:44ZThe SFTP Fileread method returned a ReadAndReaderAtCloser (backed by storage objects) without ever closing it, leaking connections/file descriptors on every SFTP download. The fix reads the content into memory and immediately closes the underlying reader via defer.
Semantic diff summary
0 added,
1 modified,
0 signature changed,
0 removed
across 1 analyzed file
+15
-1
pkg/send/protocols/sftp/handler.go
#
| ... | ... | @@ -138,8 +138,22 @@ func (f *handler) Fileread(r *sftp.Request) (io.ReaderAt, error) { | |
| 138 | 138 | ||
| 139 | 139 | fileEntry := toFileEntry(r) | |
| 140 | 140 | _, reader, err := f.writeHandler.Read(f.session, fileEntry) | |
| 141 | + | if err != nil { | |
| 142 | + | return nil, err | |
| 143 | + | } | |
| 144 | + | ||
| 145 | + | defer func() { | |
| 146 | + | if c, ok := reader.(io.Closer); ok { | |
| 147 | + | _ = c.Close() | |
| 148 | + | } | |
| 149 | + | }() | |
| 150 | + | ||
| 151 | + | buf, err := io.ReadAll(reader) | |
| 152 | + | if err != nil { | |
| 153 | + | return nil, err | |
| 154 | + | } | |
| 141 | 155 | ||
| 142 | - | return reader, err | |
| 156 | + | return bytes.NewReader(buf), nil | |
| 143 | 157 | } | |
| 144 | 158 | ||
| 145 | 159 | type handlererr struct { |