Strcpy ... want to replace with strcpy_mine, which will strncpy and null terminate

the key is in the header, but basically I inherited some code with 800+ instances of strcpy. I want to write a new function, and then replace strcpy with strcpy_mine.

So I'm trying to figure out which parameter the strcpy_mine list has.

I tried:

void strcpy_mine( char* pTarget, const char* const pCopyMe ) { const unsigned int lenAlwaysFour = sizeof(pCopyMe ); //:( strncpy( pTarget, pCopyMe, lenAlwaysFour ); //add extra terminator in case of overrun pTarget[lenAlwaysFour] = 0; } 

but sizeof is always 4 pCopyMe is a pointer

what i don't want to do is replace

 strcpy (buf, pCopyMe); 

from

 strncpy (buf, pCopyMe, sizeof(pCopyMe)); buf[sizeof(pCopyMe)] = 0; 

any ideas? (strcpy_l is unavailable)

amuses

+6
c ++ c strcpy
source share
7 answers

Depending on how the call sites look, often most cases can be handled with a simple template:

 #include <string.h> template <int bufferSize> void strcpy_mine( char (&pTarget)[bufferSize], const char* const pCopyMe ) { strncpy( pTarget, pCopyMe, bufferSize-1 ); //add extra terminator in case of overrun pTarget[bufferSize-1] = 0; } int main() { char buf[128]; strcpy_mine(buf,"Testing"); return 0; } 

If you are using Microsoft Visual Studio 2005 or later, see Secure Template Forwarding for Microsoft Implementation.

+4
source share

sizeof () returns the type size - in this case const char* const , which will be 4 on 32-bit machines.

I think you think you want strlen() . But this is not the right way to use strncpy functions. Strncpy requires an output buffer size.

To fix this, you need to examine the code on each call site and determine the size of the output buffer and pass this as the strcpy_mine argument. If the calling site for strcpy (or strcpy_mine) does not know the size of the output buffer, you need to search back in the code for the location that allocates the buffer and pass the size to the end of the strcpy site.

Basically, you cannot write a replacement for strcpy that takes the same arguments and hopes to avoid the problems that caused strncpy in the first place (and better substitutions behind it). You can create a function that takes the same arguments as strncpy, but guarantees that the result is completed with a zero mark - look at the implementation of the OpenBSD strlcpy () function. But the first step should be to change the calling sites to transfer knowledge about the size of the output buffer.

+11
source share

Perhaps a little peripheral, but since no one mentioned it, and it appeared in the header: you cannot (legally) write a global function called strcpy_mine() .

the "namespace" of functions whose names begin with str is reserved for the standard library. See, for example, the accepted answer to this question .

+2
source share

You can use the same parameter list as strncpy for your strcpy_mine, but write it so that it is always zero, completes the result. It should not be very difficult to do.

One problem is that some of your existing code that strcpy () calls may also not know the size of the buffer.

+1
source share

You can also use macros to avoid several changes. Or automate editing with some script.

0
source share

You definitely need to pass the size of the destination buffer as a parameter, as other people have said.

This is kind of off topic, but I just want to note that after using strncpy() you need to set the last character of the buffer to zero, which has an index of 1 less than the length (not the length of the buffer):

 strncpy (buf, pCopyMe, buflen); buf[buflen - 1] = '\0'; 

Or, alternatively, you can use strncat() on an empty string, passing it a length that is less than 1, and this ensures that zero terminates your string:

 buf[0] = '\0'; strncat (buf, pCopyMe, buflen - 1); 
0
source share

Douglas Leder is right. There is a limit to the usefulness of replacing strcpy if you do not want to do work with coarse transfers in a good, reasonable buffer length in each instance. This is a lot of work!

The good news is worth it! A few years ago, I came up with several C ++ projects that were late, erroneous, and unreliable. By declaring strcpy and strlen forbidden, and taking 2-3 days from the project to replace them with custom strncpy / strnlen, we could suddenly work in all of these projects for several days, not hours. We also saw that a lot of truncated lines appeared on screens and log files. This gave us the hints needed to track truncation problems, previously encountered problems.

If you do not want to do this, you can get much less benefit by simply checking both pointer options for NULL and limiting the maximum size of the string copy and registering all the time the border is reached. Do not run strlen on any of the parameters, as strlen will happily crash on you if the line is not terminated by zero correctly.

New projects currently use good string objects, but there is a lot of legacy code that doesn't.

0
source share

All Articles