feat(13-01): add the prohibited rule and dated-download and notification masks
- lagoon.ValidateRequest supports Laravel 9 prohibited (!required, not
implicit); with no catalog line its message is validation.prohibited
- tide compares Content-Disposition with real calendar dates masked on both
sides; a different name, an invalid date or a one-sided date still diffs
- tide.NormalizePublications masks a Carbon +00:00 $.data.payload.created_at
and an uncaptured positive integer $.data.payload.id as {{id}}
- the album-date test's outside-album sibling moves off payload.created_at,
which now has its own mask
- READMEs and docs describe the rule and both masks
This commit is contained in:
@@ -6,8 +6,10 @@ import (
|
||||
"fmt"
|
||||
"mime"
|
||||
"net/http"
|
||||
"regexp"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
"unicode"
|
||||
"unicode/utf8"
|
||||
)
|
||||
@@ -81,6 +83,9 @@ func compareHeaders(want, got, extra map[string]string) []Diff {
|
||||
if gv == wv {
|
||||
continue
|
||||
}
|
||||
if ck == "Content-Disposition" && sameDispositionButDates(wv, gv) {
|
||||
continue
|
||||
}
|
||||
if gv == "" {
|
||||
gv = "<missing>"
|
||||
}
|
||||
@@ -290,3 +295,32 @@ func quotePrintable(b []byte) string {
|
||||
buf.WriteByte('"')
|
||||
return buf.String()
|
||||
}
|
||||
|
||||
// dispositionDateRe finds YYYY-MM-DD tokens in a Content-Disposition value,
|
||||
// such as the date in a download name built from the current day.
|
||||
var dispositionDateRe = regexp.MustCompile(`\b\d{4}-\d{2}-\d{2}\b`)
|
||||
|
||||
// maskDispositionDates replaces every date token with one placeholder and
|
||||
// reports how many it replaced. ok is false when a token is not a real
|
||||
// calendar date, so the caller falls back to the byte comparison.
|
||||
func maskDispositionDates(s string) (masked string, n int, ok bool) {
|
||||
ok = true
|
||||
masked = dispositionDateRe.ReplaceAllStringFunc(s, func(m string) string {
|
||||
if _, err := time.Parse("2006-01-02", m); err != nil {
|
||||
ok = false
|
||||
return m
|
||||
}
|
||||
n++
|
||||
return "{{date}}"
|
||||
})
|
||||
return masked, n, ok
|
||||
}
|
||||
|
||||
// sameDispositionButDates reports whether two Content-Disposition values
|
||||
// differ only in their dates: both carry the same number of real calendar
|
||||
// dates and are equal once those are masked. Anything else stays a Diff.
|
||||
func sameDispositionButDates(want, got string) bool {
|
||||
wm, wn, wok := maskDispositionDates(want)
|
||||
gm, gn, gok := maskDispositionDates(got)
|
||||
return wok && gok && wn > 0 && wn == gn && wm == gm
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user