From 7fe98ccfee20daf38b49c358f1d29f7df77dd7b4 Mon Sep 17 00:00:00 2001 From: Dmytro Maluka Date: Sun, 18 Aug 2024 15:10:07 +0200 Subject: [PATCH] calcHash: Remove checking file size Let calcHash() unconditionally hash whatever buffer it is asked to hash, and let its callers explicitly check if the buffer is too large before calling calcHash(). This makes things simpler and less error-prone (no extra source of truth about whether the file is too large, we don't need to remember to check if calcHash() fails, we can be sure calcHash() will actually update the provided hash), and actually faster (since just calculating the buffer size, i.e. adding line lengths, is faster than md5 calculation). In particular, this fixes the following bugs: 1. Since ReOpen() doesn't check calcHash() return value, if the reloaded file is too large while the old version of the file is not, calcHash() returns ErrFileTooLarge and doesn't update origHash, so so Modified() returns true since the reloaded file's md5 sum doesn't match the old origHash, so micro wrongly reports the newly reloaded file as modified. 2. Since Modified() doesn't check calcHash() return value, Modified() may return false positives or false negatives if the buffer has *just* become too large so calcHash() returns ErrFileTooLarge and doesn't update `buff`. --- internal/buffer/buffer.go | 23 +++++------------------ internal/buffer/settings.go | 14 ++++++-------- 2 files changed, 11 insertions(+), 26 deletions(-) diff --git a/internal/buffer/buffer.go b/internal/buffer/buffer.go index c1bf6f10..1d899663 100644 --- a/internal/buffer/buffer.go +++ b/internal/buffer/buffer.go @@ -64,10 +64,6 @@ var ( // BTStdout is a buffer that only writes to stdout // when closed BTStdout = BufType{6, false, true, true} - - // ErrFileTooLarge is returned when the file is too large to hash - // (fastdirty is automatically enabled) - ErrFileTooLarge = errors.New("File is too large to hash") ) // SharedBuffer is a struct containing info that is shared among buffers @@ -649,32 +645,23 @@ func (b *Buffer) Size() int { } // calcHash calculates md5 hash of all lines in the buffer -func calcHash(b *Buffer, out *[md5.Size]byte) error { +func calcHash(b *Buffer, out *[md5.Size]byte) { h := md5.New() - size := 0 if len(b.lines) > 0 { - n, _ := h.Write(b.lines[0].data) - size += n + h.Write(b.lines[0].data) for _, l := range b.lines[1:] { if b.Endings == FFDos { - n, _ = h.Write([]byte{'\r', '\n'}) + h.Write([]byte{'\r', '\n'}) } else { - n, _ = h.Write([]byte{'\n'}) + h.Write([]byte{'\n'}) } - size += n - n, _ = h.Write(l.data) - size += n + h.Write(l.data) } } - if size > LargeFileThreshold { - return ErrFileTooLarge - } - h.Sum((*out)[:0]) - return nil } func parseDefFromFile(f config.RuntimeFile, header *highlight.Header) *highlight.Def { diff --git a/internal/buffer/settings.go b/internal/buffer/settings.go index e934da2f..9e76697c 100644 --- a/internal/buffer/settings.go +++ b/internal/buffer/settings.go @@ -12,15 +12,13 @@ func (b *Buffer) SetOptionNative(option string, nativeValue interface{}) error { if option == "fastdirty" { if !nativeValue.(bool) { - if !b.isModified { - e := calcHash(b, &b.origHash) - if e == ErrFileTooLarge { - b.Settings["fastdirty"] = true - } + if b.Size() > LargeFileThreshold { + b.Settings["fastdirty"] = true } else { - b.origHash = [md5.Size]byte{} - if b.Size() > LargeFileThreshold { - b.Settings["fastdirty"] = true + if !b.isModified { + calcHash(b, &b.origHash) + } else { + b.origHash = [md5.Size]byte{} } } }