From: "Nguyễn Thái Ngọc Duy" <pclouds@gmail.com>
To: git@vger.kernel.org
Cc: "Jonathan Niedier" <jrnieder@gmail.com>,
vnwildman@gmail.com, "Nguyễn Thái Ngọc Duy" <pclouds@gmail.com>
Subject: [PATCH] gettext.c: only work around the vsnprintf bug on glibc < 2.17
Date: Sat, 30 Nov 2013 08:51:31 +0700 [thread overview]
Message-ID: <1385776291-21006-1-git-send-email-pclouds@gmail.com> (raw)
Bug 6530 [1] 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. If git is built with glibc, it can
know running libc version with gnu_get_libc_version() and avoid the
workaround on fixed versions. As a side effect, the workaround is
dropped for all non-glibc systems.
Tested on Gentoo Linux, glibc 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>
---
We could even dlopen and look for gnu_get_libc_version at runtime and
drop USE_GLIBC define. But there may be other problems with dl* on
other platforms..
Somebody should test for the other two "USE_GLIBC = YesPlease" I
added. I don't have Debian/FreeBSD nor any non-Linux GNU systems.
Makefile | 5 +++++
config.mak.uname | 3 +++
gettext.c | 34 ++++++++++++++++++++++++++++------
3 files changed, 36 insertions(+), 6 deletions(-)
diff --git a/Makefile b/Makefile
index af847f8..8df6d6d 100644
--- a/Makefile
+++ b/Makefile
@@ -66,6 +66,8 @@ all::
# Define LIBC_CONTAINS_LIBINTL if your gettext implementation doesn't
# need -lintl when linking.
#
+# Define USE_GLIBC if your libc version is glibc >= 2.1.
+#
# Define NO_MSGFMT_EXTENDED_OPTIONS if your implementation of msgfmt
# doesn't support GNU extensions like --check and --statistics
#
@@ -1203,6 +1205,9 @@ ifndef NO_GETTEXT
ifndef LIBC_CONTAINS_LIBINTL
EXTLIBS += -lintl
endif
+ifdef USE_GLIBC
+ BASIC_CFLAGS += -DUSE_GLIBC
+endif
endif
ifdef NEEDS_SOCKET
EXTLIBS += -lsocket
diff --git a/config.mak.uname b/config.mak.uname
index 82d549e..ffb01e0 100644
--- a/config.mak.uname
+++ b/config.mak.uname
@@ -33,6 +33,7 @@ ifeq ($(uname_S),Linux)
HAVE_PATHS_H = YesPlease
LIBC_CONTAINS_LIBINTL = YesPlease
HAVE_DEV_TTY = YesPlease
+ USE_GLIBC = YesPlease
endif
ifeq ($(uname_S),GNU/kFreeBSD)
NO_STRLCPY = YesPlease
@@ -40,6 +41,7 @@ ifeq ($(uname_S),GNU/kFreeBSD)
HAVE_PATHS_H = YesPlease
DIR_HAS_BSD_GROUP_SEMANTICS = YesPlease
LIBC_CONTAINS_LIBINTL = YesPlease
+ USE_GLIBC = YesPlease
endif
ifeq ($(uname_S),UnixWare)
CC = cc
@@ -236,6 +238,7 @@ ifeq ($(uname_S),GNU)
NO_MKSTEMPS = YesPlease
HAVE_PATHS_H = YesPlease
LIBC_CONTAINS_LIBINTL = YesPlease
+ USE_GLIBC = YesPlease
endif
ifeq ($(uname_S),IRIX)
NO_SETENV = YesPlease
diff --git a/gettext.c b/gettext.c
index 71e9545..91e679d 100644
--- a/gettext.c
+++ b/gettext.c
@@ -18,6 +18,13 @@
# endif
#endif
+#ifdef USE_GLIBC
+#ifndef _GNU_SOURCE
+#define _GNU_SOURCE
+#endif
+#include <gnu/libc-version.h>
+#endif
+
#ifdef GETTEXT_POISON
int use_gettext_poison(void)
{
@@ -30,6 +37,7 @@ int use_gettext_poison(void)
#ifndef NO_GETTEXT
static const char *charset;
+static int vsnprintf_workaround;
static void init_gettext_charset(const char *domain)
{
/*
@@ -99,9 +107,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 2.17.
Then we could simply set LC_CTYPE from the environment, which would
make things like the external perror(3) messages work.
@@ -112,20 +118,36 @@ static void init_gettext_charset(const char *domain)
1. http://sourceware.org/bugzilla/show_bug.cgi?id=6530
2. E.g. "Content-Type: text/plain; charset=UTF-8\n" in po/is.po
*/
- setlocale(LC_CTYPE, "");
+ if (vsnprintf_workaround)
+ setlocale(LC_CTYPE, "");
charset = locale_charset();
bind_textdomain_codeset(domain, charset);
- setlocale(LC_CTYPE, "C");
+ if (vsnprintf_workaround)
+ setlocale(LC_CTYPE, "C");
}
void git_setup_gettext(void)
{
const char *podir = getenv("GIT_TEXTDOMAINDIR");
+#ifdef USE_GLIBC
+ int major, minor;
+ const char *version = gnu_get_libc_version();
+
+ if (version && sscanf(version, "%d.%d", &major, &minor) == 2 &&
+ (major > 2 || (major == 2 && minor >= 17)))
+ vsnprintf_workaround = 0;
+ else
+ vsnprintf_workaround = 1;
+#endif
+
if (!podir)
podir = GIT_LOCALE_PATH;
bindtextdomain("git", podir);
- setlocale(LC_MESSAGES, "");
+ if (vsnprintf_workaround)
+ setlocale(LC_MESSAGES, "");
+ else
+ setlocale(LC_ALL, "");
init_gettext_charset("git");
textdomain("git");
}
--
1.8.2.83.gc99314b
next reply other threads:[~2013-11-30 1:47 UTC|newest]
Thread overview: 12+ messages / expand[flat|nested] mbox.gz Atom feed top
2013-11-30 1:51 Nguyễn Thái Ngọc Duy [this message]
2013-11-30 9:51 ` [PATCH] gettext.c: only work around the vsnprintf bug on glibc < 2.17 Andreas Schwab
2013-11-30 12:01 ` [PATCH v2] " Nguyễn Thái Ngọc Duy
2013-11-30 23:01 ` Torsten Bögershausen
2013-11-30 23:06 ` Torsten Bögershausen
2013-12-01 1:33 ` Duy Nguyen
2013-12-01 2:45 ` [PATCH v3] gettext.c: detect the vsnprintf bug at runtime Nguyễn Thái Ngọc Duy
2013-12-02 0:31 ` Trần Ngọc Quân
2013-12-02 5:57 ` Duy Nguyen
2013-12-02 7:40 ` Trần Ngọc Quân
2013-12-02 8:49 ` Trần Ngọc Quân
2013-12-02 9:00 ` Duy Nguyen
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1385776291-21006-1-git-send-email-pclouds@gmail.com \
--to=pclouds@gmail.com \
--cc=git@vger.kernel.org \
--cc=jrnieder@gmail.com \
--cc=vnwildman@gmail.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).