From a54f6c73f2fbd6ca4ac502cf5729f72083b3ea65 Mon Sep 17 00:00:00 2001 From: Deepak-negi11 Date: Sun, 18 Oct 2026 23:17:24 +0530 Subject: [PATCH] [FIX] Stop reading past the end of the credits text in WebVTT, SAMI and SMPTE-TT write_stringz_as_webvtt/sami/smptett unescape "\n" into a NUL, which writes fewer bytes (pos_w) than the input length (len), but then read the segments back while begin < unescaped + len. With --startcreditstext 'Alpha\nBravo\nCharlie' this reads past the written data and off the end of the buffer (AddressSanitizer: heap-buffer-overflow in encode_line). Bound the read-back by pos_w. The pos_r < len - 1 check in the escape test is not a fix (at the last character string[pos_r + 1] is the terminating NUL); it keeps the code the same as ccx_encoders_srt.c after #2128. The SAMI and SMPTE-TT functions also write every normal text subtitle. Their output doesn't change: without a literal "\n", pos_w equals len. The SSA writer has the same bug; it is left to #2316, which rewrites that function. --- src/lib_ccx/ccx_encoders_sami.c | 4 ++-- src/lib_ccx/ccx_encoders_smptett.c | 4 ++-- src/lib_ccx/ccx_encoders_webvtt.c | 4 ++-- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/lib_ccx/ccx_encoders_sami.c b/src/lib_ccx/ccx_encoders_sami.c index 212f66504..23f458278 100644 --- a/src/lib_ccx/ccx_encoders_sami.c +++ b/src/lib_ccx/ccx_encoders_sami.c @@ -47,7 +47,7 @@ int write_stringz_as_sami(char *string, struct encoder_ctx *context, LLONG ms_st // Scan for \n in the string and replace it with a 0 while (pos_r < len) { - if (string[pos_r] == '\\' && string[pos_r + 1] == 'n') + if (pos_r < len - 1 && string[pos_r] == '\\' && string[pos_r + 1] == 'n') { unescaped[pos_w] = 0; pos_r += 2; @@ -62,7 +62,7 @@ int write_stringz_as_sami(char *string, struct encoder_ctx *context, LLONG ms_st unescaped[pos_w] = 0; // Now read the unescaped string (now several string'z and write them) unsigned char *begin = unescaped; - while (begin < unescaped + len) + while (begin < unescaped + pos_w) { unsigned int u = encode_line(context, el, begin); if (context->encoding != CCX_ENC_UNICODE) diff --git a/src/lib_ccx/ccx_encoders_smptett.c b/src/lib_ccx/ccx_encoders_smptett.c index 794f770ae..0919b392c 100644 --- a/src/lib_ccx/ccx_encoders_smptett.c +++ b/src/lib_ccx/ccx_encoders_smptett.c @@ -61,7 +61,7 @@ void write_stringz_as_smptett(char *string, struct encoder_ctx *context, LLONG m // Scan for \n in the string and replace it with a 0 while (pos_r < len) { - if (string[pos_r] == '\\' && string[pos_r + 1] == 'n') + if (pos_r < len - 1 && string[pos_r] == '\\' && string[pos_r + 1] == 'n') { unescaped[pos_w] = 0; pos_r += 2; @@ -76,7 +76,7 @@ void write_stringz_as_smptett(char *string, struct encoder_ctx *context, LLONG m unescaped[pos_w] = 0; // Now read the unescaped string (now several string'z and write them) unsigned char *begin = unescaped; - while (begin < unescaped + len) + while (begin < unescaped + pos_w) { unsigned int u = encode_line(context, el, begin); if (context->encoding != CCX_ENC_UNICODE) diff --git a/src/lib_ccx/ccx_encoders_webvtt.c b/src/lib_ccx/ccx_encoders_webvtt.c index fe03a541c..b1bce7293 100644 --- a/src/lib_ccx/ccx_encoders_webvtt.c +++ b/src/lib_ccx/ccx_encoders_webvtt.c @@ -155,7 +155,7 @@ int write_stringz_as_webvtt(char *string, struct encoder_ctx *context, LLONG ms_ // Scan for \n in the string and replace it with a 0 while (pos_r < len) { - if (string[pos_r] == '\\' && string[pos_r + 1] == 'n') + if (pos_r < len - 1 && string[pos_r] == '\\' && string[pos_r + 1] == 'n') { unescaped[pos_w] = 0; pos_r += 2; @@ -170,7 +170,7 @@ int write_stringz_as_webvtt(char *string, struct encoder_ctx *context, LLONG ms_ unescaped[pos_w] = 0; // Now read the unescaped string (now several string'z and write them) unsigned char *begin = unescaped; - while (begin < unescaped + len) + while (begin < unescaped + pos_w) { unsigned int u = encode_line(context, el, begin); if (context->encoding != CCX_ENC_UNICODE)