aboutsummaryrefslogtreecommitdiff
path: root/internal/liturgy/fetch.go
diff options
context:
space:
mode:
Diffstat (limited to 'internal/liturgy/fetch.go')
-rw-r--r--internal/liturgy/fetch.go12
1 files changed, 12 insertions, 0 deletions
diff --git a/internal/liturgy/fetch.go b/internal/liturgy/fetch.go
index 5447552..32eaaad 100644
--- a/internal/liturgy/fetch.go
+++ b/internal/liturgy/fetch.go
@@ -33,6 +33,14 @@ const userAgent = "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 " +
// ewangelia.py's fetch() for the original behaviour this mirrors.
var publishedRe = regexp.MustCompile(`id="\w*0all"`)
+// dateRe is the same YYYY-MM-DD shape internal/cli's dateRe validates
+// against. Load checks opts.Date against it before building any filesystem
+// path (jsonPath/htmlPath below are built by string concatenation, so an
+// unvalidated Date is a path-traversal vector) -- defense-in-depth so every
+// caller (web, cli, tui) is protected even if a future caller forgets to
+// validate its own input first.
+var dateRe = regexp.MustCompile(`^\d{4}-\d{2}-\d{2}$`)
+
// Options controls how Load resolves a day's readings.
type Options struct {
// Date is the day to load, formatted YYYY-MM-DD.
@@ -71,6 +79,10 @@ func cacheDir() string {
// has been harvested, and only surfaces the original fetch error if
// that fallback also fails.
func Load(opts Options) ([]Section, error) {
+ if !dateRe.MatchString(opts.Date) {
+ return nil, fmt.Errorf("invalid date %q: want YYYY-MM-DD", opts.Date)
+ }
+
if opts.Offline {
return LoadOffline(opts.Date)
}