address-book-cmd: be more lenient with errors

Instead of failing completely when address-book-cmd returns an invalid
line, ignore the line and report a warning in the logs.

Do not wait for 100 "valid" addresses before bailing out as the command
could only output garbage in large quantities. The issue of the command
not printing any new line characters still exists. We could address this
but I think it would be overkill.

Reported-by: Bence Ferdinandy <bence@ferdinandy.com>
Signed-off-by: Robin Jarry <robin@jarry.cc>
Tested-by: Bence Ferdinandy <bence@ferdinandy.com>
This commit is contained in:
Robin Jarry 2022-11-02 11:44:24 +01:00
parent 7565a96525
commit 14ceca3200

View file

@ -162,31 +162,39 @@ func (c *Completer) getAddressCmd(s string) (*exec.Cmd, error) {
func readCompletions(r io.Reader) ([]string, error) { func readCompletions(r io.Reader) ([]string, error) {
buf := bufio.NewReader(r) buf := bufio.NewReader(r)
completions := []string{} completions := []string{}
for { for i := 0; i < maxCompletionLines; i++ {
line, err := buf.ReadString('\n') line, err := buf.ReadString('\n')
if errors.Is(err, io.EOF) { if errors.Is(err, io.EOF) {
return completions, nil return completions, nil
} else if err != nil { } else if err != nil {
return nil, err return nil, err
} }
if strings.TrimSpace(line) == "" {
// skip empty lines
continue
}
parts := strings.SplitN(line, "\t", 3) parts := strings.SplitN(line, "\t", 3)
addr, err := mail.ParseAddress(strings.TrimSpace(parts[0])) addr, err := mail.ParseAddress(strings.TrimSpace(parts[0]))
if err != nil { if err != nil {
return nil, err logging.Warnf(
"line %d: %#v: could not parse address: %v",
line, err)
continue
} }
if len(parts) > 1 { if len(parts) > 1 {
addr.Name = strings.TrimSpace(parts[1]) addr.Name = strings.TrimSpace(parts[1])
} }
decoded, err := decodeMIME(addr.String()) decoded, err := decodeMIME(addr.String())
if err != nil { if err != nil {
return nil, fmt.Errorf("could not decode MIME string: %w", err) logging.Warnf(
"line %d: %#v: could not decode MIME string: %v",
i+1, line, err)
continue
} }
completions = append(completions, decoded) completions = append(completions, decoded)
if len(completions) >= maxCompletionLines { }
return completions, tooManyLines return completions, tooManyLines
} }
}
}
func decodeMIME(s string) (string, error) { func decodeMIME(s string) (string, error) {
var d mime.WordDecoder var d mime.WordDecoder