Skip to content

Commit c3dab40

Browse files
authored
Fix parsing invalid EPSV response - Fixes #451
1 parent 3f092e0 commit c3dab40

File tree

2 files changed

+45
-1
lines changed

2 files changed

+45
-1
lines changed

client_test.go

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -417,3 +417,47 @@ func TestDialWithDialer(t *testing.T) {
417417

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

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)