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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.