Fix panic when ARTICLE command goes w/o args

This commit is contained in:
ChronosX88 2022-02-05 19:03:54 +03:00
parent e6f8e39a8e
commit 1197ded1aa
Signed by: ChronosXYZ
GPG Key ID: 085A69A82C8C511A
3 changed files with 45 additions and 18 deletions

View File

@ -132,6 +132,9 @@ func (sb *SQLiteBackend) GetArticle(messageID string) (models.Article, error) {
if err := sb.db.Get(&a, "SELECT * FROM articles WHERE json_extract(articles.header, '$.Message-Id[0]') = ?", messageID); err != nil {
return a, err
}
if err := sb.db.Get(&a.ArticleNumber, "SELECT article_number FROM articles_to_groups WHERE article_id = ?", a.ID); err != nil {
return a, err
}
return a, json.Unmarshal([]byte(a.HeaderRaw), &a.Header)
}
@ -140,6 +143,7 @@ func (sb *SQLiteBackend) GetArticleByNumber(g *models.Group, num int) (models.Ar
if err := sb.db.Get(&a, "SELECT articles.* FROM articles INNER JOIN articles_to_groups atg on atg.article_id = articles.id WHERE atg.article_number = ? AND atg.group_id = ?", num, g.ID); err != nil {
return a, err
}
a.ArticleNumber = num
return a, json.Unmarshal([]byte(a.HeaderRaw), &a.Header)
}

View File

@ -7,10 +7,12 @@ import (
)
type Article struct {
ID int `db:"id"`
CreatedAt time.Time `db:"created_at"`
HeaderRaw string `db:"header"`
Header textproto.MIMEHeader `db:"-"`
Body string `db:"body"`
Thread sql.NullString `db:"thread"`
ID int `db:"id"`
CreatedAt time.Time `db:"created_at"`
HeaderRaw string `db:"header"`
Body string `db:"body"`
Thread sql.NullString `db:"thread"`
Header textproto.MIMEHeader `db:"-"`
ArticleNumber int `db:"-"`
}

View File

@ -197,6 +197,15 @@ func (h *Handler) handleGroup(s *Session, command string, arguments []string, id
s.currentGroup = &g
if lowWaterMark != 0 {
a, err := h.backend.GetArticleByNumber(&g, lowWaterMark)
if err != nil {
return err
}
s.currentArticle = &a
}
return s.tconn.PrintfLine(protocol.NNTPResponse{
Code: 211,
Message: fmt.Sprintf("%d %d %d %s", articlesCount, lowWaterMark, highWaterMark, g.GroupName),
@ -395,28 +404,35 @@ func (h *Handler) handleArticle(s *Session, command string, arguments []string,
s.tconn.StartResponse(id)
defer s.tconn.EndResponse(id)
if len(arguments) == 0 && s.currentArticle == nil {
return s.tconn.PrintfLine(protocol.NNTPResponse{Code: 420, Message: "No current article selected"}.String())
var err error
getByArticleNum := true
if len(arguments) == 0 {
if s.currentArticle == nil {
return s.tconn.PrintfLine(protocol.NNTPResponse{Code: 420, Message: "No current article selected"}.String())
}
getByArticleNum = false
}
if len(arguments) > 1 {
return s.tconn.PrintfLine(protocol.ErrSyntaxError.String())
}
getByArticleNum := true
num, err := strconv.Atoi(arguments[0])
if err != nil {
getByArticleNum = false
var num int
if getByArticleNum {
num, err = strconv.Atoi(arguments[0])
if err != nil {
getByArticleNum = false
}
}
if getByArticleNum && s.currentGroup == nil {
return s.tconn.PrintfLine(protocol.NNTPResponse{Code: 412, Message: "No newsgroup selected"}.String())
}
var a models.Article
var a *models.Article
if getByArticleNum {
a, err = h.backend.GetArticleByNumber(s.currentGroup, num)
article, err := h.backend.GetArticleByNumber(s.currentGroup, num)
if err != nil {
if err == sql.ErrNoRows {
return s.tconn.PrintfLine(protocol.NNTPResponse{Code: 423, Message: "No article with that number"}.String())
@ -424,8 +440,10 @@ func (h *Handler) handleArticle(s *Session, command string, arguments []string,
return err
}
}
} else {
a, err = h.backend.GetArticle(arguments[0])
a = &article
s.currentArticle = &article
} else if len(arguments) > 0 {
article, err := h.backend.GetArticle(arguments[0])
if err != nil {
if err == sql.ErrNoRows {
return s.tconn.PrintfLine(protocol.NNTPResponse{Code: 430, Message: "No Such Article Found"}.String())
@ -433,10 +451,13 @@ func (h *Handler) handleArticle(s *Session, command string, arguments []string,
return err
}
}
a = &article
s.currentArticle = &article
} else {
a = s.currentArticle
num = s.currentArticle.ArticleNumber
}
s.currentArticle = &a
switch command {
case protocol.CommandArticle:
{