tags:

views:

222

answers:

5

Hello,

I have decided to make a wrapper for strncpy as my source code requires me to do a lot of string copies. And I want to ensure that the string is terminated if the source is equal or greater than the destination.

As this code will be used in production, so I just want to see if there are any potential dangers using this wrapper.

I have never done wrappers before so tyring to make itI am trying to make it perfect.

Many thanks for any advice,

/* Null terminate a string after coping */
char* strncpy_wrapper(char *dest, const char* source, 
          const size_t dest_size, const size_t source_size)
{
    strncpy(dest, source, dest_size);
    /* 
     * Compare the different length, if source is greater
     * or equal to the destination terminate with a null.
     */
    if(source_size >= dest_size)
    {
     dest[dest_size - 1] = '\0';
    }

    return dest;
}

==== Edited updated ====

/* Null terminate a string after coping */
char* strncpy_wrapper(char *dest, const char* source, 
          const size_t dest_size)
{
    strncpy(dest, source, dest_size);
    /* 
     * If the destination is greater than zero terminate with a null.
     */
    if(dest_size > 0)
    {
     dest[dest_size - 1] = '\0';
    }
    else
    {
     dest[0] = '\0'; /* Return empty string if the destination is zero length */
    }

    return dest;
}
+3  A: 

You don't need to check that source is greater than destination just always make the last char in the dest a '\0'.

Martlark
+2  A: 

Check dest_size before accessing the array or you'll get into trouble:

if (dest_size > 0) {
    dest[dest_size - 1] = '\0';
}


Actually, now that I think of it, it's probably better to just die:

if (dest_size == 0) {
    fputs(stderr, "strncpy(x,y,0)");
    exit(1);
}

Otherwise, you'll have the same problem as with the original strncpy(), that dest may not be terminated if dest_size is 0.

Inshallah
I have just edited my question with updated source code. I have put an if else. If the dest is greater than 0. Always terminate the last element. Else insert a null in the first [0] element and return an empty destination string. What does that sound like?
robUK
You can't store a '\0' in *dest* if *dest* has zero size. You're not allowed to, since you may only access zero chars, but storing a '\0' means that you are accessing one char. I don't think it's a problem to die, it's like division through zero errors. It simply doesn't make any sense to call your function with *dest_size == 0*. It's a good idea to *fail early*, then you know at least where you messed up (in the call to strncpy()). Imagine the division operation failing silently, and giving you some random garbage as a result; very hard to debug.
Inshallah
+1  A: 

If you don't have any constraints on the allocation of the buffer, strndup could be more appropriate.

It will allocate and copy at most len chars, and always terminate with NULL.

Mehmet Ergut
+1  A: 

if dest_size is the number of characters to be copied and source_size is the number of characters in source string.
you should try this:


 size_t numchars = dest_size > source_size ? source_size : dest_size;
 strncpy(dest,source,numchars) ;
 dest[numchars] = 0 ;
Neeraj
*strncpy()* will **not** 0-terminate *dest* by itself. The 0-character will always come from *source*. That means your example will not work as the OP intends.
Inshallah
@above edited.. as pointed out
Neeraj
+2  A: 

You should investigate the semi-standard BSD functions strlcpy() and strlcat().

You should consider whether the ISO TR24731 functions such as strncpy_s() are appropriate and available where you need them.

Jonathan Leffler