This is the mail archive of the libc-alpha@sourceware.org mailing list for the glibc project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: Implement C11 annex K?


Tolga Dalman <tolga.dalman@googlemail.com> writes:

> Your argumentation appears inconsistent to me. strlcpy is a bad API by
> design and provides no benefits except convenience for some applications
> (how many use these functions, btw ?).  If an application chooses to use
> a non-portable and probably buggy function, well, then the application
> should be fixed. Not glibc.

I've heard this statement a lot, and I certainly have a lot of sympathy
with the argument that one should use dynamic strings.  And I do use
asprintf by preference.  But this argument is applied so universally,
which leaves me wondering if I'm missing something.

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
messed up the length calculation logic, I would prefer to truncate the
string than to create a buffer overflow.  The truncation might still be a
security vulnerability; the buffer overflow is almost guaranteed to be
one.  Maybe this is just personal preference.

If you have some method that doesn't involve strcpy and strcat either, and
that you think is as readable as the above, I would love to hear what it
is.  That's a sincere question: I would be happy to be taught how to be a
better C programmer.

-- 
Russ Allbery (eagle@eyrie.org)              <http://www.eyrie.org/~eagle/>


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]