From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from ffbox0-bg.ffmpeg.org (ffbox0-bg.ffmpeg.org [79.124.17.100]) by master.gitmailbox.com (Postfix) with ESMTPS id 13EFE4D256 for ; Fri, 14 Nov 2025 10:04:46 +0000 (UTC) Authentication-Results: ffbox; dkim=fail (body hash mismatch (got b'J6nAW6THHDQoxB5In9D3v0mlYk4fSFKp5nx1X8a8Ktg=', expected b'6gjJVGNIKoNmUDQBDSn9jrq2pLsVh/1VhdfHn+euQFI=')) header.d=ffmpeg.org header.i=@ffmpeg.org header.a=rsa-sha256 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ffmpeg.org; i=@ffmpeg.org; q=dns/txt; s=mail; t=1763114667; h=mime-version : to : date : message-id : reply-to : subject : list-id : list-archive : list-archive : list-help : list-owner : list-post : list-subscribe : list-unsubscribe : from : cc : content-type : content-transfer-encoding : from; bh=J6nAW6THHDQoxB5In9D3v0mlYk4fSFKp5nx1X8a8Ktg=; b=JNNqJBJ7kLTnILNvbmSWMbFJw7sy/ofA7Gw6pvJQqEMZ8r880kdRNq/J9j5SHOtE89AeX XimSCcmT3B1GwOXtBuF9EeWKbcBXAqTYNdqXzAx+c4fgQFrQ0wdxkdBDd/LUJEaSkreV6Tn YcnYF5KMXdB++COsDIbrPo8vBdZLnXStBkvL/ZwSePJuePuMbKnVH0xLwnWBeD3GkV/8rcX x/IDVm5bGY9nlTuIuHjkgLIs1FTnPtvQxPlPxNPllKAqZqGcmKyiyhDVqsf8PChiy/7+o5e zn/8+c8wgNXgwS0+qCF2iZ5XqhffZ+mxMR8aKLygjvqhdFrclDiu7cx+pg/g== Received: from [172.19.0.2] (unknown [172.19.0.2]) by ffbox0-bg.ffmpeg.org (Postfix) with ESMTP id 19E7168FE03; Fri, 14 Nov 2025 12:04:27 +0200 (EET) ARC-Seal: i=1; cv=none; a=rsa-sha256; d=ffmpeg.org; s=arc; t=1763114643; b=fYmbrhzzN+0U1n4Mr3ZtzemDXa9DOzH8pp2vP19A+tbTpIL6QaE7zTqcaaqaDTwScS+U0 /Bapv2bGmXXshxLo0XDrv4qa0HFFzUcrxTii79no3QVZqJ0g98Ze6NRvddGiacSoSdogq5b MkDRaKUZcL4KOjR1aQYafCLnQkTYVFKa+rOuM/kHZQoGcj3pGNQ29yiRm7ioGvt0cLrpztd HE8lceiJ4OHi57pzYCkZAQp5YpKUTXM1jgTuIkFWHo/jcU1+zmjvvhQG8nMygok+pf6/quG xZl6tFTxgZM8QRwIkxkgmSCGA35LnwUbbxhnJAJ1hOJ/KiWSx/NrLp/6srPQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=ffmpeg.org; s=arc; t=1763114643; h=from : sender : reply-to : subject : date : message-id : to : cc : mime-version : content-type : content-transfer-encoding : content-id : content-description : resent-date : resent-from : resent-sender : resent-to : resent-cc : resent-message-id : in-reply-to : references : list-id : list-help : list-unsubscribe : list-subscribe : list-post : list-owner : list-archive; bh=1IsRVQUEy6RCvgSxFZs/whuFGxGx7KMFd9e7DNJ5Au0=; b=tgXEF04d04fiErhR8JEXhBmXNmwB26QJ524d9UwatLs0g1XOGGVhiblUC9ozxE6IXhdmp NdhN8gZX4PPF7jmX7O7E7cGDHuVgs7rJGxQAXqCMHI3DIfwDVlAoMa6IFHhnRFmQPLA+bvH tnpoZDjRrTaMLThBtUVUH7+QadmgRL7gRjSfu7lwKwtmvxASfrkFqSQ1NbToeJ1iNej+EYI DrUiZtiVaOeEOpzxXul3ZtcTL+wP0C0wE/fAx1ah7yXA6VXxQKWYXDOTWS9Yb6LpwrbYGV7 BEaSzU+BlVlpDAPZFolPaiUL/fywrq7Q4JwTB3HJ2KvSmQHNsUP0bbFffM8g== ARC-Authentication-Results: i=1; ffmpeg.org; dkim=pass header.d=ffmpeg.org header.i=@ffmpeg.org; arc=none; dmarc=pass header.from=ffmpeg.org policy.dmarc=quarantine Authentication-Results: ffmpeg.org; dkim=pass header.d=ffmpeg.org header.i=@ffmpeg.org; arc=none (Message is not ARC signed); dmarc=pass (Used From Domain Record) header.from=ffmpeg.org policy.dmarc=quarantine DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ffmpeg.org; i=@ffmpeg.org; q=dns/txt; s=mail; t=1763114636; h=content-type : mime-version : content-transfer-encoding : from : to : reply-to : subject : date : from; bh=6gjJVGNIKoNmUDQBDSn9jrq2pLsVh/1VhdfHn+euQFI=; b=Su/5mLfw+ji2WsckVrT+JjjcAXNCTf23iwsuZRPmpV+W07OmOmEGMMTOON9aNqkZcfU8k qb6LLf2LlEeGvKCsb7iQSh34rjo+4kQ7H8PGuuTTV6R6h4xOAseL3ajU49iUuzKOTJUN4QD Wp0kW9+7/lGmFwklq7nDjPDtkUAMuafGJ3jftQZ4YNWSlQNMXeUajmLaRglZc7Q9x4vt6Mm V5i/jjQEBbCRtMziB0WGIcI+sbT3F6M5eLgcSTMm8peG1PQbiE4WQzQ7OLsX1YSnyPMmTOc crCZm12A7Slut4ez1UXehI5pq1C6R7XY2vxzpcra7hBjukGpkUwBtW0KBAYA== Received: from 188d6d40ca7a (code.ffmpeg.org [188.245.149.3]) by ffbox0-bg.ffmpeg.org (Postfix) with ESMTPS id 6A5F168FC7C for ; Fri, 14 Nov 2025 12:03:56 +0200 (EET) MIME-Version: 1.0 To: ffmpeg-devel@ffmpeg.org Date: Fri, 14 Nov 2025 10:03:56 -0000 Message-ID: <176311463658.25.11896374881943778932@2cb04c0e5124> Message-ID-Hash: F4SVDEUBD3JMDWM4V5UX6QAZ2PQOYFJU X-Message-ID-Hash: F4SVDEUBD3JMDWM4V5UX6QAZ2PQOYFJU X-MailFrom: code@ffmpeg.org X-Mailman-Rule-Hits: nonmember-moderation X-Mailman-Rule-Misses: dmarc-mitigation; no-senders; approved; loop; banned-address; header-match-ffmpeg-devel.ffmpeg.org-0; header-match-ffmpeg-devel.ffmpeg.org-1; header-match-ffmpeg-devel.ffmpeg.org-2; header-match-ffmpeg-devel.ffmpeg.org-3; emergency; member-moderation X-Mailman-Version: 3.3.10 Precedence: list Reply-To: FFmpeg development discussions and patches Subject: [FFmpeg-devel] [PATCH] avfilter/vf_drawtext: fix call GET_UTF8 with invalid argument (PR #20917) List-Id: FFmpeg development discussions and patches Archived-At: Archived-At: List-Archive: List-Archive: List-Help: List-Owner: List-Post: List-Subscribe: List-Unsubscribe: From: Zhao Zhili via ffmpeg-devel Cc: Zhao Zhili Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit Archived-At: List-Archive: List-Post: PR #20917 opened by Zhao Zhili (quink) URL: https://code.ffmpeg.org/FFmpeg/FFmpeg/pulls/20917 Patch URL: https://code.ffmpeg.org/FFmpeg/FFmpeg/pulls/20917.patch For GET_UTF8(val, GET_BYTE, ERROR), val has type of uint32_t, GET_BYTE must return an unsigned integer, otherwise signed extension happened due to val= (GET_BYTE), and GET_UTF8 went to the error path. This bug incidentally cancelled the bug where hb_buffer_add_utf8 was being called with incorrect argument, allowing drawtext to function correctly on x86 and macOS ARM, which defined char as signed. However, on Linux and Android ARM environments, because char is unsigned by default, GET_UTF8 now returns the correct return, which unexpectedly revealed issue #20906. >>From 69f97b1d47137def27fda9adf0d6c8836f8cb29f Mon Sep 17 00:00:00 2001 From: Zhao Zhili Date: Fri, 14 Nov 2025 16:23:10 +0800 Subject: [PATCH 1/3] avfilter/vf_drawtext: fix incorrect text length >>From the doc of HarfBuzz, what hb_buffer_add_utf8 needs is the number of bytes, not Unicode character: hb_buffer_add_utf8(buf, text, strlen(text), 0, strlen(text)); Fix issue #20906. --- libavfilter/vf_drawtext.c | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/libavfilter/vf_drawtext.c b/libavfilter/vf_drawtext.c index 867536aa61..f5d0dc7d6b 100644 --- a/libavfilter/vf_drawtext.c +++ b/libavfilter/vf_drawtext.c @@ -1396,7 +1396,6 @@ static int measure_text(AVFilterContext *ctx, TextMetrics *metrics) DrawTextContext *s = ctx->priv; char *text = s->expanded_text.str; char *textdup = NULL, *start = NULL; - int num_chars = 0; int width64 = 0, w64 = 0; int cur_min_y64 = 0, first_max_y64 = -32000; int first_min_x64 = 32000, last_max_x64 = -32000; @@ -1459,7 +1458,7 @@ continue_on_failed2: TextLine *cur_line = &s->lines[line_count]; HarfbuzzData *hb = &cur_line->hb_data; cur_line->cluster_offset = line_offset; - ret = shape_text_hb(s, hb, start, num_chars); + ret = shape_text_hb(s, hb, start, p - start); if (ret != 0) { goto done; } @@ -1517,14 +1516,12 @@ continue_on_failed2: if (w64 > width64) { width64 = w64; } - num_chars = -1; start = p; ++line_count; line_offset = i + 1; } if (code == 0) break; - ++num_chars; } metrics->line_height64 = s->face->size->metrics.height; -- 2.49.1 >>From 8024a765170a36895d78097dbd2ad85c34740eb5 Mon Sep 17 00:00:00 2001 From: Zhao Zhili Date: Fri, 14 Nov 2025 16:53:07 +0800 Subject: [PATCH 2/3] avfilter/vf_drawtext: fix call GET_UTF8 with invalid argument For GET_UTF8(val, GET_BYTE, ERROR), val has type of uint32_t, GET_BYTE must return an unsigned integer, otherwise signed extension happened due to val= (GET_BYTE), and GET_UTF8 went to the error path. This bug incidentally cancelled the bug where hb_buffer_add_utf8 was being called with incorrect argument, allowing drawtext to function correctly on x86 and macOS ARM, which defined char as signed. However, on Linux and Android ARM environments, because char is unsigned by default, GET_UTF8 now returns the correct return, which unexpectedly revealed issue #20906. --- libavfilter/vf_drawtext.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libavfilter/vf_drawtext.c b/libavfilter/vf_drawtext.c index f5d0dc7d6b..378f67b6ad 100644 --- a/libavfilter/vf_drawtext.c +++ b/libavfilter/vf_drawtext.c @@ -1395,7 +1395,7 @@ static int measure_text(AVFilterContext *ctx, TextMetrics *metrics) { DrawTextContext *s = ctx->priv; char *text = s->expanded_text.str; - char *textdup = NULL, *start = NULL; + char *textdup = NULL; int width64 = 0, w64 = 0; int cur_min_y64 = 0, first_max_y64 = -32000; int first_min_x64 = 32000, last_max_x64 = -32000; @@ -1405,7 +1405,7 @@ static int measure_text(AVFilterContext *ctx, TextMetrics *metrics) Glyph *glyph = NULL; int i, tab_idx = 0, last_tab_idx = 0, line_offset = 0; - char* p; + uint8_t *start, *p; int ret = 0; // Count the lines and the tab characters -- 2.49.1 >>From cbf85fea4466fe33516c602c28e5b50da1759096 Mon Sep 17 00:00:00 2001 From: Zhao Zhili Date: Fri, 14 Nov 2025 17:23:22 +0800 Subject: [PATCH 3/3] avutil/common: make it clear that GET_UTF8/GET_UTF16 need unsigned type 1. Document the type of GET_BYTE/GET_16BIT. 2. Cast to the required type in case of GET_BYTE/GET_16BIT returned incorrect type. --- libavutil/common.h | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/libavutil/common.h b/libavutil/common.h index 3b830daf30..116a010865 100644 --- a/libavutil/common.h +++ b/libavutil/common.h @@ -471,7 +471,8 @@ static av_always_inline av_const int av_parity_c(uint32_t v) * Convert a UTF-8 character (up to 4 bytes) to its 32-bit UCS-4 encoded form. * * @param val Output value, must be an lvalue of type uint32_t. - * @param GET_BYTE Expression reading one byte from the input. + * @param GET_BYTE Expression reading one byte from the input, must be unsigned + * type like uint8_t. * Evaluated up to 7 times (4 for the currently * assigned Unicode range). With a memory buffer * input, this could be *ptr++, or if you want to make sure @@ -486,13 +487,13 @@ static av_always_inline av_const int av_parity_c(uint32_t v) * to prevent undefined results. */ #define GET_UTF8(val, GET_BYTE, ERROR)\ - val= (GET_BYTE);\ + val= (uint8_t)(GET_BYTE);\ {\ uint32_t top = (val & 128) >> 1;\ if ((val & 0xc0) == 0x80 || val >= 0xFE)\ {ERROR}\ while (val & top) {\ - unsigned int tmp = (GET_BYTE) - 128;\ + unsigned int tmp = (uint8_t)(GET_BYTE) - 128;\ if(tmp>>6)\ {ERROR}\ val= (val<<6) + tmp;\ @@ -506,16 +507,17 @@ static av_always_inline av_const int av_parity_c(uint32_t v) * * @param val Output value, must be an lvalue of type uint32_t. * @param GET_16BIT Expression returning two bytes of UTF-16 data converted - * to native byte order. Evaluated one or two times. + * to native byte order, must be unsigned type like uint16_t. + * Evaluated one or two times. * @param ERROR Expression to be evaluated on invalid input, * typically a goto statement. */ #define GET_UTF16(val, GET_16BIT, ERROR)\ - val = (GET_16BIT);\ + val = (uint16_t)(GET_16BIT);\ {\ unsigned int hi = val - 0xD800;\ if (hi < 0x800) {\ - val = (GET_16BIT) - 0xDC00;\ + val = (uint16_t)(GET_16BIT) - 0xDC00;\ if (val > 0x3FFU || hi > 0x3FFU)\ {ERROR}\ val += (hi<<10) + 0x10000;\ -- 2.49.1 _______________________________________________ ffmpeg-devel mailing list -- ffmpeg-devel@ffmpeg.org To unsubscribe send an email to ffmpeg-devel-leave@ffmpeg.org