aboutsummaryrefslogtreecommitdiff
path: root/internal/admin/undo.go
diff options
context:
space:
mode:
Diffstat (limited to 'internal/admin/undo.go')
-rw-r--r--internal/admin/undo.go17
1 files changed, 15 insertions, 2 deletions
diff --git a/internal/admin/undo.go b/internal/admin/undo.go
index 3001c8b..5683f13 100644
--- a/internal/admin/undo.go
+++ b/internal/admin/undo.go
@@ -754,12 +754,21 @@ func (us *UndoStack) load() {
toChanges := func(entries []undoEntry) []ChangeDesc {
out := make([]ChangeDesc, 0, len(entries))
for _, e := range entries {
+ // A before-image recorded as nil is persisted as "" and would
+ // reload as a non-nil empty slice, defeating requireSnapshot and
+ // letting undo truncate the file to zero bytes. Map it back to nil
+ // so the guard fires. An intentionally empty before-image is also
+ // refused, which is safer than zeroing a live file.
+ oldContent := []byte(e.OldContent)
+ if e.OldContent == "" {
+ oldContent = nil
+ }
c := ChangeDesc{
Time: e.Time,
Description: e.Description,
FilePath: e.FilePath,
NewFilePath: e.NewFilePath,
- OldContent: []byte(e.OldContent),
+ OldContent: oldContent,
NewContent: []byte(e.NewContent),
IsDelete: e.IsDelete,
IsCreate: e.IsCreate,
@@ -767,10 +776,14 @@ func (us *UndoStack) load() {
IDMap: e.IDMap,
}
for _, ef := range e.ExtraFiles {
+ oldExtra := []byte(ef.OldContent)
+ if ef.OldContent == "" {
+ oldExtra = nil
+ }
c.ExtraFiles = append(c.ExtraFiles, ExtraFile{
FilePath: ef.FilePath,
NewFilePath: ef.NewFilePath,
- OldContent: []byte(ef.OldContent),
+ OldContent: oldExtra,
NewContent: []byte(ef.NewContent),
IsDelete: ef.IsDelete,
IsCreate: ef.IsCreate,