When an encoded-word fails to decode, the failure branch reset the
token length with `token->len -= tok_len`. For the base64 path that is
wrong: rspamd_cryptobox_base64_decode writes its *outlen argument
(tok_len) even on failure, so the subtraction no longer restores the
original offset and leaves token->len above pos. The bytes between the
partial decode and the grown GByteArray capacity are uninitialised and
were flushed into the decoded header value.
Reset token->len to the saved pos offset in both failure branches
instead, discarding the token cleanly.
token->len = pos + r;
}
else {
- /* Cannot decode qp */
- token->len -= tok_len;
+ /* Cannot decode qp: discard token, restore saved offset */
+ token->len = pos;
}
}
else {
token->len = pos + tok_len;
}
else {
- /* Cannot decode */
- token->len -= tok_len;
+ /*
+ * Cannot decode: discard this token. We must reset
+ * to the saved offset rather than subtracting tok_len:
+ * rspamd_cryptobox_base64_decode writes its *outlen
+ * argument (tok_len) even on failure, so the value is
+ * no longer the original token size. Leaving token->len
+ * above pos would expose uninitialised heap bytes from
+ * the freshly grown GByteArray in the decoded header.
+ */
+ token->len = pos;
}
}