본문 바로가기

C++

버퍼에 안전한 문자열 함수

[1. 개요]

기존 strcpy 나 strcat 등은 버퍼 길이를 체크하지 않아서, 버퍼 오버플로우에 취약 함.

그래서 버퍼 길이를 인자로 받는 버퍼에 조금 안전한 문자열 함수가 있어,

가급적 이러한 함수를 사용하는 것이 권장 됨

 

함수 목록

  • strncpy
  • strncat
  • snprintf
  • strncmp

마지막 NULL 문자로 채워지는 것을 보장하지 않음.

const char* cstr = "Hello" 를

char buf[5] 에 복사 시, 

buf[4] = 0; 이 아님

 

가급적, (총 버퍼 길이 - 1) 을 넘기는 편이 좋아 보임

 

또한, strncat 에서는 (concat 위치 부터 남은 버퍼 길이 - 1) 을 넘기는 편이 낫다.


[2. 예제]

#include <cstring>
#include <iostream>

int main()
{
    const char* str_5len = "Hello";

    char buf[5];
    // NULL 문자를 채워주지 않음.
    strncpy(buf, str_5len, sizeof(buf));
    buf[sizeof(buf)-1] = 0; // 주석 전후로 문자열 출력 확인 하면...
    std::cout << buf << std::endl;
    
    snprintf(buf, sizeof(buf), str_5len);
    std::cout << buf << std::endl;

    char buf2[10];
    char over = 111;
    memset(buf2, 0, sizeof(buf2));

    strncat(buf2, str_5len, sizeof(buf2));
    // concat 위치부터 남은 버퍼 길이 명시, 
    strncat(buf2, str_5len, sizeof(buf2)-strlen(buf2));
    buf2[sizeof(buf2)-1] = 0;

    std::cout << buf2 << std::endl;
    std::cout << int(over) << std::endl;

    // 접두사만 비교할 때
    std::cout << strncmp("Hell o", "Hello", 4) << std::endl;
    // 더 큰 값을 넘겨도 상관 없음. (널문자 만나면 종료)
    std::cout << strncmp("Hello", "Hello", 60) << std::endl;
    // 만약 NULL 로 끝나는 문자열이 아닌 경우.
    char buf3[] = {'H', 'I'};
    char buf4[] = {'B', 'Y', 'E'};
    std::cout << strncmp(buf3, buf4, 2) << std::endl;

    return 0;
}

 

'C++' 카테고리의 다른 글

함수의 중복 정의 방지  (0) 2025.09.09
스레드에 안전한 localtime()  (0) 2025.09.09
segmentation fault 사례 6  (0) 2025.08.22
fsanitize 컴파일 옵션  (2) 2025.07.02
buffer overflow 사례1  (0) 2025.06.26