]> git.ipfire.org Git - thirdparty/git.git/commitdiff
gettext: avoid using gettext if the locale dir is not present
authorJohannes Schindelin <johannes.schindelin@gmx.de>
Wed, 22 Feb 2023 11:40:55 +0000 (12:40 +0100)
committerJohannes Schindelin <johannes.schindelin@gmx.de>
Mon, 17 Apr 2023 19:15:39 +0000 (21:15 +0200)
In cc5e1bf99247 (gettext: avoid initialization if the locale dir is not
present, 2018-04-21) Git was taught to avoid a costly gettext start-up
when there are not even any localized messages to work with.

But we still called `gettext()` and `ngettext()` functions.

Which caused a problem in Git for Windows when the libgettext that is
consumed from the MSYS2 project stopped using a runtime prefix in
https://github.com/msys2/MINGW-packages/pull/10461

Due to that change, we now use an unintialized gettext machinery that
might get auto-initialized _using an unintended locale directory_:
`C:\mingw64\share\locale`.

Let's record the fact when the gettext initialization was skipped, and
skip calling the gettext functions accordingly.

This addresses CVE-2023-25815.

Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
gettext.c
gettext.h

index 1b564216d03f6a7bb75fb4c867ad1b0e5cfbecd0..610d402fe720aba33281877f47976895f659578f 100644 (file)
--- a/gettext.c
+++ b/gettext.c
@@ -109,6 +109,8 @@ static void init_gettext_charset(const char *domain)
                setlocale(LC_CTYPE, "C");
 }
 
+int git_gettext_enabled = 0;
+
 void git_setup_gettext(void)
 {
        const char *podir = getenv(GIT_TEXT_DOMAIN_DIR_ENVIRONMENT);
@@ -130,6 +132,8 @@ void git_setup_gettext(void)
        init_gettext_charset("git");
        textdomain("git");
 
+       git_gettext_enabled = 1;
+
        free(p);
 }
 
index bee52eb11347da9336e9f1906f7973aa0e224d3b..b96ab9d3403481b2c585db0a259f24b15724590a 100644 (file)
--- a/gettext.h
+++ b/gettext.h
 int use_gettext_poison(void);
 
 #ifndef NO_GETTEXT
+extern int git_gettext_enabled;
 void git_setup_gettext(void);
 int gettext_width(const char *s);
 #else
+#define git_gettext_enabled (0)
 static inline void git_setup_gettext(void)
 {
        use_gettext_poison(); /* getenv() reentrancy paranoia */
@@ -48,7 +50,8 @@ static inline FORMAT_PRESERVING(1) const char *_(const char *msgid)
 {
        if (!*msgid)
                return "";
-       return use_gettext_poison() ? "# GETTEXT POISON #" : gettext(msgid);
+       return use_gettext_poison() ? "# GETTEXT POISON #" :
+               !git_gettext_enabled ? msgid : gettext(msgid);
 }
 
 static inline FORMAT_PRESERVING(1) FORMAT_PRESERVING(2)
@@ -56,6 +59,8 @@ const char *Q_(const char *msgid, const char *plu, unsigned long n)
 {
        if (use_gettext_poison())
                return "# GETTEXT POISON #";
+       if (!git_gettext_enabled)
+               return n == 1 ? msgid : plu;
        return ngettext(msgid, plu, n);
 }