aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRobin Jarry <robin@jarry.cc>2023-06-29 09:21:04 +0200
committerRobin Jarry <robin@jarry.cc>2023-07-15 17:51:33 +0200
commit8dcb58c81782a30f06794227cf9a1b54928134e3 (patch)
treee11226a2a9b4d4a164879ea4755823c6ac08436a
parent7a674312b6f006be7c1241b10cf9063841aa1d9c (diff)
downloadaerc-8dcb58c81782a30f06794227cf9a1b54928134e3.tar.gz
aerc-8dcb58c81782a30f06794227cf9a1b54928134e3.zip
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.go93
-rw-r--r--config/binds.go2
-rw-r--r--config/config.go2
-rw-r--r--widgets/account-wizard.go18
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