diff options
| author | Lukasz Kasprzak <lukas@labunix.xyz> | 2026-09-14 23:07:57 +0200 |
|---|---|---|
| committer | Lukasz Kasprzak <lukas@labunix.xyz> | 2026-09-14 23:07:57 +0200 |
| commit | c66a842ce4679a3ffa5504dad39b1402bea75e9f (patch) | |
| tree | 9e9db5e569b9f16a4ca4e66d0a5b0f456a186ece /internal/journal | |
| parent | b013e5fb87580e4cab0d85a0d2c8bb402c610413 (diff) | |
| download | krino-0.0.7.tar.gz krino-0.0.7.zip | |
plan 10 re-check: cut run column, damaged undo run, emptied directory cleanup, text turning binary, explain flags, interrupt docsv0.0.7
Diffstat (limited to 'internal/journal')
| -rw-r--r-- | internal/journal/read.go | 6 | ||||
| -rw-r--r-- | internal/journal/read_test.go | 29 |
2 files changed, 33 insertions, 2 deletions
diff --git a/internal/journal/read.go b/internal/journal/read.go index 48cd6b0..9099c0d 100644 --- a/internal/journal/read.go +++ b/internal/journal/read.go @@ -172,10 +172,12 @@ func Entries(path, runID string) ([]Entry, error) { // runFieldOf best-effort extracts a line's Run column even when the line // otherwise fails to parse, so Entries can tell whether an unparsable line -// belonged to the run it was asked for. +// belonged to the run it was asked for. The column counts only when a tab +// ends it: a line cut inside it holds a prefix of some run's ID, which names +// no run (plan 10 re-check R2). func runFieldOf(line string) (string, bool) { f := strings.SplitN(line, "\t", 3) - if len(f) < 2 { + if len(f) < 3 { return "", false } return unescape(f[1]), true diff --git a/internal/journal/read_test.go b/internal/journal/read_test.go index fb6f77f..676b2bd 100644 --- a/internal/journal/read_test.go +++ b/internal/journal/read_test.go @@ -702,3 +702,32 @@ func TestReversedStepsCountsEveryUndoOfARun(t *testing.T) { } } } + +// TestEntriesRefusesALineCutInsideItsRunColumn: a crash that cuts the last +// line inside its run column leaves a prefix of some run's ID - it cannot +// be called another run's line, so inside this run's window it refuses the +// run (plan 10 re-check R2). +func TestEntriesRefusesALineCutInsideItsRunColumn(t *testing.T) { + path := filepath.Join(t.TempDir(), "krino.log") + w, _ := Open(path) + at := time.Date(2026, 9, 11, 10, 2, 3, 0, time.UTC) + run := "20260911T100203-ab12" + for _, e := range []Entry{ + {Time: at, Run: run, Action: "run-start", Status: "ok"}, + {Time: at, Run: run, Dir: "dl", File: "x.pdf", Step: 1, Action: "copy", Status: "ok", Src: "/a/x.pdf", Dst: "/b/x.pdf"}, + } { + if err := w.Append(e); err != nil { + t.Fatal(err) + } + } + w.Close() + f, err := os.OpenFile(path, os.O_APPEND|os.O_WRONLY, 0) + if err != nil { + t.Fatal(err) + } + f.WriteString("2026-09-11T10:02:04Z\t20260911T10") + f.Close() + if got, err := Entries(path, run); err == nil { + t.Errorf("Entries = %+v, no error; a line cut inside its run column must refuse the run", got) + } +} |
