delorie.com/archives/browse.cgi   search  
Mail Archives: djgpp-workers/2003/01/08/20:41:28

X-Originating-IP: [204.39.230.222]
From: "David F" <foobar1996 AT hotmail DOT com>
To: djgpp-workers AT delorie DOT com
Subject: Re: RESEND: strlcat, strlcpy [PATCH]
Date: Thu, 09 Jan 2003 00:28:20 +0000
Mime-Version: 1.0
Message-ID: <F9cwAQq12LRF58tP9DL000250b7@hotmail.com>
X-OriginalArrivalTime: 09 Jan 2003 00:28:20.0829 (UTC) FILETIME=[033F28D0:01C2B776]
Reply-To: djgpp-workers AT delorie DOT com

Hello,

There are a couple of omissions in the original paper. The specifications 
for both strlcpy and strlcat fail to consider the case where the buffers 
overlap. IMO, this is a minor issue. I figure most people would assume they 
handle such cases the same as strcpy and strcat, which is to say they don't 
handle such cases. So something along the lines of the following sentence 
should be added to their specification: "If copying takes place between 
objects that overlap, the behavior is undefined." Were they to be 
implemented in C99, their pointer arguments would most likely be restrict 
qualified.

The second omission concerns an unconsidered case with regard to the input 
to strlcat. The original paper fails to consider the case when a NUL 
character is not found within the destination buffer. This case is strange 
to say the least and almost certainly represents a bug in the calling code, 
however, I think the behavior of strlcat in such a case should be defined. 
Particularly, I think strlcat should not read past the end of the buffer. I 
believe that in such cases the buffer should remain unmodified and strlcat's 
return value should be the sum of the specified buffer length and the length 
of the would-be concatenated string. That is how the current OpenBSD 
implementation handles this case. If you check the RCS log for OpenBSD's 
strlcat.c you will see that someone submitted a patch that would read past 
the end of the buffer until it found a NUL. The OpenBSD maintainers 
committed the patch, though better of it, and backed-out the patch a few 
hours latter.

It's worth noting that the implementation proposed for inclusion in djgpp's 
libc will read past the end of the buffer.

Personally, I like the below-included implementations. I believe them to be 
correct, they have no dependencies, and I think any modern compiler should 
be able to generate reasonably decent code from them (I could be wrong 
though; on any or all counts). Inclusion in a libc (and one that will only 
be compiled with gcc, at that) was not one of my goals when I wrote them, 
however.

DJGPP was one of my first introductions to Free Software, and I am grateful 
for the effort you guys put into it.

Cheers

I hereby disclaim any copyright interest in the following code.


size_t strlcpy(char *dest, const char *src, size_t count)
{
    const char *p = src;

    if (count > 0) {
        while(--count && *p)
            *dest++ = *p++;

        *dest = '\0';
    }

    for (; *p; ++p);

    return p - src;
}


size_t strlcat(char *dest, const char *src, size_t count)
{
    char *p = dest;
    const char *s;

    while (count && *p) {
        ++p;
        --count;
    }

    if (count > 0) {
        while(--count && *src)
            *p++ = *src++;

        *p = '\0';
    }

    if (!*src) {
        return p - dest;
    } else {
        s = src;

        do {
            ++src;
        } while (*src);

        return (p - dest) + (src - s);
    }
}


_________________________________________________________________
Add photos to your e-mail with MSN 8. Get 2 months FREE*. 
http://join.msn.com/?page=features/featuredemail

- Raw text -


  webmaster     delorie software   privacy  
  Copyright © 2019   by DJ Delorie     Updated Jul 2019