Commit 6b74d7d61 for clamav.net
commit 6b74d7d617fdcc41f5cdedd24c3fc8486b755096
Author: metsw24-max <metsw24@gmail.com>
Date: Tue Jun 30 01:26:14 2026 +0530
Libclamav: fix compressed XLM STRING reads (#1735)
The compressed STRING record path read from data[6] while using
biff_header.length - 3 as the precision. A maximum-length record can
therefore read three bytes past the record body and off the end of the
BIFF record buffer.
For OPC_STRING, the string bytes start at offset 3, after the
two-byte character count and one-byte flags field. Read compressed
strings from that offset, matching the UTF-16 path, and clamp the
printed length to the bytes present so a malformed character count
cannot over-read the record.
diff --git a/libclamav/xlm_extract.c b/libclamav/xlm_extract.c
index f424184a4..be9197f56 100644
--- a/libclamav/xlm_extract.c
+++ b/libclamav/xlm_extract.c
@@ -4886,8 +4886,16 @@ cl_error_t cli_extract_xlm_macros_and_images(const char *dir, cli_ctx *ctx, char
}
if (!(flags & 0x1)) {
- // String is compressed
- len = fprintf(out_file, " - \"%.*s\"", (int)(biff_header.length - 3), &data[6]);
+ // String is compressed (one byte per character). The character data
+ // begins at offset 3, after the 2-byte character count and the flags
+ // byte, the same offset the UTF-16 branch below reads from. Clamp the
+ // printed length to the bytes actually present in the record so a
+ // malformed character count cannot read past the record buffer.
+ if (string_length > biff_header.length - 3) {
+ string_length = biff_header.length - 3;
+ }
+
+ len = fprintf(out_file, " - \"%.*s\"", (int)string_length, &data[3]);
if (len < 0) {
cli_dbgmsg("[cli_extract_xlm_macros_and_images] Error formatting STRING record message with ANSI content\n");