This is the mail archive of the
libc-alpha@sourceware.org
mailing list for the glibc project.
Re: Implement C11 annex K?
- From: Rich Felker <dalias at libc dot org>
- To: libc-alpha at sourceware dot org
- Date: Wed, 13 Aug 2014 22:25:01 -0400
- Subject: Re: Implement C11 annex K?
- Authentication-results: sourceware.org; auth=none
- References: <E1XHe8v-0004Ur-Hp at rmm6prod02 dot runbox dot com> <Pine dot LNX dot 4 dot 64 dot 1408132054090 dot 16622 at digraph dot polyomino dot org dot uk> <53EBD7D9 dot 1040008 at cs dot ucla dot edu> <20140813213520 dot GQ12888 at brightrain dot aerifal dot cx> <53EBEACD dot 3070000 at googlemail dot com> <87k36cc559 dot fsf at windlord dot stanford dot edu>
On Wed, Aug 13, 2014 at 04:59:46PM -0700, Russ Allbery wrote:
> At the risk of drifting off into the weeds (and if you feel like this is
> inappropriate for this mailing list, please feel free to only respond in
> private or tell me that in private), how would you recommend writing this
> function without using strlcpy and strlcat?
>
> /*
> * Given a vector and a separator string, allocate and build a new string
> * composed of all the strings in the vector separated from each other by the
> * seperator string. Caller is responsible for freeing.
> */
> char *
> vector_join(const struct vector *vector, const char *seperator)
> {
> char *string;
> size_t i, size, seplen;
>
> /* If the vector is empty, this is trivial. */
> assert(vector != NULL);
> if (vector->count == 0)
> return xstrdup("");
>
> /* Determine the total size of the resulting string. */
> seplen = strlen(seperator);
> for (size = 0, i = 0; i < vector->count; i++)
> size += strlen(vector->strings[i]);
> size += (vector->count - 1) * seplen + 1;
>
> /* Allocate the memory and build up the string using strlcat. */
> string = xmalloc(size);
> strlcpy(string, vector->strings[0], size);
> for (i = 1; i < vector->count; i++) {
> strlcat(string, seperator, size);
> strlcat(string, vector->strings[i], size);
> }
> return string;
> }
>
> If the answer is "use strcpy and strcat because this code is provably
> correct with them," I guess I understand your position, but if I somehow
The answer is "use memcpy". While statements of absolutes are
generally wrong, I'd venture very close to saying you should never use
any functions except snprintf and memcpy for constructing strings, at
least not unless you're an expert and willing to spend a lot of extra
time checking over your code to make sure you didn't make careless
errors.
There are a few places where strcpy is safe and efficient (e.g. when
you know a bound on the length of a string because it's a tail of a
string of known length, and thereby know that it fits in the
destination buffer, but you don't have the original pointer to get the
exact length and use memcpy) but these are definitely rare cases
rather than the norm.
Rich