Skip to content

Commit 216a356

Browse files
committed
fix(kncloudevents): truncate error body before base64 encode
Avoid panic when failed delivery returns a large HTTP body and the knativeerrordata extension is populated for dead letter sinks. Fixes #9504 Signed-off-by: Aaron <amark@g.jct.ac.il>
1 parent 2153953 commit 216a356

1 file changed

Lines changed: 24 additions & 7 deletions

File tree

‎pkg/kncloudevents/event_dispatcher.go‎

Lines changed: 24 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -583,16 +583,33 @@ func dispatchExecutionInfoTransformers(destination *apis.URL, dispatchExecutionI
583583

584584
destination = sanitizeURL(destination)
585585

586-
// Encodes response body as base64 for the resulting length.
587-
bodyLen := len(httpResponseBody)
588-
encodedLen := base64.StdEncoding.EncodedLen(bodyLen)
589-
if encodedLen > attributes.KnativeErrorDataExtensionMaxLength {
590-
encodedLen = attributes.KnativeErrorDataExtensionMaxLength
591-
}
586+
// Encodes response body as base64, truncated so the encoded form fits in the
587+
// knativeerrordata extension (KnativeErrorDataExtensionMaxLength characters).
588+
maxEncodedLen := attributes.KnativeErrorDataExtensionMaxLength
589+
maxRawLen := maxRawLenForBase64(maxEncodedLen)
590+
if len(httpResponseBody) > maxRawLen {
591+
httpResponseBody = httpResponseBody[:maxRawLen]
592+
}
593+
encodedLen := base64.StdEncoding.EncodedLen(len(httpResponseBody))
592594
encodedBuf := make([]byte, encodedLen)
593595
base64.StdEncoding.Encode(encodedBuf, httpResponseBody)
594596

595-
return attributes.KnativeErrorTransformers(*destination.URL(), dispatchExecutionInfo.ResponseCode, string(encodedBuf[:encodedLen]))
597+
return attributes.KnativeErrorTransformers(*destination.URL(), dispatchExecutionInfo.ResponseCode, string(encodedBuf))
598+
}
599+
600+
// maxRawLenForBase64 returns the largest source length whose standard base64 encoding
601+
// uses at most maxEncodedLen bytes.
602+
func maxRawLenForBase64(maxEncodedLen int) int {
603+
if maxEncodedLen <= 0 {
604+
return 0
605+
}
606+
// EncodedLen(n) = 4 * ((n + 2) / 3)
607+
for n := (maxEncodedLen / 4) * 3; n >= 0; n-- {
608+
if base64.StdEncoding.EncodedLen(n) <= maxEncodedLen {
609+
return n
610+
}
611+
}
612+
return 0
596613
}
597614

598615
// isFailure returns true if the status code is not a successful HTTP status.

0 commit comments

Comments
 (0)