diff --git a/imap/command/fetch.go b/imap/command/fetch.go index 63d10b89..ae4e50f6 100644 --- a/imap/command/fetch.go +++ b/imap/command/fetch.go @@ -58,7 +58,7 @@ func (FetchCommandParser) FromParser(p *rfcparser.Parser) (Payload, error) { return nil, err } - switch attribute { + switch attribute.Value { case "all": attributes = []FetchAttribute{&FetchAttributeAll{}} case "full": @@ -78,13 +78,13 @@ func (FetchCommandParser) FromParser(p *rfcparser.Parser) (Payload, error) { return &Fetch{SeqSet: seqSet, Attributes: attributes}, nil } -func parseFetchAttributeName(p *rfcparser.Parser) (string, error) { +func parseFetchAttributeName(p *rfcparser.Parser) (rfcparser.String, error) { att, err := p.CollectBytesWhileMatches(rfcparser.TokenTypeChar) if err != nil { - return "", err + return rfcparser.String{}, err } - return strings.ToLower(string(att.Value)), nil + return att.IntoString().ToLower(), nil } func parseFetchAttributes(p *rfcparser.Parser) ([]FetchAttribute, error) { @@ -141,7 +141,7 @@ func parseFetchAttribute(p *rfcparser.Parser) (FetchAttribute, error) { return attr, nil } -func handleFetchAttribute(name string, p *rfcparser.Parser) (FetchAttribute, error) { +func handleFetchAttribute(name rfcparser.String, p *rfcparser.Parser) (FetchAttribute, error) { /* fetch-att = "ENVELOPE" / "FLAGS" / "INTERNALDATE" / "RFC822" [".HEADER" / ".SIZE" / ".TEXT"] / @@ -149,7 +149,7 @@ func handleFetchAttribute(name string, p *rfcparser.Parser) (FetchAttribute, err "BODY" section ["<" number "." nz-number ">"] / "BODY.PEEK" section ["<" number "." nz-number ">"] */ - switch name { + switch name.Value { case "envelope": return &FetchAttributeEnvelope{}, nil case "flags": @@ -165,7 +165,7 @@ func handleFetchAttribute(name string, p *rfcparser.Parser) (FetchAttribute, err case "body": return handleBodyFetchAttribute(p) default: - return nil, fmt.Errorf("unknown fetch attribute '%v'", name) + return nil, p.MakeErrorAtOffset(fmt.Sprintf("unknown fetch attribute '%v'", name.Value), name.Offset) } } @@ -185,7 +185,7 @@ func handleRFC822FetchAttribute(p *rfcparser.Parser) (FetchAttribute, error) { return nil, err } - switch attribute { + switch attribute.Value { case "header": return &FetchAttributeRFC822Header{}, nil case "size": @@ -193,7 +193,7 @@ func handleRFC822FetchAttribute(p *rfcparser.Parser) (FetchAttribute, error) { case "text": return &FetchAttributeRFC822Text{}, nil default: - return nil, fmt.Errorf("unknown fetch attribute 'RFC822.%v", attribute) + return nil, p.MakeErrorAtOffset(fmt.Sprintf("unknown fetch attribute 'RFC822.%v", attribute.Value), attribute.Offset) } } @@ -337,9 +337,9 @@ func parseSectionText(p *rfcparser.Parser) (BodySection, error) { return nil, err } - textStr := strings.ToLower(string(text.Value)) + textStr := text.IntoString().ToLower() - if textStr == "mime" { + if textStr.Value == "mime" { return &BodySectionMIME{}, nil } @@ -352,16 +352,16 @@ func parseSectionMsgText(p *rfcparser.Parser) (BodySection, error) { return nil, err } - textStr := strings.ToLower(string(text.Value)) + textStr := text.IntoString().ToLower() return handleSectionMessageText(textStr, p) } -func handleSectionMessageText(text string, p *rfcparser.Parser) (BodySection, error) { +func handleSectionMessageText(text rfcparser.String, p *rfcparser.Parser) (BodySection, error) { // section-msgtext = "HEADER" / "HEADER.FIELDS" [".NOT"] SP header-list / // "TEXT" // ; top-level or MESSAGE/RFC822 part - switch text { + switch text.Value { case "header": if ok, err := p.Matches(rfcparser.TokenTypePeriod); err != nil { return nil, err @@ -374,7 +374,7 @@ func handleSectionMessageText(text string, p *rfcparser.Parser) (BodySection, er case "text": return &BodySectionText{}, nil default: - return nil, fmt.Errorf("unknown section msg text value '%v'", text) + return nil, p.MakeErrorAtOffset(fmt.Sprintf("unknown section msg text value '%v'", text.Value), text.Offset) } } diff --git a/imap/command/search.go b/imap/command/search.go index 757fe1b1..2a6d133a 100644 --- a/imap/command/search.go +++ b/imap/command/search.go @@ -134,7 +134,7 @@ func (scp *SearchCommandParser) FromParser(p *rfcparser.Parser) (Payload, error) } if len(keys) == 0 { - return nil, fmt.Errorf("no search keys specified") + return nil, p.MakeError("no search keys specified") } return &Search{ diff --git a/imap/command/uid.go b/imap/command/uid.go index 72ca7d0d..c46735b6 100644 --- a/imap/command/uid.go +++ b/imap/command/uid.go @@ -41,6 +41,8 @@ func (u *UIDCommandParser) FromParser(p *rfcparser.Parser) (Payload, error) { var commandBytes []byte + offset := p.PreviousToken().Offset + for { if ok, err := p.Matches(rfcparser.TokenTypeChar); err != nil { return nil, err @@ -60,7 +62,7 @@ func (u *UIDCommandParser) FromParser(p *rfcparser.Parser) (Payload, error) { builder, ok := u.commands[command] if !ok { - return nil, fmt.Errorf("unknown uid command '%v'", command) + return nil, p.MakeErrorAtOffset(fmt.Sprintf("unknown uid command '%v'", command), offset) } payload, err := builder.FromParser(p)