Why is strcpy unsafe in C? [duplicate]
Asked Answered
C

3

10

I am a beginner, and I am learning how to copy a string in C now.

Here is a problem I just met:

Every time I try to use "strcpy" command to copy from string 1 to string 2, Visual Studio 2013 will give me an error/warning message saying that "strcpy" is unsafe and suggest me to use strcpy_s instead.

Can you please explain why is strcpy unsafe to use? And what are the safer alternatives to strcpy?

Here is my code:

#include<stdio.h>
#include<string.h>
main()
{
    char str1[] = "Copy a string.";
    char str2[15];
    char str3[15];
    int i;

    /* with strcpy() */
    strcpy(str2, str1);
    /* Without strcpy() */
    for (i = 0; str1[i]; i++)
        str3[i] = str1[i];
    str3[i] = '\0';
    /* Display str2 and str3 */
    printf("The content of str2: %s\n", str2);
    printf("The content of str3: %s\n", str3);
    return 0;
}

P.S. I am using Visual Studio 2013 64-bit ultimate on Windows 7 64-bit ultimate. Thank you for your time!

Carnelian answered 26/4, 2014 at 23:31 Comment(5)
Actually, things get interesting when the MSVC compiler tells you that strncpy is also unsafe. They want you to use strncpy_s, which adds a second parameter indicating size and modifies the standard behavior of strncpy, such that truncated strings append a null-terminator. Needless to say, all of these _s functions are non-standard and I generally just define a certain pre-processor definition to make that warning go away.Letter
strcpy() is not unsafe, Microsoft is unsafe. Where is the support for the c99 standard? BTW: "unsafe" is PHB-speak, better ignore it. BTW2: the prototype for main is: int main(void) or int main(int argc, char **argv)Unhair
Yeah, Microsoft wants to embrace, extend, extinguish C as well. strcpy() is a perfectly safe function (unlike, say, gets()) in the right hands. Unfortunately, a lot of programmers don't code well, and then demand a "safer" language. Wimps.Innominate
...because C strings are inherently unsafe:(Impoverish
Suggest: char str2[sizeofstr1]; and avoid magic numbers like 15. Let the compiler do the work to compute the needed size.Tedford
W
12

strcpy has no way of knowing how large the destination buffer is (i.e. there is no length parameter) so sloppy programming using it can lead to overrunning the buffer and corrupting other memory. Such an overrun can lead to crashes, odd behaviour and may be exploitable by malware authors.

BTW, look at strncpy that takes a length parameter. One problem to be aware of is that strncpy will not terminate the string if the buffer is too small so it is dangerous in its own way.

In answer to your comment/question - it will depend on context. If you know the buffer is large enough (for example, you allocated it in the previous line at the correct size), use strcpy. If there is any possibility of an overflow then use strncpy and make sure you set the last position in the buffer to null. Note that "any possibility" should be interpreted very generously - unless the previous five or six lines are enough to show safety then use strncpy.

Also see Andon's comment above about strncpy_s. Finally, if you do use strcpy, you might want to add a #pragma to suppress the warning at that location.

Wileen answered 26/4, 2014 at 23:33 Comment(2)
What do you suggest to make the program more robust? Thanks for the answer!Carnelian
Please don't use strncpy as a "safer" alternative to strcpy. See this answer.Ceto
S
3

Here's your original code:

int main() {
    char str1[] = "Copy a string.";
    char str2[15];

    strcpy(str2, str1);
}

Now, three day later, you go to edit this code. You've realized that you actually need to write the message "This code is copying a string." instead.

int main() {
    char str1[] = "This code is copying a string.";
    char str2[15];

    strcpy(str2, str1);
}

However, you've now accidentally introduced a buffer overflow.

strcpy_s requires the extra argument of the length of str2. This way, while you may not get the whole string into your new buffer, you won't cause undefined behavior.

Schnozzle answered 27/4, 2014 at 0:4 Comment(0)
B
1

Unlike strncpy and strcpy_s, strcpy doesn't do any length checking of the destination buffer which may cause stack overflow allowing an attacker to execute malicious code if exploited or just crach your application

Barite answered 27/4, 2014 at 0:3 Comment(1)
Note: strncpy does not insure string termination either.Tedford

© 2022 - 2024 — McMap. All rights reserved.