* Issue in man page wcsncpy.3
@ 2022-12-04 9:07 Helge Kreutzmann
2022-12-04 20:42 ` Alejandro Colomar
2022-12-04 20:44 ` Alejandro Colomar
0 siblings, 2 replies; 15+ messages in thread
From: Helge Kreutzmann @ 2022-12-04 9:07 UTC (permalink / raw)
To: alx.manpages; +Cc: mario.blaettermann, linux-man
Without further ado, the following was found:
Issue: Is the "L" in the bracket (for the NULL character) correct?
"The B<wcsncpy>() function is the wide-character equivalent of the "
"B<strncpy>(3) function. It copies at most I<n> wide characters from the "
"wide-character string pointed to by I<src>, including the terminating null "
"wide character (L\\(aq\\e0\\(aq), to the array pointed to by I<dest>. "
"Exactly I<n> wide characters are written at I<dest>. If the length "
"I<wcslen(src)> is smaller than I<n>, the remaining wide characters in the "
"array pointed to by I<dest> are filled with null wide characters. If the "
"length I<wcslen(src)> is greater than or equal to I<n>, the string pointed "
"to by I<dest> will not be terminated by a null wide character."
^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: Issue in man page wcsncpy.3
2022-12-04 9:07 Issue in man page wcsncpy.3 Helge Kreutzmann
@ 2022-12-04 20:42 ` Alejandro Colomar
2022-12-04 22:44 ` Alejandro Colomar
2022-12-04 23:06 ` Sam James
2022-12-04 20:44 ` Alejandro Colomar
1 sibling, 2 replies; 15+ messages in thread
From: Alejandro Colomar @ 2022-12-04 20:42 UTC (permalink / raw)
To: Helge Kreutzmann, GNU C Library; +Cc: mario.blaettermann, linux-man
[-- Attachment #1.1: Type: text/plain, Size: 2547 bytes --]
Hi Helge, glibc developers,
On 12/4/22 10:07, Helge Kreutzmann wrote:
> Without further ado, the following was found:
>
> Issue: Is the "L" in the bracket (for the NULL character) correct?
>
> "The B<wcsncpy>() function is the wide-character equivalent of the"
> "B<strncpy>(3) function. It copies at most I<n> wide characters from the"
> "wide-character string pointed to by I<src>, including the terminating null"
> "wide character (L\\(aq\\e0\\(aq), to the array pointed to by I<dest>."
> "Exactly I<n> wide characters are written at I<dest>. If the length"
> "I<wcslen(src)> is smaller than I<n>, the remaining wide characters in the"
> "array pointed to by I<dest> are filled with null wide characters. If the"
> "length I<wcslen(src)> is greater than or equal to I<n>, the string pointed"
> "to by I<dest> will not be terminated by a null wide character."
As an unrelated note. I've had this running in my mind for some time... your
various bug reports for strncpy(3) and similar wide character functions have
triggered those thougts.
I'm going to mark strncpy(3) and similar functions as deprecated, even if no
libc or standard has done so. There's wide agreement (at least in some
communities) that strncpy(3) _is evil_. There's simply no use for it.
I propose that glibc also marks it as deprecated.
I've worked for a few months on improving string handling in various projects:
shadow-utils <https://github.com/shadow-maint/shadow/pull/569>, and in nginx
Unit. I've come to the following guidelines for using strings:
- strlcpy(3): Copy from string to string, detecting truncation
- strscpy(9): Copy from untrusted string to string, detecting broken ones
- ustr2str(): Copy from unterminated string to string
- Definition:
<https://github.com/shadow-maint/shadow/pull/569/files#diff-a2b8f8568ad025c2aeb4c64d3510f42d874e9ef0a64a89c2dd750aa93aabcd97>
- stpecpy(): Copy from string to string, with easy & safe concatenation, and
reporting truncation at the end of the chain call.
- Definition: <https://software.codidact.com/posts/285946/287522#answer-287522>
- ustr2stpe(): Combination of ustr2str() and stpecpy().
- Definition: Not yet public
And also, memcpy(), mempcpy(), or memccpy() can be used for copying unterminated
strings.
But I don't see any scenario where strncpy() is the right function to call. And
the name is certainly not telling that either.
Cheers,
Alex
--
<http://www.alejandro-colomar.es/>
[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 833 bytes --]
^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: Issue in man page wcsncpy.3
2022-12-04 9:07 Issue in man page wcsncpy.3 Helge Kreutzmann
2022-12-04 20:42 ` Alejandro Colomar
@ 2022-12-04 20:44 ` Alejandro Colomar
2022-12-05 17:09 ` Helge Kreutzmann
1 sibling, 1 reply; 15+ messages in thread
From: Alejandro Colomar @ 2022-12-04 20:44 UTC (permalink / raw)
To: Helge Kreutzmann; +Cc: mario.blaettermann, linux-man
[-- Attachment #1.1: Type: text/plain, Size: 1032 bytes --]
Hi Helge,
On 12/4/22 10:07, Helge Kreutzmann wrote:
> Without further ado, the following was found:
>
> Issue: Is the "L" in the bracket (for the NULL character) correct?
AFAIK, yes. I never used it myself, but I believe L'\0' generates a "null wide
character".
Cheers,
Alex
>
> "The B<wcsncpy>() function is the wide-character equivalent of the"
> "B<strncpy>(3) function. It copies at most I<n> wide characters from the"
> "wide-character string pointed to by I<src>, including the terminating null"
> "wide character (L\\(aq\\e0\\(aq), to the array pointed to by I<dest>."
> "Exactly I<n> wide characters are written at I<dest>. If the length"
> "I<wcslen(src)> is smaller than I<n>, the remaining wide characters in the"
> "array pointed to by I<dest> are filled with null wide characters. If the"
> "length I<wcslen(src)> is greater than or equal to I<n>, the string pointed"
> "to by I<dest> will not be terminated by a null wide character."
--
<http://www.alejandro-colomar.es/>
[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 833 bytes --]
^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: Issue in man page wcsncpy.3
2022-12-04 20:42 ` Alejandro Colomar
@ 2022-12-04 22:44 ` Alejandro Colomar
2022-12-04 23:06 ` Sam James
1 sibling, 0 replies; 15+ messages in thread
From: Alejandro Colomar @ 2022-12-04 22:44 UTC (permalink / raw)
To: Helge Kreutzmann, GNU C Library; +Cc: mario.blaettermann, linux-man
[-- Attachment #1.1: Type: text/plain, Size: 3102 bytes --]
Hi,
On 12/4/22 21:42, Alejandro Colomar wrote:
> As an unrelated note. I've had this running in my mind for some time... your
> various bug reports for strncpy(3) and similar wide character functions have
> triggered those thougts.
>
> I'm going to mark strncpy(3) and similar functions as deprecated, even if no
> libc or standard has done so. There's wide agreement (at least in some
> communities) that strncpy(3) _is evil_. There's simply no use for it.
>
> I propose that glibc also marks it as deprecated.
>
> I've worked for a few months on improving string handling in various projects:
> shadow-utils <https://github.com/shadow-maint/shadow/pull/569>, and in nginx
> Unit. I've come to the following guidelines for using strings:
>
> - strlcpy(3): Copy from string to string, detecting truncation
> - strscpy(9): Copy from untrusted string to string, detecting broken ones
> - ustr2str(): Copy from unterminated string to string
> - Definition:
> <https://github.com/shadow-maint/shadow/pull/569/files#diff-a2b8f8568ad025c2aeb4c64d3510f42d874e9ef0a64a89c2dd750aa93aabcd97>
>
> - stpecpy(): Copy from string to string, with easy & safe concatenation, and
> reporting truncation at the end of the chain call.
> - Definition:
> <https://software.codidact.com/posts/285946/287522#answer-287522>
>
> - ustr2stpe(): Combination of ustr2str() and stpecpy().
> - Definition: Not yet public
>
>
> And also, memcpy(), mempcpy(), or memccpy() can be used for copying unterminated
> strings.
>
> But I don't see any scenario where strncpy() is the right function to call. And
> the name is certainly not telling that either.
I did some initial work, to split strcpy(3) and strncpy(3) manual pages, and
clearly document the only purpose for which strncpy(3) seems to be useful (or at
least, not plain wrong): copying a string into a fixed-width buffer, and
ensuring that no garbage is leaked.
However, even for that niche use-case, it has issues: it can't report truncation.
Consider a trivial implementation of strncpy(3):
char *
strncpy(char *dest, const char *src, size_t n)
{
bzero(dest, n);
memccpy(dest, src, '\0', n);
return dest;
}
As this implementation hints, this function is only useful when you do want to
apply those two calls in that order. There are few use cases for that, but not
inexistent, okay. However:
(1) Having the 2 separate calls is probably better for self documentation than
strncpy(3), especially since strncpy(3) has been misused extensively. However,
if a project correctly documents its use of strncpy(3), it might be fine, and
less code.
(2) strncpy(3) can't detect truncation. strncpy(3) has been misdesigned, and
this repurpose is not great.
(3) Its name is not at all telling what it does.
Which is why I think we should deprecate it.
Cheers,
Alex
--
<http://www.alejandro-colomar.es/>
[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 833 bytes --]
^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: Issue in man page wcsncpy.3
2022-12-04 20:42 ` Alejandro Colomar
2022-12-04 22:44 ` Alejandro Colomar
@ 2022-12-04 23:06 ` Sam James
2022-12-04 23:09 ` Sam James
2022-12-04 23:14 ` Alejandro Colomar
1 sibling, 2 replies; 15+ messages in thread
From: Sam James @ 2022-12-04 23:06 UTC (permalink / raw)
To: Alejandro Colomar
Cc: Helge Kreutzmann, GNU C Library, mario.blaettermann, linux-man
[-- Attachment #1: Type: text/plain, Size: 1819 bytes --]
> On 4 Dec 2022, at 20:42, Alejandro Colomar via Libc-alpha <libc-alpha@sourceware.org> wrote:
>
> Hi Helge, glibc developers,
>
> On 12/4/22 10:07, Helge Kreutzmann wrote:
>> Without further ado, the following was found:
>> Issue: Is the "L" in the bracket (for the NULL character) correct?
>> "The B<wcsncpy>() function is the wide-character equivalent of the"
>> "B<strncpy>(3) function. It copies at most I<n> wide characters from the"
>> "wide-character string pointed to by I<src>, including the terminating null"
>> "wide character (L\\(aq\\e0\\(aq), to the array pointed to by I<dest>."
>> "Exactly I<n> wide characters are written at I<dest>. If the length"
>> "I<wcslen(src)> is smaller than I<n>, the remaining wide characters in the"
>> "array pointed to by I<dest> are filled with null wide characters. If the"
>> "length I<wcslen(src)> is greater than or equal to I<n>, the string pointed"
>> "to by I<dest> will not be terminated by a null wide character."
>
> As an unrelated note. I've had this running in my mind for some time... your various bug reports for strncpy(3) and similar wide character functions have triggered those thougts.
>
> I'm going to mark strncpy(3) and similar functions as deprecated, even if no libc or standard has done so. There's wide agreement (at least in some communities) that strncpy(3) _is evil_. There's simply no use for it.
>
Please don't do this unilaterally. Apple did this unilaterally for sprintf which has caused problems, as well.
It's going to cause confusion as people will inevitably ask where/who deprecated it and there won't
be a solid answer. And if we can't get a libc to agree to deprecate it as well, then doing it in the man
pages is wrong. Even if I understand the spirit of the idea.
Best,
sam
[-- Attachment #2: Message signed with OpenPGP --]
[-- Type: application/pgp-signature, Size: 358 bytes --]
^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: Issue in man page wcsncpy.3
2022-12-04 23:06 ` Sam James
@ 2022-12-04 23:09 ` Sam James
2022-12-04 23:28 ` Alejandro Colomar
2022-12-04 23:14 ` Alejandro Colomar
1 sibling, 1 reply; 15+ messages in thread
From: Sam James @ 2022-12-04 23:09 UTC (permalink / raw)
To: Sam James
Cc: Alejandro Colomar, Helge Kreutzmann, GNU C Library,
mario.blaettermann, linux-man
[-- Attachment #1: Type: text/plain, Size: 1680 bytes --]
> On 4 Dec 2022, at 23:06, Sam James via Libc-alpha <libc-alpha@sourceware.org> wrote:
>
>
>
>> On 4 Dec 2022, at 20:42, Alejandro Colomar via Libc-alpha <libc-alpha@sourceware.org> wrote:
>>
>> Hi Helge, glibc developers,
>>
>> On 12/4/22 10:07, Helge Kreutzmann wrote:
>>> Without further ado, the following was found:
>>> Issue: Is the "L" in the bracket (for the NULL character) correct?
>>> "The B<wcsncpy>() function is the wide-character equivalent of the"
>>> "B<strncpy>(3) function. It copies at most I<n> wide characters from the"
>>> "wide-character string pointed to by I<src>, including the terminating null"
>>> "wide character (L\\(aq\\e0\\(aq), to the array pointed to by I<dest>."
>>> "Exactly I<n> wide characters are written at I<dest>. If the length"
>>> "I<wcslen(src)> is smaller than I<n>, the remaining wide characters in the"
>>> "array pointed to by I<dest> are filled with null wide characters. If the"
>>> "length I<wcslen(src)> is greater than or equal to I<n>, the string pointed"
>>> "to by I<dest> will not be terminated by a null wide character."
>>
>> As an unrelated note. I've had this running in my mind for some time... your various bug reports for strncpy(3) and similar wide character functions have triggered those thougts.
>>
>> I'm going to mark strncpy(3) and similar functions as deprecated, even if no libc or standard has done so. There's wide agreement (at least in some communities) that strncpy(3) _is evil_. There's simply no use for it.
>>
>
> Please don't do this unilaterally. Apple did this unilaterally for sprintf which has caused problems, as well.
snprintf, that is
[-- Attachment #2: Message signed with OpenPGP --]
[-- Type: application/pgp-signature, Size: 358 bytes --]
^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: Issue in man page wcsncpy.3
2022-12-04 23:06 ` Sam James
2022-12-04 23:09 ` Sam James
@ 2022-12-04 23:14 ` Alejandro Colomar
1 sibling, 0 replies; 15+ messages in thread
From: Alejandro Colomar @ 2022-12-04 23:14 UTC (permalink / raw)
To: Sam James; +Cc: Helge Kreutzmann, GNU C Library, mario.blaettermann, linux-man
[-- Attachment #1.1: Type: text/plain, Size: 6094 bytes --]
Hi Sam!
On 12/5/22 00:06, Sam James wrote:
>
>
>> On 4 Dec 2022, at 20:42, Alejandro Colomar via Libc-alpha <libc-alpha@sourceware.org> wrote:
>>
>> Hi Helge, glibc developers,
>>
>> On 12/4/22 10:07, Helge Kreutzmann wrote:
>>> Without further ado, the following was found:
>>> Issue: Is the "L" in the bracket (for the NULL character) correct?
>>> "The B<wcsncpy>() function is the wide-character equivalent of the"
>>> "B<strncpy>(3) function. It copies at most I<n> wide characters from the"
>>> "wide-character string pointed to by I<src>, including the terminating null"
>>> "wide character (L\\(aq\\e0\\(aq), to the array pointed to by I<dest>."
>>> "Exactly I<n> wide characters are written at I<dest>. If the length"
>>> "I<wcslen(src)> is smaller than I<n>, the remaining wide characters in the"
>>> "array pointed to by I<dest> are filled with null wide characters. If the"
>>> "length I<wcslen(src)> is greater than or equal to I<n>, the string pointed"
>>> "to by I<dest> will not be terminated by a null wide character."
>>
>> As an unrelated note. I've had this running in my mind for some time... your various bug reports for strncpy(3) and similar wide character functions have triggered those thougts.
>>
>> I'm going to mark strncpy(3) and similar functions as deprecated, even if no libc or standard has done so. There's wide agreement (at least in some communities) that strncpy(3) _is evil_. There's simply no use for it.
>>
>
> Please don't do this unilaterally. Apple did this unilaterally for sprintf which has caused problems, as well.
>
> It's going to cause confusion as people will inevitably ask where/who deprecated it and there won't
> be a solid answer.
I'm writing up a solid answer for that. Please check
<https://git.kernel.org/pub/scm/docs/man-pages/man-pages.git/tree/man3/strncpy.3>.
The manual page is now all about why it should never be used. In fact, I was
going to do that without adding the [[deprecated]] attribute to the SYNOPSIS,
but I convinced myself that it's necessary after writing that.
I'll copy here the current state of the page. If there's general concern about
the attribute, I can remove it while keeping everything else against its use; I
don't think it will be a big change. But I hope this convinces readers about it
being harmful.
strncpy(3) Library Functions Manual strncpy(3)
NAME
strncpy - copy a string into a fixed‐length buffer and zero the
rest of it
LIBRARY
Standard C library (libc, -lc)
SYNOPSIS
#include <string.h>
[[deprecated]] char *strncpy(char dest[restrict .n],
const char src[restrict .n], size_t n);
DESCRIPTION
Note: This is not the function you want to use. For safe string
copying, see strlcpy(3bsd). For copying a string into a fixed‐
length buffer with zeroing of the rest, see stpncpy(3).
The strncpy() copies at most n bytes of src, and fills the rest of
the dest buffer with null bytes. Warning: If there is no null
byte among the first n bytes of src, the string placed in dest
will not be null‐terminated.
A simple implementation of strncpy() might be:
char *
strncpy(char *dest, const char *src, size_t n)
{
bzero(dest, n);
memccpy(dest, src, '\0', n);
return dest;
}
The only valid use of strncpy() is to copy a C string to a fixed‐
length buffer while ensuring that unused bytes in the destination
buffer are zeroed out (perhaps to prevent information leaks if the
buffer is to be written to media or transmitted to another process
via an interprocess communication technique). But stpncpy(3) is
better for this purpose, since it detects truncation. See CAVEATS
below.
RETURN VALUE
The strncpy() function returns a pointer to the destination buffer
dest.
ATTRIBUTES
For an explanation of the terms used in this section, see attrib‐
utes(7).
┌───────────────────────────────────────┬───────────────┬─────────┐
│Interface │ Attribute │ Value │
├───────────────────────────────────────┼───────────────┼─────────┤
│strncpy() │ Thread safety │ MT‐Safe │
└───────────────────────────────────────┴───────────────┴─────────┘
STANDARDS
POSIX.1‐2001, POSIX.1‐2008, C89, C99, SVr4, 4.3BSD.
CAVEATS
strncpy() has a misleading name. It doesn’t produce a (null‐ter‐
minated) string; and it should never be used for producing a
string.
It can’t detect truncation. It’s probably better to explicitly
call bzero(3) and memccpy(3), or stpncpy(3) since they allow de‐
tecting truncation.
SEE ALSO
bzero(3), memccpy(3), stpncpy(3), string(3), wcsncpy(3)
Linux man‐pages (unreleased) (date) strncpy(3)
> And if we can't get a libc to agree to deprecate it as well, then doing it in the man
> pages is wrong. Even if I understand the spirit of the idea.
I hope this can convince someone in glibc :)
If there's consensus against marking it as [[deprecated]], I'll revert that bit
before the next release later this month.
Cheers,
Alex
>
> Best,
> sam
--
<http://www.alejandro-colomar.es/>
[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 833 bytes --]
^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: Issue in man page wcsncpy.3
2022-12-04 23:09 ` Sam James
@ 2022-12-04 23:28 ` Alejandro Colomar
0 siblings, 0 replies; 15+ messages in thread
From: Alejandro Colomar @ 2022-12-04 23:28 UTC (permalink / raw)
To: Sam James, Sam James
Cc: Helge Kreutzmann, GNU C Library, mario.blaettermann, linux-man
[-- Attachment #1.1: Type: text/plain, Size: 1917 bytes --]
Hi Sam,
On 12/5/22 00:09, Sam James wrote:
>
>
>> On 4 Dec 2022, at 23:06, Sam James via Libc-alpha <libc-alpha@sourceware.org> wrote:
>>
>>
>>
>>> On 4 Dec 2022, at 20:42, Alejandro Colomar via Libc-alpha <libc-alpha@sourceware.org> wrote:
>>>
>>> Hi Helge, glibc developers,
>>>
>>> On 12/4/22 10:07, Helge Kreutzmann wrote:
>>>> Without further ado, the following was found:
>>>> Issue: Is the "L" in the bracket (for the NULL character) correct?
>>>> "The B<wcsncpy>() function is the wide-character equivalent of the"
>>>> "B<strncpy>(3) function. It copies at most I<n> wide characters from the"
>>>> "wide-character string pointed to by I<src>, including the terminating null"
>>>> "wide character (L\\(aq\\e0\\(aq), to the array pointed to by I<dest>."
>>>> "Exactly I<n> wide characters are written at I<dest>. If the length"
>>>> "I<wcslen(src)> is smaller than I<n>, the remaining wide characters in the"
>>>> "array pointed to by I<dest> are filled with null wide characters. If the"
>>>> "length I<wcslen(src)> is greater than or equal to I<n>, the string pointed"
>>>> "to by I<dest> will not be terminated by a null wide character."
>>>
>>> As an unrelated note. I've had this running in my mind for some time... your various bug reports for strncpy(3) and similar wide character functions have triggered those thougts.
>>>
>>> I'm going to mark strncpy(3) and similar functions as deprecated, even if no libc or standard has done so. There's wide agreement (at least in some communities) that strncpy(3) _is evil_. There's simply no use for it.
>>>
>>
>> Please don't do this unilaterally. Apple did this unilaterally for sprintf which has caused problems, as well.
>
> snprintf, that is
No, they deprecated sprintf(3), AFAIK.
<https://lists.gnu.org/r/bug-gnulib/2022-11/msg00013.html>
Cheers,
Alex
--
<http://www.alejandro-colomar.es/>
[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 833 bytes --]
^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: Issue in man page wcsncpy.3
2022-12-04 20:44 ` Alejandro Colomar
@ 2022-12-05 17:09 ` Helge Kreutzmann
2022-12-05 17:55 ` G. Branden Robinson
0 siblings, 1 reply; 15+ messages in thread
From: Helge Kreutzmann @ 2022-12-05 17:09 UTC (permalink / raw)
To: Alejandro Colomar; +Cc: mario.blaettermann, linux-man
[-- Attachment #1: Type: text/plain, Size: 1271 bytes --]
Hello Alejandro,
On Sun, Dec 04, 2022 at 09:44:47PM +0100, Alejandro Colomar wrote:
> On 12/4/22 10:07, Helge Kreutzmann wrote:
> > Without further ado, the following was found:
> >
> > Issue: Is the "L" in the bracket (for the NULL character) correct?
>
> AFAIK, yes. I never used it myself, but I believe L'\0' generates a "null
> wide character".
Just to get this clear for myself, the man page currently use quoting
characters (not plain ''), i.e.
L\\(aq\\e0\\(aq
And this should not be translated? Currently I translate the quotes,
i.e. in German this is marked as:
L»\\e0«
This is probably wrong?
Is there a way to note that this quotes are not to be translated even
though they are not printed literally but with the macro \\(aq?
I explicitly ask this because using macros (markup) is a clear sign
for me that it can be translated, and thus this breaks my heuristics.
Thanks for clarifications.
Greetings
Helge
--
Dr. Helge Kreutzmann debian@helgefjell.de
Dipl.-Phys. http://www.helgefjell.de/debian.php
64bit GNU powered gpg signed mail preferred
Help keep free software "libre": http://www.ffii.de/
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]
^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: Issue in man page wcsncpy.3
2022-12-05 17:09 ` Helge Kreutzmann
@ 2022-12-05 17:55 ` G. Branden Robinson
2023-01-25 20:01 ` Jakub Wilk
0 siblings, 1 reply; 15+ messages in thread
From: G. Branden Robinson @ 2022-12-05 17:55 UTC (permalink / raw)
To: Helge Kreutzmann; +Cc: Alejandro Colomar, mario.blaettermann, linux-man
[-- Attachment #1: Type: text/plain, Size: 6915 bytes --]
Hi Helge,
At 2022-12-05T18:09:35+0100, Helge Kreutzmann wrote:
> Hello Alejandro,
> On Sun, Dec 04, 2022 at 09:44:47PM +0100, Alejandro Colomar wrote:
> > On 12/4/22 10:07, Helge Kreutzmann wrote:
> > > Without further ado, the following was found:
> > >
> > > Issue: Is the "L" in the bracket (for the NULL character) correct?
> >
> > AFAIK, yes. I never used it myself, but I believe L'\0' generates a "null
> > wide character".
>
> Just to get this clear for myself, the man page currently use quoting
> characters (not plain ''), i.e.
>
> L\\(aq\\e0\\(aq
Right. \(aq means "write out ASCII 39 decimal (U+0027)".[0]
> And this should not be translated? Currently I translate the quotes,
> i.e. in German this is marked as:
>
> L»\\e0«
>
> This is probably wrong?
Yes. You are turning this into a set of typographical quotes for
written prose, but the expression is a literal constant in the C
language and must be typed using "straight single quotes" a.k.a. ASCII
39 decimal.
L'\0' is a null wide character, that is, a null character of type
wchar_t. The language has this because '\0' without the L prefix
already means a null character constant of CHAR_BITS width; if wchar_t
is wider than that, then there can be ambiguity with respect to what
happens to the higher-order bits in the object thus initialized.
The following compiles without warnings on my system, even with -Wall.
int main(int argc, char *argv[]) {
wchar_t w1 = '\0', w2 = L'\0';
printf("%d\n", (w1 + w2));
}
For me this reliably writes "0" to the standard output.
However it is conceivable, depending on the implementation, that bits 8+
of w1 come from uninitialized memory, and a large positive or negative
value would be written to stdout.
C is full of undefined and implementation-dependent behavior. This is
what makes it go fast and break stuff.
> Is there a way to note that this quotes are not to be translated even
> though they are not printed literally but with the macro \\(aq?
Technically, in roff parlance, that is not a macro, but a special
character escape sequence.[1]
> I explicitly ask this because using macros (markup) is a clear sign
> for me that it can be translated, and thus this breaks my heuristics.
That heuristic is not reliable. \(aq and \(dq, among other
characters,[2] will often be used in man pages to _avoid_ the output of
glyphs common in a conventional prose typography context.
groff_char(7) surveys several kinds of quotation mark. UTF-8 follows.
Quotation marks
The neutral double quote, often useful when documenting programming
languages, is also available as a special character for convenient
embedding in macro arguments; see subsection “Fundamental character
set” above.
Output Input Unicode Notes
─────────────────────────────────────────────────────────────────────
„ \[Bq] u201E low double comma quote
‚ \[bq] u201A low single comma quote
“ \[lq] u201C left double quote
” \[rq] u201D right double quote
‘ \[oq] u2018 single opening (left) quote
’ \[cq] u2019 single closing (right) quote
' \[aq] u0027 apostrophe, neutral single quote
" " u0022 neutral double quote
" \[dq] u0022 neutral double quote
« \[Fo] u00AB left double chevron
» \[Fc] u00BB right double chevron
‹ \[fo] u2039 left single chevron
› \[fc] u203A right single chevron
Programming languages frequently attach important semantics to \(aq and
\(dq (ASCII ' and "), so it is important not to subject these to natural
language quotation mark transformations.
Because of their specialized nature, this also means that if you see a
man page using them in prose, the page is wrong. You should translate
the quotation marks as if you were seeing \(lq, \(rq, \(oq, \(cq, and so
forth.
Here's an example of erroneous input.
After reading from /proc/$$/mem, Anne\(aqs mom told her not to
\(dqparty\(dq.
The foregoing should be recast to use conventional punctuation and
typographer's quotes.
After reading from /proc/$$/mem, Anne's mom told her not to
\(lqparty\(rq.
The above uses en_US quotation; en_GB practice is different.
After reading from /proc/$$/mem, Anne's mom told her not to
\(oqparty\(cq.
...but experienced readers of English generally have little trouble
switching conventions.[2]
Regards,
Branden
[0] Technically, the glyph corresponding to it, and this will do the
right thing even on OS/390 Unix, which uses code page 1047 (EBCDIC).
There is a way to ask for glyph index 39 in the current font, but a
man page should never fool with that.
[1] Once a groff user is good and comfortable with the distinction,
someone comes along and does this.
https://git.savannah.gnu.org/cgit/groff.git/tree/src/roff/troff/node.cpp#n5029
This is why manufacturers of voodoo dolls will never starve.
[2] From groff_man_style(7):
• Some ASCII characters look funny or copy and paste wrong.
On devices with large glyph repertoires, like UTF‐8‐capable
terminals and PDF, several keyboard glyphs are mapped to code
points outside the Unicode basic Latin range because that
usually results in better typography in the general case. When
documenting GNU/Linux command or C language syntax, however,
this translation is sometimes not desirable.
To get a “literal”... ...should be input.
────────────────────────────────────────────
' \(aq
- \-
\ \(rs
^ \(ha
` \(ga
~ \(ti
────────────────────────────────────────────
Additionally, if a neutral double quote (") is needed in a macro
argument, you can use \(dq to get it. You should not use \(aq
for an ordinary apostrophe (as in “can’t”) or \- for an ordinary
hyphen (as in “word‐aligned”). Review subsection “Portability”
above.
[3] The U.K. practice of dropping periods from abbreviations when the
last letter of the abbreviated word remains intact is far more
distracting and productive of ambiguity.
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]
^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: Issue in man page wcsncpy.3
2022-12-05 17:55 ` G. Branden Robinson
@ 2023-01-25 20:01 ` Jakub Wilk
0 siblings, 0 replies; 15+ messages in thread
From: Jakub Wilk @ 2023-01-25 20:01 UTC (permalink / raw)
To: G. Branden Robinson
Cc: Helge Kreutzmann, Alejandro Colomar, mario.blaettermann,
linux-man
* G. Branden Robinson <g.branden.robinson@gmail.com>, 2022-12-05 11:55:
>The following compiles without warnings on my system, even with -Wall.
>
>int main(int argc, char *argv[]) {
> wchar_t w1 = '\0', w2 = L'\0';
> printf("%d\n", (w1 + w2));
>}
>
>For me this reliably writes "0" to the standard output.
>
>However it is conceivable, depending on the implementation, that bits
>8+ of w1 come from uninitialized memory, and a large positive or
>negative value would be written to stdout.
Er, no? Both assignments and additions in this code are well defined.
You're just operating with zeros of different types, which is completely
fine.
The only potential for undefined behavior is printf, because %d may not
be compatible with wchar_t. In fact, it isn't on my system (i386):
wchar.c:5:18: warning: format ‘%d’ expects argument of type ‘int’, but argument 2 has type ‘wchar_t’ {aka ‘long int’} [-Wformat=]
--
Jakub Wilk
^ permalink raw reply [flat|nested] 15+ messages in thread
* Issue in man page wcsncpy.3
@ 2023-03-11 17:13 Helge Kreutzmann
2023-03-11 23:23 ` Alejandro Colomar
0 siblings, 1 reply; 15+ messages in thread
From: Helge Kreutzmann @ 2023-03-11 17:13 UTC (permalink / raw)
To: alx.manpages; +Cc: mario.blaettermann, linux-man
Without further ado, the following was found:
Issue: null wide characters → NUL wide characters?
"The B<wcsncpy>() function is the wide-character equivalent of the "
"B<strncpy>(3) function. It copies at most I<n> wide characters from the "
"wide-character string pointed to by I<src>, including the terminating null "
"wide character (L\\[aq]\\e0\\[aq]), to the array pointed to by I<dest>. "
"Exactly I<n> wide characters are written at I<dest>. If the length "
"I<wcslen(src)> is smaller than I<n>, the remaining wide characters in the "
"array pointed to by I<dest> are filled with null wide characters. If the "
"length I<wcslen(src)> is greater than or equal to I<n>, the string pointed "
"to by I<dest> will not be terminated by a null wide character."
^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: Issue in man page wcsncpy.3
2023-03-11 17:13 Helge Kreutzmann
@ 2023-03-11 23:23 ` Alejandro Colomar
2023-03-12 4:54 ` Helge Kreutzmann
0 siblings, 1 reply; 15+ messages in thread
From: Alejandro Colomar @ 2023-03-11 23:23 UTC (permalink / raw)
To: Helge Kreutzmann; +Cc: mario.blaettermann, linux-man
[-- Attachment #1.1: Type: text/plain, Size: 1131 bytes --]
Hi Helge,
On 3/11/23 18:13, Helge Kreutzmann wrote:
> Without further ado, the following was found:
>
> Issue: null wide characters → NUL wide characters?
This is incorrect. NUL is an ASCII character, which hasn't wide
characters. It's correct as "null wide characters", a.k.a. L'\0'.
Cheers,
Alex
>
> "The B<wcsncpy>() function is the wide-character equivalent of the "
> "B<strncpy>(3) function. It copies at most I<n> wide characters from the "
> "wide-character string pointed to by I<src>, including the terminating null "
> "wide character (L\\[aq]\\e0\\[aq]), to the array pointed to by I<dest>. "
> "Exactly I<n> wide characters are written at I<dest>. If the length "
> "I<wcslen(src)> is smaller than I<n>, the remaining wide characters in the "
> "array pointed to by I<dest> are filled with null wide characters. If the "
> "length I<wcslen(src)> is greater than or equal to I<n>, the string pointed "
> "to by I<dest> will not be terminated by a null wide character."
--
<http://www.alejandro-colomar.es/>
GPG key fingerprint: A9348594CE31283A826FBDD8D57633D441E25BB5
[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 833 bytes --]
^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: Issue in man page wcsncpy.3
2023-03-11 23:23 ` Alejandro Colomar
@ 2023-03-12 4:54 ` Helge Kreutzmann
0 siblings, 0 replies; 15+ messages in thread
From: Helge Kreutzmann @ 2023-03-12 4:54 UTC (permalink / raw)
To: Alejandro Colomar; +Cc: mario.blaettermann, linux-man
[-- Attachment #1: Type: text/plain, Size: 737 bytes --]
Hello Alex,
On Sun, Mar 12, 2023 at 12:23:20AM +0100, Alejandro Colomar wrote:
> > Without further ado, the following was found:
> >
> > Issue: null wide characters → NUL wide characters?
>
> This is incorrect. NUL is an ASCII character, which hasn't wide
> characters. It's correct as "null wide characters", a.k.a. L'\0'.
Thanks for the explanation; I'm still learning about these NUL(L).
Greetings
Helge
--
Dr. Helge Kreutzmann debian@helgefjell.de
Dipl.-Phys. http://www.helgefjell.de/debian.php
64bit GNU powered gpg signed mail preferred
Help keep free software "libre": http://www.ffii.de/
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]
^ permalink raw reply [flat|nested] 15+ messages in thread
* Issue in man page wcsncpy.3
@ 2025-08-24 14:48 Helge Kreutzmann
0 siblings, 0 replies; 15+ messages in thread
From: Helge Kreutzmann @ 2025-08-24 14:48 UTC (permalink / raw)
To: alx; +Cc: mario.blaettermann, linux-man
Without further ado, the following was found:
Issue: B<…>size_t n → B<…size_t> I<n>
"B<wchar_t *wcsncpy(>size_t n;\n"
"B< wchar_t >I<dest>B<[restrict >I<n>B<],>\n"
"B< const wchar_t *restrict >I<src>B<,>\n"
"B< size_t >I<n>B<);>\n"
^ permalink raw reply [flat|nested] 15+ messages in thread
end of thread, other threads:[~2025-08-24 14:48 UTC | newest]
Thread overview: 15+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2022-12-04 9:07 Issue in man page wcsncpy.3 Helge Kreutzmann
2022-12-04 20:42 ` Alejandro Colomar
2022-12-04 22:44 ` Alejandro Colomar
2022-12-04 23:06 ` Sam James
2022-12-04 23:09 ` Sam James
2022-12-04 23:28 ` Alejandro Colomar
2022-12-04 23:14 ` Alejandro Colomar
2022-12-04 20:44 ` Alejandro Colomar
2022-12-05 17:09 ` Helge Kreutzmann
2022-12-05 17:55 ` G. Branden Robinson
2023-01-25 20:01 ` Jakub Wilk
-- strict thread matches above, loose matches on Subject: below --
2023-03-11 17:13 Helge Kreutzmann
2023-03-11 23:23 ` Alejandro Colomar
2023-03-12 4:54 ` Helge Kreutzmann
2025-08-24 14:48 Helge Kreutzmann
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.