Refuse a PRIVMSG or NOTICE whose body or meta has the wrong type (closes #245)
check / check (push) Canceled after 0s
check / check (push) Canceled after 0s
Over the HTTP API, a PRIVMSG or NOTICE body was checked only by decoding it into a list of strings. JSON null decodes into an empty string there, and meta was not checked at all, so a null line, or a meta that is not an object, reached every recipient. handlePrivmsg now answers 400 invalid request body, before anything else, when body is present and is not an array of strings, or meta is present and is not an object. A missing or empty body still gets ERR_NOTEXTTOSEND. README.md says so. Model: opus-5-5
This commit is contained in:
@@ -1141,6 +1141,16 @@ func (hdlr *Handlers) handlePrivmsg(
|
||||
meta json.RawMessage,
|
||||
bodyLines func() []string,
|
||||
) {
|
||||
if !validBodyAndMeta(body, meta) {
|
||||
hdlr.respondError(
|
||||
writer, request,
|
||||
"invalid request body",
|
||||
http.StatusBadRequest,
|
||||
)
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
if target == "" {
|
||||
hdlr.enqueueNumeric(
|
||||
request.Context(), clientID,
|
||||
@@ -1189,6 +1199,40 @@ func (hdlr *Handlers) handlePrivmsg(
|
||||
)
|
||||
}
|
||||
|
||||
// validBodyAndMeta reports whether body, when present, is an
|
||||
// array of strings and meta, when present, is an object.
|
||||
// Decoding into []string would turn a null line into "", so
|
||||
// each line is decoded as any and checked. A null body or
|
||||
// meta decodes without an error into nil.
|
||||
func validBodyAndMeta(body, meta json.RawMessage) bool {
|
||||
if body != nil {
|
||||
var lines []any
|
||||
|
||||
err := json.Unmarshal(body, &lines)
|
||||
if err != nil || lines == nil {
|
||||
return false
|
||||
}
|
||||
|
||||
for _, line := range lines {
|
||||
_, isString := line.(string)
|
||||
if !isString {
|
||||
return false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if meta != nil {
|
||||
var fields map[string]any
|
||||
|
||||
err := json.Unmarshal(meta, &fields)
|
||||
if err != nil || fields == nil {
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
// respondIRCError enqueues a numeric error reply, notifies
|
||||
// the broker, and sends HTTP 200 with {"status":"error"}.
|
||||
func (hdlr *Handlers) respondIRCError(
|
||||
|
||||
Reference in New Issue
Block a user