Skip to content

Commit

Permalink
gettext.c: detect the vsnprintf bug at runtime
Browse files Browse the repository at this point in the history
Bug 6530 [1] in glibc causes "git show v0.99.6~1" to fail with error
"your vsnprintf is broken". The workaround avoids that, but it
corrupts system error messages in non-C locales.

The bug has been fixed since 2.17. We could know running glibc version
with gnu_get_libc_version(). But version is not a sure way to detect
the bug because downstream may back port the fix to older versions. Do
a runtime test that immitates the call flow that leads to "your
vsnprintf is broken". Only enable the workaround if the test fails.

Tested on Gentoo Linux, glibc 2.16.0 and 2.17, amd64.

[1] http://sourceware.org/bugzilla/show_bug.cgi?id=6530

Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
  • Loading branch information
Nguyễn Thái Ngọc Duy authored and Junio C Hamano committed Dec 5, 2013
1 parent a155a5f commit 9c0495d
Showing 1 changed file with 15 additions and 4 deletions.
19 changes: 15 additions & 4 deletions gettext.c
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,17 @@ int use_gettext_poison(void)
#endif

#ifndef NO_GETTEXT
static int test_vsnprintf(const char *fmt, ...)
{
char buf[26];
int ret;
va_list ap;
va_start(ap, fmt);
ret = vsnprintf(buf, sizeof(buf), fmt, ap);
va_end(ap);
return ret;
}

static const char *charset;
static void init_gettext_charset(const char *domain)
{
Expand Down Expand Up @@ -99,9 +110,7 @@ static void init_gettext_charset(const char *domain)
$ LANGUAGE= LANG=de_DE.utf8 ./test
test: Kein passendes Ger?t gefunden
In the long term we should probably see about getting that
vsnprintf bug in glibc fixed, and audit our code so it won't
fall apart under a non-C locale.
The vsnprintf bug has been fixed since glibc 2.17.
Then we could simply set LC_CTYPE from the environment, which would
make things like the external perror(3) messages work.
Expand All @@ -115,7 +124,9 @@ static void init_gettext_charset(const char *domain)
setlocale(LC_CTYPE, "");
charset = locale_charset();
bind_textdomain_codeset(domain, charset);
setlocale(LC_CTYPE, "C");
/* the string is taken from v0.99.6~1 */
if (test_vsnprintf("%.*s", 13, "David_K\345gedal") < 0)
setlocale(LC_CTYPE, "C");
}

void git_setup_gettext(void)
Expand Down

0 comments on commit 9c0495d

Please sign in to comment.