This is the mail archive of the
libc-alpha@sourceware.org
mailing list for the glibc project.
Re: [PATCH] Implement strlcpy [BZ #178]
- From: Rich Felker <dalias at libc dot org>
- To: libc-alpha at sourceware dot org
- Date: Mon, 15 Sep 2014 11:34:07 -0400
- Subject: Re: [PATCH] Implement strlcpy [BZ #178]
- Authentication-results: sourceware.org; auth=none
- References: <5416EDEA dot 4080903 at redhat dot com>
On Mon, Sep 15, 2014 at 03:47:22PM +0200, Florian Weimer wrote:
> +size_t
> +strlcpy(char *__restrict dest, const char *__restrict src, size_t size)
> +{
> + if (__glibc_unlikely (size == 0))
> + return 0;
This is definitely wrong. strlcpy always returns strlen(src),
regardless of what it can or cannot store. See the specification here:
http://www.openbsd.org/cgi-bin/man.cgi?query=strlcpy
> + size_t src_length = strnlen (src, size);
> + if (__glibc_unlikely (src_length >= size))
> + {
> + /* Copy the leading portion of the string, excluding the NUL
> + character. The last character will be overwritten, but the
> + destination size is usually a multiple of a small power of
> + two, so writing it twice should be more efficient. */
> + memcpy (dest, src, size);
> + dest[size - 1] = '\0';
> + return size - 1;
> + }
> + else
> + {
> + /* Copy the string and its terminating NUL character. */
> + memcpy (dest, src, src_length + 1);
> + return src_length;
> + }
> +}
> +libc_hidden_def (strlcpy)
And likewise this is wrong. You need strlen, not strnlen. I agree in
many respects an interface that returned something like strnlen would
have been nicer, but the only thing worse than having applications
provide their own buggy and incompatible versions of this function is
having the system libc provide an incompatible version. If this kind
of incompatibility made it into glibc, the amount of hackery trying to
determine whether the system libc's strlcpy is usable or needs to be
replaced would vastly increase (probably in ways that break
cross-compiling due to trying to perform runtime tests) and we'd have
an utter mess.
Rich