Re: strcpy versus strncpy

From: der Mouse (mouseat_private)
Date: Wed Mar 04 1998 - 06:56:56 PST

  • Next message: Nick Maclaren: "Re: strcpy versus strncpy"

    > What's wrong with using the following [...]?
    > It's not MT safe, but other than that I can't see any problems.
    
    > char *sstrcpy(char *dst, size_t n, const char *src) {
    >     if (strlen(src) > (n - 1)) {
    
    Can you count on src being NUL-terminated?  If not, calling strlen on
    it is unsafe; you could run off the end of VM and segfault.
    
    >         errno = ENOSPC;
    
    This is exactly as thread-safe as errno itself is.
    
    >         return NULL;
    >     }
    >     strcpy(dst, src);
    >     dst[n - 1] = '\0';
    
    This assignment is unnecessary, unless src was changed between the
    strlen and the strcpy - and in that case, all alleged safety goes out
    the window anyway.
    
    >     return dst;
    > }
    
    Aside from errno (and the caveat about src being changed asynchronously
    wrt sstrcpy), I can't see any reason it wouldn't be fully thread-safe -
    unless of course strlen or strcpy is somehow thread-unsafe.
    
    Incidentally, a while ago strnlen was mentioned (I think it was on
    bugtraq, though I could be misremembering), and I saw at least two
    suggested implementations that amount to
    
    int strnlen(const char *s, int maxlen)
    {
     const char *np;
    
     np = memchr(s,0,maxlen);
     return(np?np-s:maxlen);
    }
    
    This is not OK; memchr is allowed to access any subset it pleases of
    the block of memory described by its first and third arguments.
    strnlen should not access memory beyond the NUL, if there is one (or at
    least it should behave "as if" that were the case; on some
    architectures, for example, it may be possible to read multiple bytes
    at once anyway).
    
    If you still don't see how can it make a difference, consider this
    example: suppose VM ends at 0x100000, and the arguments passed to
    strnlen are 0xffff0 and 128, but there is a NUL present at 0xffff9.
    memchr as called above would be within its interface contract to
    segfault instead of returning 0xffff9, but strnlen wouldn't.
    
                                            der Mouse
    
                                   mouseat_private
                         7D C8 61 52 5D E7 2D 39  4E F1 31 3E E8 B3 27 4B
    



    This archive was generated by hypermail 2b30 : Fri Apr 13 2001 - 13:43:59 PDT