From 05158475e91571dfbb2cdf6af35f68225dd3506a Mon Sep 17 00:00:00 2001 From: Philip Withnall Date: Tue, 9 Apr 2024 23:07:53 +0100 Subject: [PATCH] gunidecomp: Fix a false positive from the static analyser MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit scan-build was complaining that the `wc_buffer[old_n_wc]` in `cc = COMBINING_CLASS (wc_buffer[old_n_wc])` could dereference memory off the end of the initialised `wc_buffer` array. It came to this conclusion by assuming that the result of `find_decomposition()` for one of the `gunichar`s was a non-`NULL` empty string, so that iteration of the decomposition loop didn’t append anything to `wc_buffer`. I don’t think it’s possible for an iteration of the loop to *not* append anything to `wc_buffer`. Unicode characters don’t decompose to nothing. Indeed, the current code coverage for GLib says that the `if (n_wc > 0)` branch is always taken, and at that point in the control flow, `n_wc <= 0` is never true. So, add an assertion to check that progress is made (i.e. `n_wc` is incremented by at least 1), and remove the unnecessary condition. Signed-off-by: Philip Withnall Helps: #1767 --- glib/gunidecomp.c | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/glib/gunidecomp.c b/glib/gunidecomp.c index 5c2d41b1d..8f0f0010d 100644 --- a/glib/gunidecomp.c +++ b/glib/gunidecomp.c @@ -26,6 +26,7 @@ #include "gunicode.h" #include "gunidecomp.h" #include "gmem.h" +#include "gtestutils.h" #include "gunicomp.h" #include "gunicodeprivate.h" @@ -428,16 +429,16 @@ _g_utf8_normalize_wc (const gchar *str, wc_buffer[n_wc++] = wc; } - if (n_wc > 0) - { - cc = COMBINING_CLASS (wc_buffer[old_n_wc]); + /* Each code path above *must* have appended at least gunichar to wc_buffer. */ + g_assert (n_wc > old_n_wc); - if (cc == 0) - { - g_unicode_canonical_ordering (wc_buffer + last_start, n_wc - last_start); - last_start = old_n_wc; - } - } + cc = COMBINING_CLASS (wc_buffer[old_n_wc]); + + if (cc == 0) + { + g_unicode_canonical_ordering (wc_buffer + last_start, n_wc - last_start); + last_start = old_n_wc; + } p = g_utf8_next_char (p); }