[PATCH] Implement strlcat [BZ#178]
Paul Eggert
eggert@cs.ucla.edu
Thu Dec 3 17:33:00 GMT 2015
Thanks for the review. Revised patchset attached. At this point I'm
inclined to install the first two patches (which don't change semantics)
to make it easier to review and maintain the third one (which adds
strlcpy+strlcat), but I'll hold off a bit longer on that to get more
feedback.
Replying to your comments:
> I don't understand the “and as for strings usually pointers … are used”
> part.
Changed to "A wide-string variable is usually declared to be a pointer
of type @code{wchar_t *}, by analogy with string variables and
@code{char *}." Hope this makes it clear.
> Standard uses “wide string” by the way, not “wide character string”.
C11 says "wide string", POSIX says "wide-character string". True, the
more-concise form is better here, so I've changed it to that. Similarly,
I changed "multibyte character string" (POSIX wording) to "multibyte
string" (C Standard wording). I wish the standards could standardize the
wording...
> Please also use “integer constant @code{0}”. Only the integer constant
> zero represents a null pointer, an integer variable which stores the
> value zero does not.
Done.
> +literal. Strings can also be formed by @dfn{string concatenation}:
> +@code{"a" "b"} is the
>
> The original had “string literal”. As this only works for string
> literals, it's best to keep it.
The original was incorrect; it said "string literals can also be formed
by @dfn{string concatenation}" but string literals are the input to
string concatenation, not the output from it. I changed the wording to
"String literals can also contribute to @dfn{string concatenation}:...".
> blocks of memory, and functions that are specific to null-terminated
> -arrays of characters and wide characters.
> +strings and wide strings.
>
> Should be “specific to strings and wide character strings” (the
> “null-terminated” is redundant,
OK, though this will be "wide strings" as per the above-described changed.
> and “wide strings” has not been defined.
>
> Most of the remaining “null-terminated” occurrences in string.texi
> should be removed, for consistency and clarity.
Sure, done.
> @@ -309,7 +318,8 @@ returns @var{maxlen}. Therefore this function is
> equivalent to
> @code{(strlen (@var{s}) < @var{maxlen} ? strlen (@var{s}) : @var{maxlen})}
> but it
> is more efficient and works even if the string @var{s} is not
> -null-terminated.
> +null-terminated so long as @var{maxlen} does not exceed the
> +size of @var{s}'s array.
>
> This doesn't make much sense anymore because strings are defined to be
> always null-terminated.
Reworded to "If the array @var{s} of size @var{maxlen} contains a null
byte, the @code{strnlen} function returns the length of the string
@var{s} in bytes. Otherwise it returns @var{maxlen}. Therefore this
function is equivalent to @code{(strlen (@var{s}) < @var{maxlen} ?
strlen (@var{s}) : @var{maxlen})} but it is more efficient and works
even if @var{s} is not null-terminated so long as @var{maxlen} does not
exceed the size of @var{s}'s array."
>
>> PS. This time around I noticed that in some cases strlcat is required
>> to not null-terminate its output, even when there's room for a null byte
>> in the destination buffer. Eeeuuuw. Do we really want to document that
>> particular misfeature? Does user code really require it?
> It's part of the specification, as far as I can tell.
Yes and no. The FreeBSD man page says that "for strlcat() both src and
dst must be NUL-terminated"; see
<https://www.freebsd.org/cgi/man.cgi?query=strlcpy&sektion=3>.
Admittedly the FreeBSD spec is confused here, as the second part of its
RETURN VALUES section describes what happens when the destination is not
null-terminated! But that section also says "this should not happen",
and obviously user code should not depend on behavior that "should not
happen" and in practice I expect user code follows this, so let's go
with the slightly-tighter spec.
Come to think of it, this is related to the confusion between one of the
main goals of strlcpy (namely, the result is always null-terminated),
and the weird special case where the destination size is zero (where
strlcpy cannot null-terminate the destination). In practice user code
does not and should not depend on this weird special case. We can fix
this confusion by making strlcpy have undefined behavior if the
destination size is zero. This simplifies the spec, and gives us an
opportunity to add one more runtime sanity check that the destination
size is nonzero in our debugging implementation, if we want to do that.
I've added this idea to the third patch in the attached patchset (which
changes only the documentation).
-------------- next part --------------
A non-text attachment was scrubbed...
Name: 0001-Consistency-about-byte-vs-character-in-string.texi.patch
Type: text/x-patch
Size: 66051 bytes
Desc: not available
URL: <http://sourceware.org/pipermail/libc-alpha/attachments/20151203/2dc9a9e4/attachment.bin>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: 0002-Split-large-string-section-add-truncation-advice.patch
Type: text/x-patch
Size: 28746 bytes
Desc: not available
URL: <http://sourceware.org/pipermail/libc-alpha/attachments/20151203/2dc9a9e4/attachment-0001.bin>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: 0003-Add-strlcpy-strlcat.patch
Type: text/x-patch
Size: 6134 bytes
Desc: not available
URL: <http://sourceware.org/pipermail/libc-alpha/attachments/20151203/2dc9a9e4/attachment-0002.bin>
More information about the Libc-alpha
mailing list