bug-gettext
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: POSIX xgettext and dgettext() calls


From: Bruno Haible
Subject: Re: POSIX xgettext and dgettext() calls
Date: Thu, 12 May 2022 01:01:48 +0200

https://posix.rhansen.org/p/gettext_draft
Lines 1173..1179

> on Solaris, the resulting .po file is called "foobar.po" and contains the 
> msgid "test".

Confirmed; it's like this on OmniOS and OpenIndiana.

> Running it on GNU, the resulting .po file is called "messages.po" and there 
> is no indication that the msgid belongs to "foobar".

Confirmed as well. It is like this since at least version 0.10.40 from 2001.

> According to the L18nux specification, the Solaris behavior is intended.

Confirmed: LI18NUX 2000 says "msgid strings in dgettext() calls are written
to the output file domainname.po where domainname is the first parameter to
the dgettext() call."

> Why does GNU xgettext deviate?

I think there are three reasons:

(1) Premature standardization: At that time, there was no established
    practice regarding how to deal with multiple domains.

    The old Uniforum specification pushed for the idea of a multi-domain
    PO file, with the 'domain' directives; this approach made it hard to
    concatenate and manipulate the files.

    The LI18NUX 2000 specification pushed for extracting a separate .po
    file for dgettext() directives.

    This did not attain wide use either, because the programmers want to
    minimize the number of domains: ideally one domain per package. Then
    it makes no sense to mention the domain name at hundreds of places in
    the source code. The programmer would instead write
      #define _(msgid) dgettext("mydomain", msgid)
    and use the _() macro throughout the source code.

(2) Integration into a build system.

    The xgettext utility is, in 99% of the cases, used as part of a build
    system. In a build system, a maintainer wants to have control over the
    file names; that is, they don't want files with arbitrary names to
    appear. For comparison, have you ever seen a C/C++ compiler create a
    separate file for each function/class/template/whatever? No, because
    the build systems people conceive for C/C++, with Makefile rules etc.,
    don't like files with arbitrary file names in the current directory.

(3) Security: When your test program is changed to

    #include <libintl.h>
    #include <stdio.h>
    int main(){
        printf("%s\n",dgettext("../../../../../../tmp/foobar","test"));
    }

    it does indeed create a file /tmp/foobar.po. Similar things can be
    done, to write into any writable directory on the disk. This is
    nowadays considered a security issue, which is why e.g. GNU tar
    prohibits extracting files outside of the current directory, since
    version 1.30.

Suggestion:
Mark this case as unspecified.

Rationale: I don't think the Li18nux + Solaris behaviour should be
standardized, because of the points (2), (3) above. And I don't think
it's worth standardizing any particular behaviour at all, because of
what I wrote in (1). It's a fringe case no one uses.

Bruno






reply via email to

[Prev in Thread] Current Thread [Next in Thread]