From fd3eda0da228d2417b8b7f9007533e214d7a5e80 Mon Sep 17 00:00:00 2001 From: Lukasz Kasprzak Date: Tue, 18 Aug 2026 18:08:20 +0200 Subject: fix(clectio-gen): write the verse keys gzipped as well as plain clectio's Makefile unpacks gen/verses_
.keys from the COMMITTED .gz, and its clean target deletes the plain file. clectio-gen wrote only the plain one, so regenerating the tables without separately re-gzipping the keys left gen/liturgy_.h indexing verses the packed text did not hold. clectio then dereferenced a NULL verse pointer. That shipped: 1246 of the 10957 EF dates in the 2025-2054 range segfaulted, 11% of the calendar. OF was unaffected -- its tables had not been regenerated since the keys were last packed. The two artefacts are generated together, so they are now written together and cannot drift. OF's keys are byte-different after this (Go's gzip, not gzip(1)) but content-identical, verified. --- cmd/clectio-gen/main.go | 26 +++++++++++++++++++++++++- 1 file changed, 25 insertions(+), 1 deletion(-) (limited to 'cmd/clectio-gen/main.go') diff --git a/cmd/clectio-gen/main.go b/cmd/clectio-gen/main.go index 422cd34..9897642 100644 --- a/cmd/clectio-gen/main.go +++ b/cmd/clectio-gen/main.go @@ -23,6 +23,7 @@ package main import ( "bufio" + "compress/gzip" "flag" "fmt" "os" @@ -256,18 +257,41 @@ func resolveRef(sec liturgy.Section, form string) string { return bible.OFRef(cit, "vulgate") } +// writeKeys writes the verse keys BOTH plain and gzipped, because clectio's +// Makefile unpacks gen/verses_.keys from the COMMITTED .gz -- and its +// clean target deletes the plain file. Emitting only the plain one therefore +// left a regenerated gen/liturgy_.h indexing verses the packed text did +// not hold, and clectio dereferenced a NULL verse: 1246 of the 10957 EF dates +// segfaulted in the version that shipped that way. The two artefacts are +// generated together, so they are now written together. func writeKeys(path string, keys []string) { + writeKeysTo(path, keys, false) + writeKeysTo(path+".gz", keys, true) +} + +func writeKeysTo(path string, keys []string, compress bool) { f, err := os.Create(path) if err != nil { fmt.Fprintln(os.Stderr, err) os.Exit(1) } defer f.Close() - w := bufio.NewWriter(f) + var w *bufio.Writer + var gz *gzip.Writer + if compress { + gz, _ = gzip.NewWriterLevel(f, gzip.BestCompression) + defer gz.Close() + w = bufio.NewWriter(gz) + } else { + w = bufio.NewWriter(f) + } for _, k := range keys { w.WriteString(k + "\n") } w.Flush() + if gz != nil { + gz.Flush() + } } func cstr(s string) string { -- cgit v1.3