Fix NNTP IHAVE missing message ID (#24)

Co-authored-by: lazyGPT07 <lazyGPT07@users.noreply.github.com>
This commit is contained in:
lazyGPT07 2026-06-15 02:34:13 -06:00 committed by GitHub
parent 36c6e0e275
commit c480e62f39
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 47 additions and 2 deletions

View file

@ -362,6 +362,9 @@ func handleIHave(args []string, s *session, c *textproto.Conn) error {
if !s.backend.AllowPost() { if !s.backend.AllowPost() {
return ErrNotWanted return ErrNotWanted
} }
if len(args) < 1 {
return ErrSyntax
}
article, err := s.backend.GetArticle(nil, args[0]) article, err := s.backend.GetArticle(nil, args[0])
if article != nil { if article != nil {
return ErrNotWanted return ErrNotWanted

View file

@ -13,6 +13,7 @@ import (
type whitespaceBackend struct { type whitespaceBackend struct {
group *nntp.Group group *nntp.Group
allowPost bool
} }
func (b *whitespaceBackend) ListGroups(max int) ([]*nntp.Group, error) { func (b *whitespaceBackend) ListGroups(max int) ([]*nntp.Group, error) {
@ -40,7 +41,7 @@ func (b *whitespaceBackend) Authenticate(user, pass string) (Backend, error) {
return b, nil return b, nil
} }
func (b *whitespaceBackend) AllowPost() bool { return false } func (b *whitespaceBackend) AllowPost() bool { return b.allowPost }
func (b *whitespaceBackend) Post(article *nntp.Article) error { func (b *whitespaceBackend) Post(article *nntp.Article) error {
return errors.New("posting disabled") return errors.New("posting disabled")
@ -85,3 +86,44 @@ func TestProcessCollapsesRepeatedCommandWhitespace(t *testing.T) {
t.Fatal("server did not close after QUIT") t.Fatal("server did not close after QUIT")
} }
} }
func TestIHaveWithoutMessageIDReturnsSyntaxError(t *testing.T) {
backend := &whitespaceBackend{
group: &nntp.Group{Name: "pfs.general", Posting: nntp.PostingPermitted},
allowPost: true,
}
server := NewServer(backend)
clientConn, serverConn := net.Pipe()
defer clientConn.Close()
done := make(chan struct{})
go func() {
server.Process(serverConn)
close(done)
}()
client := textproto.NewConn(clientConn)
defer client.Close()
if line, err := client.ReadLine(); err != nil || !strings.HasPrefix(line, "200 ") {
t.Fatalf("greeting = %q, %v", line, err)
}
if err := client.PrintfLine("IHAVE"); err != nil {
t.Fatalf("send IHAVE: %v", err)
}
if line, err := client.ReadLine(); err != nil || !strings.HasPrefix(line, "501 ") {
t.Fatalf("IHAVE without message-id = %q, %v; want 501", line, err)
}
if err := client.PrintfLine("QUIT"); err != nil {
t.Fatalf("send QUIT: %v", err)
}
if line, err := client.ReadLine(); err != nil || !strings.HasPrefix(line, "205 ") {
t.Fatalf("QUIT = %q, %v; want 205", line, err)
}
select {
case <-done:
case <-time.After(time.Second):
t.Fatal("server did not close after QUIT")
}
}