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

Re: *Really* noisy encoding warnings post-v2.33.0

From
Jeff King <peff@peff.net>
Date
Oct 27, 2021, 11:03 UTC
Message-ID
<YXkx6WzoF+B1id5T@coredump.intra.peff.net>
In-Reply-To
<871r4umfnm.fsf@evledraar.gmail.com>
On Sat, Oct 09, 2021 at 03:47:16PM +0200, Ævar Arnfjörð Bjarmason wrote:
Show 8 quoted lines
> But in this case this seems to have been because someone tried to feed
> "HTML" to it, which is not an encoding, and something iconv_open() has
> (I daresay) always and will always error on. It returns -1 and sets
> errno=EINVAL.
> 
> So having a warning or other detection in the revision loop seems
> backwards to me, surely we want something like the below instead?
> I.e. die as close to bad option parsing as possible?

Sorry for the slow response; this got thrown on my "to think about and look at later" pile.

Yeah, I agree that if we sanity-checked the encoding up front, that would cover the case we saw in practice, and goes a long way towards catching any practical errors.

But I think this patch is tricky:
Show 22 quoted lines
> diff --git a/environment.c b/environment.c
> index 43bb1b35ffe..c26b18f8e5c 100644
> --- a/environment.c
> +++ b/environment.c
> @@ -357,8 +357,18 @@ void set_git_dir(const char *path, int make_realpath)
>  
>  const char *get_log_output_encoding(void)
>  {
> -	return git_log_output_encoding ? git_log_output_encoding
> +	const char *encoding = git_log_output_encoding ? git_log_output_encoding
>  		: get_commit_output_encoding();
> +#ifndef NO_ICONV
> +	iconv_t conv;
> +	conv = iconv_open(encoding, "UTF-8");
> +	if (conv == (iconv_t) -1 && errno == EINVAL)
> +		die_errno("the '%s' encoding is not known to iconv", encoding);
> +#else
> +	if (strcmp(encoding, "UTF-8"))
> +		die("compiled with NO_ICONV=Y, can't re-encode to '%s'", encoding);
> +#endif
> +	return encoding;
>  }

So one obvious problem here is that we call this function once per commit, so it's a lot of extra iconv_open() calls. But obviously we could use a static flag to do it once per process.

The other issue is that it is assuming UTF-8 on one end of the conversion. But we aren't necessarily doing such a conversion; it depends on the commit's on-disk encoding, and the requested output encoding. In particular:

  - if both of those match, we do not need to call iconv at all (see the
    same_encoding() check in repo_logmsg_reencode()). With the patch
    above, the NO_ICONV case would start to die() when both are say
    iso8859-1, even though it currently works.
  - likewise, even if you have iconv support, it's possible that your
    preferred encoding is not compatible with utf8. In which case
    iconv_open() may complain, even though the actual conversion we'd
    ask it to do would succeed.

I.e., I don't think there's a way to just ask iconv "does this encoding name by itself make any sense". You can only ask it about to/from combos.

So I think a much better version of this is to catch the _actual_ iconv_open() call we make. And if it fails, say "woah, this combo of encodings isn't supported". The reason I didn't do that in the earlier patch is that all of this is obscured inside reencode_string_len(), which does both the iconv_open() and the iconv() call. We could surface that error information.

But I'm not sure it would make sense to die() in that case. While for something like "git log --encoding=nonsense" every commit is going to fail to re-encode, it's still possible that iconv_open() failures are commit-specific. I.e., you could have some garbage commit in your history with an unsupported encoding, and you wouldn't want to die() for it (it's the same case you are complaining about having a warning for, but much worse).

I suspect the best we could do along these lines is to wait until a real iconv_open(to, from) fails, and then as a fallback try:

  iconv_open("UTF-8", from);
  iconv_open(to, "UTF-8");

to sanity-check them individually, and guess that one of them is broken if it can't go to/from UTF-8. But even that feels like it's making assumptions about both the system iconv, and the charsets people use.

To be clear, I'd expect that most people just use utf-8 in the first place, and even if they don't that their system has some basic utf-8 support. But we are deep into the realm of weird corner cases here, and the utility of this warning / error-checking doesn't seem high enough to merit the possible regressions we'd get by trying to make too many assumptions.

-Peff
Previous: Ævar Arnfjörð BjarmasonNext: Ævar Arnfjörð Bjarmason
Message 16 of 33 in “git log --encoding=HTML is not supported”
  1. Krzysztof ŻelechowskiAug 24, 2021
  2. Bagas SanjayaAug 24, 2021
  3. Krzysztof ŻelechowskiAug 24, 2021
  4. Bagas SanjayaAug 24, 2021
  5. Junio C HamanoAug 24, 2021
  6. Jeff KingAug 25, 2021
  7. Junio C HamanoAug 25, 2021
  8. Jeff KingAug 27, 2021
  9. Jeff KingAug 27, 2021
  10. Junio C HamanoAug 27, 2021
  11. *Really* noisy encoding warnings post-v2.33.0Ævar Arnfjörð Bjarmason, Oct 9, 2021
  12. Ævar Arnfjörð BjarmasonOct 9, 2021
  13. Jeff KingOct 9, 2021
  14. Jeff KingOct 9, 2021
  15. Ævar Arnfjörð BjarmasonOct 9, 2021
  16. Jeff KingOct 27, 2021
  17. Ævar Arnfjörð BjarmasonOct 29, 2021
  18. Jeff KingOct 29, 2021
  19. Junio C HamanoOct 29, 2021
  20. Junio C HamanoOct 29, 2021
  21. Jeff KingOct 29, 2021
  22. Ævar Arnfjörð BjarmasonOct 22, 2021
  23. Johannes SixtOct 10, 2021
  24. Ævar Arnfjörð BjarmasonOct 10, 2021
  25. Krzysztof ŻelechowskiAug 25, 2021
  26. Jeff KingAug 27, 2021
  27. Krzysztof ŻelechowskiAug 25, 2021
  28. Bryan TurnerAug 25, 2021
  29. Junio C HamanoAug 26, 2021
  30. Krzysztof ŻelechowskiAug 26, 2021
  31. Junio C HamanoAug 27, 2021
  32. Jeff KingAug 27, 2021
  33. Junio C HamanoAug 27, 2021

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.