From d7e43d497448cc30a20c38b8d76388877f6918e7 Mon Sep 17 00:00:00 2001 From: Neko Box Coder <93885501+Neko-Box-Coder@users.noreply.github.com> Date: Tue, 22 Jul 2025 21:58:18 +0100 Subject: [PATCH] Adding missing file closes, rewriting safeWrite() to be more robust (#3807) --- internal/buffer/buffer.go | 1 + internal/buffer/save.go | 58 +++++++++++++++++++++++++-------------- 2 files changed, 38 insertions(+), 21 deletions(-) diff --git a/internal/buffer/buffer.go b/internal/buffer/buffer.go index 3b4be32d..5280a71f 100644 --- a/internal/buffer/buffer.go +++ b/internal/buffer/buffer.go @@ -537,6 +537,7 @@ func (b *Buffer) ReOpen() error { if err != nil { return err } + defer file.Close() enc, err := htmlindex.Get(b.Settings["encoding"].(string)) if err != nil { diff --git a/internal/buffer/save.go b/internal/buffer/save.go index 1fd56289..c7bed485 100644 --- a/internal/buffer/save.go +++ b/internal/buffer/save.go @@ -337,6 +337,27 @@ func (b *Buffer) saveToFile(filename string, withSudo bool, autoSave bool) error return err } +func (b *Buffer) writeBackup(path string) (string, error) { + backupDir := b.backupDir() + if _, err := os.Stat(backupDir); err != nil { + if !errors.Is(err, fs.ErrNotExist) { + return "", err + } + if err = os.Mkdir(backupDir, os.ModePerm); err != nil { + return "", err + } + } + + backupName := util.DetermineEscapePath(backupDir, path) + _, err := b.overwriteFile(backupName) + if err != nil { + os.Remove(backupName) + return "", err + } + + return backupName, nil +} + // safeWrite writes the buffer to a file in a "safe" way, preventing loss of the // contents of the file if it fails to write the new contents. // This means that the file is not overwritten directly but by writing to the @@ -353,28 +374,28 @@ func (b *Buffer) safeWrite(path string, withSudo bool, newFile bool) (int, error } }() - backupDir := b.backupDir() - if _, err := os.Stat(backupDir); err != nil { - if !errors.Is(err, fs.ErrNotExist) { - return 0, err - } - if err = os.Mkdir(backupDir, os.ModePerm); err != nil { - return 0, err - } - } - backupName := util.DetermineEscapePath(backupDir, path) - _, err = b.overwriteFile(backupName) + // Try to backup first before writing + backupName, err := b.writeBackup(path) if err != nil { - os.Remove(backupName) + file.Close() return 0, err } b.forceKeepBackup = true - size, err := file.Write(b) - if err != nil { - err = util.OverwriteError{err, backupName} - return size, err + size := 0 + { + // If we failed to write or close, keep the backup we made + size, err = file.Write(b) + if err != nil { + file.Close() + return 0, util.OverwriteError{err, backupName} + } + + err = file.Close() + if err != nil { + return 0, util.OverwriteError{err, backupName} + } } b.forceKeepBackup = false @@ -382,10 +403,5 @@ func (b *Buffer) safeWrite(path string, withSudo bool, newFile bool) (int, error os.Remove(backupName) } - err2 := file.Close() - if err2 != nil && err == nil { - err = err2 - } - return size, err }