programing tip

왜 strcpy 대신 strncpy를 사용해야합니까?

itbloger 2020. 10. 13. 07:31
반응형

왜 strcpy 대신 strncpy를 사용해야합니까?


편집 : 예제에 대한 소스를 추가했습니다.

내가 건너 온 이 예 :

char source[MAX] = "123456789";
char source1[MAX] = "123456789";
char destination[MAX] = "abcdefg";
char destination1[MAX] = "abcdefg";
char *return_string;
int index = 5;

/* This is how strcpy works */
printf("destination is originally = '%s'\n", destination);
return_string = strcpy(destination, source);
printf("after strcpy, dest becomes '%s'\n\n", destination);

/* This is how strncpy works */
printf( "destination1 is originally = '%s'\n", destination1 );
return_string = strncpy( destination1, source1, index );
printf( "After strncpy, destination1 becomes '%s'\n", destination1 );

이 출력은 다음과 같습니다.

대상은 원래 = 'abcdefg'입니다.
strcpy 이후 목적지는 '123456789'가됩니다.

destination1은 원래 = 'abcdefg'입니다.
strncpy 이후 destination1은 '12345fg'가됩니다.

왜 누군가가이 효과를 원하는지 궁금합니다. 혼란 스러울 것 같습니다. 이 프로그램은 기본적으로 Tom Bro763을 사용하여 누군가의 이름 (예 : Tom Brokaw)을 복사 할 수 있다고 생각합니다.

strncpy() over 사용의 장점은 무엇입니까strcpy() ?


strncpy길이를 입력하도록 요구하여 버퍼 오버 플로우를 방지합니다. strcpy후행에 의존하며 \0항상 발생하지는 않습니다.

둘째, 7 자 문자열에 5 자만 복사하도록 선택한 이유는 저를 넘어서지 만 예상되는 동작을 생성합니다. 세 번째 인수가 있는 첫 번째 n문자 만 복사합니다 n.

n함수는 모두 버퍼 오버플로에 대한 방어 코딩으로 사용됩니다. 와 같은 이전 기능 대신 사용하십시오 strcpy.


strncpy()함수는 매우 특별한 문제를 염두에두고 설계되었습니다. 원래 UNIX 디렉토리 항목의 방식으로 저장된 문자열을 조작하는 것입니다. 이것들은 고정 된 크기의 배열을 사용했고, nul 종료자는 파일 이름이 배열보다 짧은 경우에만 사용되었습니다.

이것이 두 가지 이상한 이유 뒤에 있습니다 strncpy().

  • 완전히 채워지면 목적지에 널 (nul) 종료자를 넣지 않습니다.
  • 필요한 경우 nuls로 항상 목적지를 완전히 채 웁니다.

"안전한 strcpy()"경우 다음 strncat()과 같이 사용하는 것이 좋습니다 .

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

그것은 항상 결과를 무효화하고 필요 이상으로 복사하지 않을 것입니다.


의 의도를 알고 있지만 strncpy실제로 좋은 기능은 아닙니다. 둘 다 피하십시오. Raymond Chen이 설명합니다 .

개인적으로 내 결론은 strncpynull로 끝나는 문자열을 다루는 경우 단순히 피하고 모든 친구들 을 피하는 것 입니다. 이름에 "str"이 있음에도 불구하고 이러한 함수는 null로 끝나는 문자열을 생성하지 않습니다. 널로 끝나는 문자열을 원시 문자 버퍼로 변환합니다. 두 번째 버퍼가 잘못되어 널로 끝나는 문자열이 예상되는 곳에서 사용하십시오. 소스가 너무 길면 적절한 null 종료를 얻지 못할뿐만 아니라 소스가 짧으면 불필요한 null 패딩이 발생합니다.

strncpy가 안전하지 않은 이유 도 참조하십시오 .


strncpy는 strcpy보다 안전하지 않으며 한 유형의 버그를 다른 유형과 교환 할뿐입니다. C에서 C 문자열을 처리 할 때 버퍼의 크기를 알아야합니다. strncpy는 다른 사람들이 언급 한 디렉토리 항목에 대해 정당화되었지만 그렇지 않으면 절대 사용해서는 안됩니다.

  • 문자열과 버퍼의 길이를 알고 있다면 왜 strncpy를 사용합니까? 기껏해야 컴퓨팅 성능 낭비입니다 (쓸모없는 0 추가).
  • 길이를 모르면 버퍼 오버플로보다 낫지 않은 문자열을 조용히 잘라낼 위험이 있습니다.

당신이 찾고있는 것은 기능입니다 strlcpy() 있는 것은 항상 0으로 문자열을 종료하고 버퍼를 초기화하는 입니다. 또한 오버플로를 감지 할 수 있습니다. 유일한 문제는 (정말) 이식성이없고 일부 시스템 (BSD, Solaris)에만 존재한다는 것입니다. 이 기능의 문제점은 http://en.wikipedia.org/wiki/Strlcpy 의 토론에서 볼 수 있듯이 또 다른 웜 캔을 열 수 있다는 것입니다 .

내 개인적인 의견은 strncpy()보다 훨씬 더 유용하다는 것 strcpy()입니다. 더 나은 성능을 가지고 있으며 snprintf(). 이 기능이없는 플랫폼의 경우 구현하기가 비교적 쉽습니다. (응용 프로그램의 개발 단계에서이 두 기능을 대체합니다 (snprintf()strlcpy())를 버퍼 오버플로 또는 잘림시 프로그램을 잔인하게 중단하는 트래핑 버전으로 . 이렇게하면 최악의 공격자를 신속하게 잡을 수 있습니다. 특히 다른 사람의 코드베이스에서 작업하는 경우 .

편집 : strlcpy()쉽게 구현할 수 있습니다.

size_t strlcpy(char *dst, const char *src, size_t dstsize)
{
  size_t len = strlen(src);
  if(dstsize) {
    size_t bl = (len < dstsize-1 ? len : dstsize-1);
    ((char*)memcpy(dst, src, bl))[bl] = 0;
  }
  return len;
}

strncpy()함수는 더 안전한 함수입니다. 대상 버퍼가 허용 할 수있는 최대 길이를 전달해야합니다. 그렇지 않으면 소스 문자열이 올바르게 0으로 종료되지 않을 수 있습니다.strcpy() function could write more characters to destination, corrupting anything which is in the memory after the destination buffer. This is the buffer-overrun problem used in many exploits

또한 read()버퍼에 종료 0을 넣지 않고 읽은 바이트 수를 반환하는 POSIX API 함수의 경우 수동으로 0을 넣거나 strncpy().

In your example code, index is actually not an index, but a count - it tells how many characters at most to copy from source to destination. If there is no null byte among the first n bytes of source, the string placed in destination will not be null terminated


strncpy fills the destination up with '\0' for the size of source, eventhough the size of the destination is smaller....

manpage:

If the length of src is less than n, strncpy() pads the remainder of dest with null bytes.

and not only the remainder...also after this until n characters is reached. And thus you get an overflow... (see the man page implementation)


This may be used in many other scenarios, where you need to copy only a portion of your original string to the destination. Using strncpy() you can copy a limited portion of the original string as opposed by strcpy(). I see the code you have put up comes from publib.boulder.ibm.com.


That depends on our requirement. For windows users

We use strncpy whenever we don't want to copy entire string or we want to copy only n number of characters. But strcpy copies the entire string including terminating null character.

These links will help you more to know about strcpy and strncpy and where we can use.

about strcpy

about strncpy


the strncpy is a safer version of strcpy as a matter of fact you should never use strcpy because its potential buffer overflow vulnerability which makes you system vulnerable to all sort of attacks

참고URL : https://stackoverflow.com/questions/1258550/why-should-you-use-strncpy-instead-of-strcpy

반응형