-
Notifications
You must be signed in to change notification settings - Fork 760
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
bind_textdomain_codeset() return value updates #4311
Comments
POSIX is pretty clear here:
and
If musl (or any other implementation) return NULL here, they are not conforming to the specification. And that errno is unchanged, is to be expected. What is PHP supposed to do? Just say "yeah, the call was successful" would be wrong. |
I'm only talking about bind_textdomain_codeset. There's a separate paragraph about its return value:
|
Okay, but than musl could (and likely should) return |
This was my first thought, too, but if you want to entertain some wild speculation, I think the reasoning is:
So, we wind up with a consistent I think this would be a lot more sensible after php/php-src#17163, but I filed them separately because changing the implementation is a lot harder to do than updating the docs to reflect reality. FWIW you can get a "failure" from musl, but only via char *bind_textdomain_codeset(const char *domainname, const char *codeset)
{
if (codeset && strcasecmp(codeset, "UTF-8"))
errno = EINVAL;
return NULL;
} |
Well, for me it just says "A string on success." That needs to fixed anyway. And yeah, should explicitly document what is returned if the codeset has not been set yet (currently, |
…musl The musl implementation of bind_textdomain_codeset() always returns NULL. The POSIX-correctness of this is debatable, but it is roughly equivalent to correct, because musl only support UTF-8, so the NULL value indicating that the codeset is unchanged from the locale's codeset (UTF-8) is accurate. PHP's bind_textdomain_codeset() function however treats NULL as failure, unconditionally: * php/doc-en#4311 * php#17163 This unfortunately causes false to be returned consistently on musl -- even when nothing unexpected has happened -- and naturally this is affecting several tests. For now we change two tests to accept "false" in addition to "UTF-8" so that they may pass on musl. If PHP's bind_textdomain_codeset() is updated to differentiate between NULL and NULL-with-errno-set, these tests can also be updated once again to reject the NULL-with-errno result. This partially addresses GH php#13696
I'm confused by the spec, as it seems to contradict itself:
But also:
The terms "If domainname is not bound" and "if a codeset has not yet been set" appear to be equivalent, based on the rest of the spec. If we consider the first quote, If we consider the second quote, it's supposed to return The RETURN VALUE section agrees with the second quote:
The GNU gettext manpage agrees with the second quote as well:
So the second quote is probably the right one. Given that setting the codeset always fails on Musl (kind of, as it doesn't set So it would be enough to just document that |
Indeed. This is new in POSIX 2024, and all of the docs I can find for the various implementations (solaris, gnu, musl, freebsd) have it returning |
I got nothing but a headache trying to sign up for the POSIX bug tracker / mailing list, but I did find the email address of a technical editor and sent him a note. |
Musl has two quirks that are leading to failed internationalization tests. First is that the return value of bindtextdomain(..., NULL) will always be false, rather than an "implementation-defined default directory," because musl does not have an implementation-defined default directory. One test needs a special case for this. Second is that the musl implementation of bind_textdomain_codeset() always returns NULL. The POSIX-correctness of this is debatable, but it is roughly equivalent to correct, because musl only support UTF-8, so the NULL value indicating that the codeset is unchanged from the locale's codeset (UTF-8) is accurate. PHP's bind_textdomain_codeset() function however treats NULL as failure, unconditionally: * php/doc-en#4311 * php#17163 This unfortunately causes false to be returned consistently on musl -- even when nothing unexpected has happened -- and naturally this is affecting several tests. For now we change two tests to accept "false" in addition to "UTF-8" so that they may pass on musl. If PHP's bind_textdomain_codeset() is updated to differentiate between NULL and NULL-with-errno-set, these tests can also be updated once again to reject the NULL-with-errno result. This partially addresses GH php#13696
Musl has two quirks that are leading to failed internationalization tests. First is that the return value of bindtextdomain(..., NULL) will always be false, rather than an "implementation-defined default directory," because musl does not have an implementation-defined default directory. One test needs a special case for this. Second is that the musl implementation of bind_textdomain_codeset() always returns NULL. The POSIX-correctness of this is debatable, but it is roughly equivalent to correct, because musl only support UTF-8, so the NULL value indicating that the codeset is unchanged from the locale's codeset (UTF-8) is accurate. PHP's bind_textdomain_codeset() function however treats NULL as failure, unconditionally: * php/doc-en#4311 * php#17163 This unfortunately causes false to be returned consistently on musl -- even when nothing unexpected has happened -- and naturally this is affecting several tests. For now we change two tests to accept "false" in addition to "UTF-8" so that they may pass on musl. If PHP's bind_textdomain_codeset() is updated to differentiate between NULL and NULL-with-errno-set, these tests can also be updated once again to reject the NULL-with-errno result. This partially addresses GH php#13696
Musl has two quirks that are leading to failed internationalization tests. First is that the return value of bindtextdomain(..., NULL) will always be false, rather than an "implementation-defined default directory," because musl does not have an implementation-defined default directory. One test needs a special case for this. Second is that the musl implementation of bind_textdomain_codeset() always returns NULL. The POSIX-correctness of this is debatable, but it is roughly equivalent to correct, because musl only support UTF-8, so the NULL value indicating that the codeset is unchanged from the locale's codeset (UTF-8) is accurate. PHP's bind_textdomain_codeset() function however treats NULL as failure, unconditionally: * php/doc-en#4311 * #17163 This unfortunately causes false to be returned consistently on musl -- even when nothing unexpected has happened -- and naturally this is affecting several tests. For now we change two tests to accept "false" in addition to "UTF-8" so that they may pass on musl. If PHP's bind_textdomain_codeset() is updated to differentiate between NULL and NULL-with-errno-set, these tests can also be updated once again to reject the NULL-with-errno result. This partially addresses GH #13696
bind_textdomain_codeset()
is documented to return a string on success, andfalse
on failure. But there is one success case that also returnsfalse
. If you query the codeset for a domain that has not been explicitly set (yet), you will also getfalse
:This is because the C function returns
NULL
to indicate that the locale's codeset will be used. Quoting from https://pubs.opengroup.org/onlinepubs/9799919799.2024edition/functions/bind_textdomain_codeset.htmlI bring this up because musl only supports UTF-8, and always returns
NULL
from itsbind_textdomain_codeset()
. Its PHP counterpart therefore always appears to fail, when it is working as... well, not quite expected, but as documented.To summarize:
false
will also be returned if no codeset has been explicitly set for the domainfalse
under musl libc where the only supported codeset is UTF-8The text was updated successfully, but these errors were encountered: