gunidecomp: Fix a false positive from the static analyser

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 <pwithnall@gnome.org>

Helps: #1767
This commit is contained in:
Philip Withnall 2024-04-09 23:07:53 +01:00
parent 70a49e35cc
commit 05158475e9
No known key found for this signature in database
GPG Key ID: DCDF5885B1F3ED73

View File

@ -26,6 +26,7 @@
#include "gunicode.h" #include "gunicode.h"
#include "gunidecomp.h" #include "gunidecomp.h"
#include "gmem.h" #include "gmem.h"
#include "gtestutils.h"
#include "gunicomp.h" #include "gunicomp.h"
#include "gunicodeprivate.h" #include "gunicodeprivate.h"
@ -428,8 +429,9 @@ _g_utf8_normalize_wc (const gchar *str,
wc_buffer[n_wc++] = wc; wc_buffer[n_wc++] = wc;
} }
if (n_wc > 0) /* Each code path above *must* have appended at least gunichar to wc_buffer. */
{ g_assert (n_wc > old_n_wc);
cc = COMBINING_CLASS (wc_buffer[old_n_wc]); cc = COMBINING_CLASS (wc_buffer[old_n_wc]);
if (cc == 0) if (cc == 0)
@ -437,7 +439,6 @@ _g_utf8_normalize_wc (const gchar *str,
g_unicode_canonical_ordering (wc_buffer + last_start, n_wc - last_start); g_unicode_canonical_ordering (wc_buffer + last_start, n_wc - last_start);
last_start = old_n_wc; last_start = old_n_wc;
} }
}
p = g_utf8_next_char (p); p = g_utf8_next_char (p);
} }