diff options
author | Robin Jarry <robin@jarry.cc> | 2023-06-29 09:21:04 +0200 |
---|---|---|
committer | Robin Jarry <robin@jarry.cc> | 2023-07-15 17:51:33 +0200 |
commit | 8dcb58c81782a30f06794227cf9a1b54928134e3 (patch) | |
tree | e11226a2a9b4d4a164879ea4755823c6ac08436a | |
parent | 7a674312b6f006be7c1241b10cf9063841aa1d9c (diff) | |
download | aerc-8dcb58c81782a30f06794227cf9a1b54928134e3.tar.gz |
wizard: properly initialize configuration
The wizard constructs an AccountConfig object by hand without
initializing default values. This causes a crash when replying to an
email (rr) just after completing the account creation:
~/.config/aerc/aerc.conf not found, installing the system default~/.config/aerc/binds.conf not found, installing the system defaultpanic: runtime error: invalid memory address or nil pointer dereference [recovered]
panic: runtime error: invalid memory address or nil pointer dereference
[signal SIGSEGV: segmentation violation code=0x1 addr=0x90 pc=0x5d1550]
...
regexp.(*Regexp).doExecute(0x7fc1089aa108?, {0x0?, 0x0?}, {0x0?, 0x0?, 0xc000fe5408?}, {0xc000698120?, 0x10?}, 0xad3a40?, 0x2, ...)
regexp/exec.go:527 +0x90
regexp.(*Regexp).FindString(0x44e372?, {0xc000698120, 0x27})
regexp/regexp.go:852 +0x6c
git.sr.ht/~rjarry/aerc/commands/msg.trimLocalizedRe({0xc000698120, 0x27}, 0xc00003e420?)
git.sr.ht/~rjarry/aerc/commands/msg/reply.go:332 +0x36
git.sr.ht/~rjarry/aerc/commands/msg.reply.Execute({}, 0xc0002ba180, {0xc0002f8800?, 0x2, 0x2})
git.sr.ht/~rjarry/aerc/commands/msg/reply.go:157 +0x765
...
Extract the account parsing and initialization into a function. Reuse
that function in both accounts.conf parsing and the wizard.
Fixes: 40cc540357d9 ("reply: allow to override localized Re regexp in configuration")
Reported-by: Mechiel Lukkien <mechiel@ueber.net>
Signed-off-by: Robin Jarry <robin@jarry.cc>
Tested-by: Andrew Yu <andrew@andrewyu.org>
-rw-r--r-- | config/accounts.go | 93 | ||||
-rw-r--r-- | config/binds.go | 2 | ||||
-rw-r--r-- | config/config.go | 2 | ||||
-rw-r--r-- | widgets/account-wizard.go | 18 |
4 files changed, 56 insertions, 59 deletions
diff --git a/config/accounts.go b/config/accounts.go index eec6ca44..a8c2b9bf 100644 --- a/config/accounts.go +++ b/config/accounts.go @@ -146,27 +146,11 @@ func parseAccounts(root string, accts []string) error { continue } sec := file.Section(_sec) - account := AccountConfig{ - Name: _sec, - Params: make(map[string]string), - } - if err = MapToStruct(sec, &account, true); err != nil { + + account, err := ParseAccountConfig(_sec, sec) + if err != nil { return err } - for key, val := range sec.KeysHash() { - backendSpecific := true - typ := reflect.TypeOf(account) - for i := 0; i < typ.NumField(); i++ { - field := typ.Field(i) - if field.Tag.Get("ini") == key { - backendSpecific = false - break - } - } - if backendSpecific { - account.Params[key] = val - } - } if _, ok := account.Params["smtp-starttls"]; ok && !starttls_warned { Warnings = append(Warnings, Warning{ Title: "accounts.conf: smtp-starttls is deprecated", @@ -178,31 +162,9 @@ If you want to disable STARTTLS, append +insecure to the schema. }) starttls_warned = true } - if account.Source == "" { - return fmt.Errorf("Expected source for account %s", _sec) - } - if account.From == nil { - return fmt.Errorf("Expected from for account %s", _sec) - } - if len(account.Headers) > 0 { - defaults := []string{ - "date", - "subject", - "from", - "sender", - "reply-to", - "to", - "cc", - "bcc", - "in-reply-to", - "message-id", - "references", - } - account.Headers = append(account.Headers, defaults...) - } log.Debugf("accounts.conf: [%s] from = %s", account.Name, account.From) - Accounts = append(Accounts, &account) + Accounts = append(Accounts, account) } if len(accts) > 0 { // Sort accounts struct to match the specified order, if we @@ -218,6 +180,53 @@ If you want to disable STARTTLS, append +insecure to the schema. return nil } +func ParseAccountConfig(name string, section *ini.Section) (*AccountConfig, error) { + account := AccountConfig{ + Name: name, + Params: make(map[string]string), + } + if err := MapToStruct(section, &account, true); err != nil { + return nil, err + } + for key, val := range section.KeysHash() { + backendSpecific := true + typ := reflect.TypeOf(account) + for i := 0; i < typ.NumField(); i++ { + field := typ.Field(i) + if field.Tag.Get("ini") == key { + backendSpecific = false + break + } + } + if backendSpecific { + account.Params[key] = val + } + } + if account.Source == "" { + return nil, fmt.Errorf("Expected source for account %s", name) + } + if account.From == nil { + return nil, fmt.Errorf("Expected from for account %s", name) + } + if len(account.Headers) > 0 { + defaults := []string{ + "date", + "subject", + "from", + "sender", + "reply-to", + "to", + "cc", + "bcc", + "in-reply-to", + "message-id", + "references", + } + account.Headers = append(account.Headers, defaults...) + } + return &account, nil +} + func (a *AccountConfig) ParseSource(sec *ini.Section, key *ini.Key) (string, error) { var remote RemoteConfig remote.Value = key.String() diff --git a/config/binds.go b/config/binds.go index 55814cd2..b219adad 100644 --- a/config/binds.go +++ b/config/binds.go @@ -101,7 +101,7 @@ var Binds = defaultBindsConfig() func parseBinds(root string) error { filename := path.Join(root, "binds.conf") if _, err := os.Stat(filename); errors.Is(err, os.ErrNotExist) { - fmt.Printf("%s not found, installing the system default", filename) + fmt.Printf("%s not found, installing the system default\n", filename) if err := installTemplate(root, "binds.conf"); err != nil { return err } diff --git a/config/config.go b/config/config.go index d70bcfe0..4ace7d26 100644 --- a/config/config.go +++ b/config/config.go @@ -98,7 +98,7 @@ func LoadConfigFromFile(root *string, accts []string) error { // if it doesn't exist copy over the template, then load if _, err := os.Stat(filename); errors.Is(err, os.ErrNotExist) { - fmt.Printf("%s not found, installing the system default", filename) + fmt.Printf("%s not found, installing the system default\n", filename) if err := installTemplate(*root, "aerc.conf"); err != nil { return err } diff --git a/widgets/account-wizard.go b/widgets/account-wizard.go index 9ad814b5..8c9739e6 100644 --- a/widgets/account-wizard.go +++ b/widgets/account-wizard.go @@ -13,7 +13,6 @@ import ( "sync" "time" - "github.com/emersion/go-message/mail" "github.com/gdamore/tcell/v2" "github.com/go-ini/ini" "github.com/kyoh86/xdg" @@ -531,25 +530,14 @@ func (wizard *AccountWizard) finish(tutorial bool) { } } - from, err := mail.ParseAddress(sec.Key("from").String()) + account, err := config.ParseAccountConfig(sec.Name(), sec) if err != nil { wizard.errorFor(nil, err) return } + config.Accounts = append(config.Accounts, account) - account := config.AccountConfig{ - Name: sec.Name(), - Default: "INBOX", - From: from, - Source: sec.Key("source").String(), - Outgoing: config.RemoteConfig{Value: sec.Key("outgoing").String()}, - } - if wizard.copySent { - account.CopyTo = "Sent" - } - config.Accounts = append(config.Accounts, &account) - - view, err := NewAccountView(wizard.aerc, &account, wizard.aerc, nil) + view, err := NewAccountView(wizard.aerc, account, wizard.aerc, nil) if err != nil { wizard.aerc.NewTab(errorScreen(err.Error()), account.Name) return |