Refuse every form of path or address in a wait's words, a contradicting healthy answer, and a malformed wait at Waiting
mesh/merge-gate pass: builds mesh-sdk, sent nowhere; no bus step; every machine composes with the change as it did without (4 of 4 compose)
mesh/repo-check pass: its merge-check.sh passed, each part in its toolchain: merge-check.sh (typescript), go/merge-check.sh (go)
mesh/delivery delivered
mesh/delivery-group group feat/386-a-wait-for-the-operator delivered: every member is delivered
mesh/merge-gate pass: builds mesh-sdk, sent nowhere; no bus step; every machine composes with the change as it did without (4 of 4 compose)
mesh/repo-check pass: its merge-check.sh passed, each part in its toolchain: merge-check.sh (typescript), go/merge-check.sh (go)
mesh/delivery delivered
mesh/delivery-group group feat/386-a-wait-for-the-operator delivered: every member is delivered
From the review of mesh-sdk#18: quoted and bracketed paths, home and relative paths, IPv6, host and port, UNC and drive paths passed the check.
This commit is contained in:
+24
-3
@@ -70,14 +70,31 @@ func Waiting(why string, waits ...Wait) Answer {
|
||||
if len(waits) == 0 {
|
||||
return Unhealthy(orSaid(why, "it says it waits") + " (and names nothing it waits for)")
|
||||
}
|
||||
for _, w := range waits {
|
||||
if err := w.Check(); err != nil {
|
||||
return Unhealthy(orSaid(why, "it says it waits") + " (" + err.Error() + ")")
|
||||
}
|
||||
}
|
||||
return Answer{State: StateWaits, Why: why, Waits: waits}
|
||||
}
|
||||
|
||||
// name is a secret's or a setting's name: what a manifest may declare.
|
||||
var name = regexp.MustCompile(`^[a-z0-9][a-z0-9-]*$`)
|
||||
|
||||
// looksLikeAddress finds an IPv4 address, a URL, or a path in words meant for the operator.
|
||||
var looksLikeAddress = regexp.MustCompile(`\b[0-9]{1,3}(\.[0-9]{1,3}){3}\b|://|(^|\s)/[^\s]`)
|
||||
// looksLikeAddress finds what the operator's words never carry: a URL, an IPv4 or IPv6 address, a host and port, a
|
||||
// path (absolute, from a home or relative, on its own or after a bracket or a quote), a UNC path or a drive path.
|
||||
// It cannot find a value typed in plain words ("the password hunter2"): a module never puts one there, and the
|
||||
// words are its own, not the operator's.
|
||||
var looksLikeAddress = regexp.MustCompile(strings.Join([]string{
|
||||
`://`,
|
||||
`\b[0-9]{1,3}(\.[0-9]{1,3}){3}\b`,
|
||||
`[0-9A-Fa-f]{0,4}::[0-9A-Fa-f]{0,4}`,
|
||||
`\b[0-9A-Fa-f]{1,4}(:[0-9A-Fa-f]{1,4}){3,}\b`,
|
||||
`\b[A-Za-z0-9.-]+:[0-9]{1,5}\b`,
|
||||
`(^|[\s(\[{"'\x60])[~.]{0,2}/`,
|
||||
`\\\\`,
|
||||
`\b[A-Za-z]:\\`,
|
||||
}, "|"))
|
||||
|
||||
// Check says why a wait cannot be read, or nil.
|
||||
func (w Wait) Check() error {
|
||||
@@ -132,8 +149,12 @@ func Read(result []byte) (Answer, error) {
|
||||
a.State = StateUnhealthy
|
||||
}
|
||||
case StateHealthy:
|
||||
if !a.Healthy {
|
||||
return Unhealthy(fmt.Sprintf("it answered the state healthy and healthy false, which contradict each other (%s)",
|
||||
orSaid(a.Why, "and said nothing more"))), nil
|
||||
}
|
||||
// A healthy module waits for nothing: a wait beside healthy is a contradiction, and is dropped.
|
||||
a.Healthy, a.Waits = true, nil
|
||||
a.Waits = nil
|
||||
case StateUnhealthy:
|
||||
a.Healthy = false
|
||||
case StateWaits:
|
||||
|
||||
@@ -116,3 +116,35 @@ func TestNotAnAnswerIsAnError(t *testing.T) {
|
||||
t.Fatal("a string read as an answer")
|
||||
}
|
||||
}
|
||||
|
||||
func TestEveryFormOfPathOrAddressIsRefused(t *testing.T) {
|
||||
for _, words := range []string{
|
||||
"the source (/mnt/games)", `the source "/mnt/games"`, "the folder ~/games", "the folder ./games",
|
||||
"2001:db8::1", "fe80::1%eth0", "2001:0db8:0000:0000:0000:0000:0000:0001", "nas.lan:445", "192.0.2.7:445",
|
||||
`\\nas\games`, `C:\Users\x`, "smb://nas/games", "198.51.100.4",
|
||||
} {
|
||||
w := Wait{Part: "the source games", Secret: "smb-password-games", What: "the password of " + words}
|
||||
if err := w.Check(); err == nil {
|
||||
t.Errorf("%q passed as words for the operator", words)
|
||||
}
|
||||
}
|
||||
for _, words := range []string{"the password of the source games", "the username of the source games-2", "the API key, issued by the vendor"} {
|
||||
w := Wait{Part: "the source games", Secret: "smb-password-games", What: words}
|
||||
if err := w.Check(); err != nil {
|
||||
t.Errorf("%q refused: %v", words, err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestHealthyStateWithHealthyFalseIsUnhealthy(t *testing.T) {
|
||||
got, err := Read([]byte(`{"state":"healthy","healthy":false,"why":"x"}`))
|
||||
if err != nil || got.State != StateUnhealthy || !strings.Contains(got.Why, "contradict") {
|
||||
t.Fatalf("read as %+v, %v", got, err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestWaitingChecksItsWaits(t *testing.T) {
|
||||
if a := Waiting("it waits", Wait{Part: "p", What: "w"}); a.State != StateUnhealthy || !strings.Contains(a.Why, "neither") {
|
||||
t.Fatalf("Waiting with a malformed wait is %+v", a)
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user