Skip to content

Commit 22f209e

Browse files
czoIgrobert.kubac
authored andcommitted
Fix parsing invalid EPSV response - Fixes #451
1 parent 6602e98 commit 22f209e

File tree

2 files changed

+46
-1
lines changed

2 files changed

+46
-1
lines changed

client_test.go

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import (
55
"fmt"
66
"io"
77
"net"
8+
"net/textproto"
89
"syscall"
910
"testing"
1011
"time"
@@ -417,3 +418,47 @@ func TestDialWithDialer(t *testing.T) {
417418

418419
assert.Equal(t, true, dialerCalled)
419420
}
421+
422+
func runEPSVWithResponse(response string) (int, error) {
423+
client, server := net.Pipe()
424+
tpServer := textproto.NewConn(server)
425+
go func() {
426+
defer tpServer.Close()
427+
_, _ = tpServer.ReadLine()
428+
tpServer.PrintfLine("229 %s", response)
429+
}()
430+
431+
c := &ServerConn{options: &dialOptions{}, conn: textproto.NewConn(client)}
432+
defer c.conn.Close()
433+
return c.epsv()
434+
}
435+
436+
func TestEPSV_Parse_Valid(t *testing.T) {
437+
port, err := runEPSVWithResponse("Entering Extended Passive Mode (|||4242|)")
438+
assert.NoError(t, err)
439+
assert.Equal(t, 4242, port)
440+
}
441+
442+
func TestEPSV_Parse_MissingTrailingPipe_ShouldError(t *testing.T) {
443+
defer func() {
444+
if r := recover(); r != nil {
445+
t.Fatalf("epsv() panicked, want graceful error: %v", r)
446+
}
447+
}()
448+
_, err := runEPSVWithResponse("Entering Extended Passive Mode (|||4242)")
449+
if err == nil {
450+
t.Fatalf("expected error for malformed EPSV response, got nil")
451+
}
452+
}
453+
454+
func TestEPSV_Parse_MissingPortBetweenPipes_ShouldError(t *testing.T) {
455+
defer func() {
456+
if r := recover(); r != nil {
457+
t.Fatalf("epsv() panicked, want graceful error: %v", r)
458+
}
459+
}()
460+
_, err := runEPSVWithResponse("Entering Extended Passive Mode (||||)")
461+
if err == nil {
462+
t.Fatalf("expected error for malformed EPSV response, got nil")
463+
}
464+
}

ftp.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -484,7 +484,7 @@ func (c *ServerConn) epsv() (port int, err error) {
484484

485485
start := strings.Index(line, "|||")
486486
end := strings.LastIndex(line, "|")
487-
if start == -1 || end == -1 {
487+
if start == -1 || start+3 >= end {
488488
return 0, errors.New("invalid EPSV response format")
489489
}
490490
port, err = strconv.Atoi(line[start+3 : end])

0 commit comments

Comments
 (0)