git/list[1] front-page[2] threads[3] people[4] search[5] about
 

Re: [PATCH v4 13/16] builtin/blame: fix type of `length` variable when emitting object ID

From
Johannes Schindelin <johannes.schindelin@gmx.de>
Date
Jan 8, 2025, 19:17 UTC
Message-ID
<4d812802-afbc-4635-7a19-73896fcda625@gmx.de>
In-Reply-To
<20241206-pks-sign-compare-v4-13-0344c6dfb219@pks.im>
Hi Patrick,
On Fri, 6 Dec 2024, Patrick Steinhardt wrote:
Show 62 quoted lines
> The `length` variable is used to store how many bytes we wish to emit
> from an object ID. This value will either be the full hash algorithm's
> length, or the abbreviated hash that can be set via `--abbrev` or the
> "core.abbrev" option. The former is of type `size_t`, whereas the latter
> is of type `int`, which causes a warning with "-Wsign-compare".
>
> The reason why `abbrev` is using a signed type is mostly that it is
> initialized with `-1` to indicate that we have to compute the minimum
> abbreviation length. This length is computed via `find_alignment()`,
> which always gets called before `emit_other()`, and thus we can assume
> that the value would never be negative in `emit_other()`.
>
> In fact, we can even assume that the value will always be at least
> `MINIMUM_ABBREV`, which is enforced by both `git_default_core_config()`
> and `parse_opt_abbrev_cb()`. We implicitly rely on this by subtracting
> up to 3 without checking for whether the value becomes negative. We then
> pass the value to printf(3p) to print the prefix of our object's ID, so
> if that assumption was violated we may end up with undefined behaviour.
>
> Squelch the warning by asserting this invariant and casting the value of
> `abbrev` to `size_t`. This allows us to store the whole length as an
> unsigned integer, which we can then pass to `fwrite()`.
>
> Signed-off-by: Patrick Steinhardt <ps@pks.im>
> ---
>  builtin/blame.c | 10 +++++++---
>  1 file changed, 7 insertions(+), 3 deletions(-)
>
> diff --git a/builtin/blame.c b/builtin/blame.c
> index b33b44c89a431d45e05d9863f69c049ba5eec08c..867032e4c16878ffd56df8a73162b89ca4bd2694 100644
> --- a/builtin/blame.c
> +++ b/builtin/blame.c
> @@ -6,7 +6,6 @@
>   */
>
>  #define USE_THE_REPOSITORY_VARIABLE
> -#define DISABLE_SIGN_COMPARE_WARNINGS
>
>  #include "builtin.h"
>  #include "config.h"
> @@ -468,9 +467,14 @@ static void emit_other(struct blame_scoreboard *sb, struct blame_entry *ent, int
>  		reset = GIT_COLOR_RESET;
>  	}
>
> +	if (abbrev < MINIMUM_ABBREV)
> +		BUG("abbreviation is smaller than minimum length: %d < %d",
> +		    abbrev, MINIMUM_ABBREV);
> +
>  	for (cnt = 0; cnt < ent->num_lines; cnt++) {
>  		char ch;
> -		int length = (opt & OUTPUT_LONG_OBJECT_NAME) ? the_hash_algo->hexsz : abbrev;
> +		size_t length = (opt & OUTPUT_LONG_OBJECT_NAME) ?
> +			the_hash_algo->hexsz : (size_t) abbrev;
>
>  		if (opt & OUTPUT_COLOR_LINE) {
>  			if (cnt > 0) {
> @@ -501,7 +505,7 @@ static void emit_other(struct blame_scoreboard *sb, struct blame_entry *ent, int
>  			length--;
>  			putchar('?');
>  		}
> -		printf("%.*s", length, hex);
> +		fwrite(hex, 1, length, stdout);

I just noticed this, and would like to point out a difference of behavior. Try this at home:

	git blame --abbrev=99999 git.c

The difference relative to the previous behavior that I am observing is that the `fwrite()` call does not stop at the NUL character and hence happily continues out-of-bounds. The `printf()` call would have stopped at the NUL character.

Ciao, Johannes

Show 9 quoted lines
>  		if (opt & OUTPUT_ANNOTATE_COMPAT) {
>  			const char *name;
>  			if (opt & OUTPUT_SHOW_EMAIL)
>
> --
> 2.47.0.366.g5daf58cba8.dirty
>
>
>
Previous: Patrick SteinhardtNext: Patrick Steinhardt
Message 61 of 66 in “Start compiling with `-Wsign-compare`”
  1. 00/10 Start compiling with `-Wsign-compare`Patrick Steinhardt, Nov 29, 2024
  2. 02/10 compat/regex: explicitly ignore "-Wsign-compare" warningsPatrick Steinhardt, Nov 29, 2024
  3. 01/10 git-compat-util: introduce macros to disable "-Wsign-compare" warningsPatrick Steinhardt, Nov 29, 2024
  4. 03/10 compat/win32: fix -Wsign-compare warning in "wWinMain()"Patrick Steinhardt, Nov 29, 2024
  5. 05/10 config.mak.dev: drop `-Wno-sign-compare`Patrick Steinhardt, Nov 29, 2024
  6. 06/10 global: fix unsigned integer promotions in ternary statementsPatrick Steinhardt, Nov 29, 2024
  7. shejialuoNov 30, 2024
  8. Patrick SteinhardtDec 2, 2024
  9. Jeff KingDec 1, 2024
  10. Patrick SteinhardtDec 2, 2024
  11. 04/10 global: mark code units that generate warnings with `-Wsign-compare`Patrick Steinhardt, Nov 29, 2024
  12. 07/10 diff.h: fix index used to loop through unsigned integerPatrick Steinhardt, Nov 29, 2024
  13. 09/10 daemon: fix loops that have mismatching integer typesPatrick Steinhardt, Nov 29, 2024
  14. Jeff KingDec 1, 2024
  15. Patrick SteinhardtDec 2, 2024
  16. Jeff KingDec 5, 2024
  17. 08/10 global: trivial conversions to fix `-Wsign-compare` warningsPatrick Steinhardt, Nov 29, 2024
  18. Jeff KingDec 1, 2024
  19. Patrick SteinhardtDec 2, 2024
  20. 10/10 daemon: fix type of `max_connections`Patrick Steinhardt, Nov 29, 2024
  21. Jeff KingDec 1, 2024
  22. shejialuoNov 30, 2024
  23. Patrick SteinhardtDec 2, 2024
  24. Jeff KingDec 1, 2024
  25. Patrick SteinhardtDec 2, 2024
  26. 00/15 Start compiling with `-Wsign-compare`Patrick Steinhardt, Dec 5, 2024
  27. 01/15 git-compat-util: introduce macros to disable "-Wsign-compare" warningsPatrick Steinhardt, Dec 5, 2024
  28. 02/15 compat/regex: explicitly ignore "-Wsign-compare" warningsPatrick Steinhardt, Dec 5, 2024
  29. 03/15 compat/win32: fix -Wsign-compare warning in "wWinMain()"Patrick Steinhardt, Dec 5, 2024
  30. 05/15 config.mak.dev: drop `-Wno-sign-compare`Patrick Steinhardt, Dec 5, 2024
  31. 04/15 global: mark code units that generate warnings with `-Wsign-compare`Patrick Steinhardt, Dec 5, 2024
  32. 06/15 diff.h: fix index used to loop through unsigned integerPatrick Steinhardt, Dec 5, 2024
  33. 07/15 sign-compare: 32-bit supportPatrick Steinhardt, Dec 5, 2024
  34. Jeff KingDec 5, 2024
  35. Patrick SteinhardtDec 6, 2024
  36. 08/15 global: trivial conversions to fix `-Wsign-compare` warningsPatrick Steinhardt, Dec 5, 2024
  37. 09/15 daemon: fix loops that have mismatching integer typesPatrick Steinhardt, Dec 5, 2024
  38. 11/15 gpg-interface: address -Wsign-comparison warningsPatrick Steinhardt, Dec 5, 2024
  39. 10/15 daemon: fix type of `max_connections`Patrick Steinhardt, Dec 5, 2024
  40. 12/15 builtin/blame: fix type of `length` variable when emitting object IDPatrick Steinhardt, Dec 5, 2024
  41. 13/15 builtin/patch-id: fix type of `get_one_patchid()`Patrick Steinhardt, Dec 5, 2024
  42. 14/15 scalar: address -Wsign-compare warningsPatrick Steinhardt, Dec 5, 2024
  43. 15/15 t/helper: don't depend on implicit wraparoundPatrick Steinhardt, Dec 5, 2024
  44. 00/16 Start compiling with `-Wsign-compare`Patrick Steinhardt, Dec 6, 2024
  45. 01/16 git-compat-util: introduce macros to disable "-Wsign-compare" warningsPatrick Steinhardt, Dec 6, 2024
  46. karthik nayakDec 6, 2024
  47. 02/16 compat/regex: explicitly ignore "-Wsign-compare" warningsPatrick Steinhardt, Dec 6, 2024
  48. 03/16 compat/win32: fix -Wsign-compare warning in "wWinMain()"Patrick Steinhardt, Dec 6, 2024
  49. 05/16 config.mak.dev: drop `-Wno-sign-compare`Patrick Steinhardt, Dec 6, 2024
  50. 04/16 global: mark code units that generate warnings with `-Wsign-compare`Patrick Steinhardt, Dec 6, 2024
  51. 06/16 diff.h: fix index used to loop through unsigned integerPatrick Steinhardt, Dec 6, 2024
  52. 07/16 csum-file: fix -Wsign-compare warning on 32-bit platformPatrick Steinhardt, Dec 6, 2024
  53. 08/16 pkt-line: fix -Wsign-compare warning on 32 bit platformPatrick Steinhardt, Dec 6, 2024
  54. Jeff KingDec 8, 2024
  55. Junio C HamanoDec 9, 2024
  56. 09/16 global: trivial conversions to fix `-Wsign-compare` warningsPatrick Steinhardt, Dec 6, 2024
  57. 10/16 daemon: fix loops that have mismatching integer typesPatrick Steinhardt, Dec 6, 2024
  58. 11/16 daemon: fix type of `max_connections`Patrick Steinhardt, Dec 6, 2024
  59. 12/16 gpg-interface: address -Wsign-comparison warningsPatrick Steinhardt, Dec 6, 2024
  60. 13/16 builtin/blame: fix type of `length` variable when emitting object IDPatrick Steinhardt, Dec 6, 2024
  61. Johannes SchindelinJan 8, 2025
  62. Patrick SteinhardtJan 9, 2025
  63. 14/16 builtin/patch-id: fix type of `get_one_patchid()`Patrick Steinhardt, Dec 6, 2024
  64. 15/16 scalar: address -Wsign-compare warningsPatrick Steinhardt, Dec 6, 2024
  65. 16/16 t/helper: don't depend on implicit wraparoundPatrick Steinhardt, Dec 6, 2024
  66. karthik nayakDec 6, 2024

Read the whole thread, see it on lore, or plain text.

$ cat FOOTERMessages come from the public archive at lore.kernel.org/git, fetched every hour. The front page is chosen and written each morning by an AI editor and can be wrong; the threads themselves are the record. About and API. For agents: an MCP server at https://gitlist.dev/mcp, and any thread, story or person page as Markdown by adding .md to its URL (or sending Accept: text/markdown). Details in /llms.txt.