본문 바로가기

Job Notes/Programming

[펌] 안전한 string 함수 (strncpy_s, sscanf_s, sprintf_s) 사용

1. strcpy은 strncpy, strncpy_s를 사용한다.
참고 : http://msdn.microsoft.com/ko-kr/library/5dae5d43.aspx
Example>
char src[] = "Test";
char dest[10];

strncpy_s(dest, _countof(dest), src, strlen(src));

2. sscanf 대신 sscanf_s를 사용한다.
참고 : http://msdn.microsoft.com/ko-kr/library/t6z7bya3.aspx
Example>
char pRaw_data[] = "A 10 20 AB 30 CD 40 EF 50 GH 60 IJ 70 KL 80 MN 90 OP 11.2";
char count;
int snr;
int score0, score1, score2, score3, score4, score5, score6, score7;
char result0[5], result1[5], result2[5], result3[5], result4[5], result5[5], result6[5];
char* result7;
result7 = new char[5];
float fl;

sscanf_s(pRaw_data, "%c %d %d %s %d %s %d %s %d %s %d %s %d %s %d %s %d %s %f", 
    &count, sizeof(char), &snr, &score0, result0, _countof(result0), &score1, result1, _countof(result1), 
    &score2, result2, _countof(result2), &score3, result3, _countof(result3), 
    &score4, result4, _countof(result4), &score5, result5, _countof(result5), 
    &score6, result6, _countof(result6), &score7, result7, _countof(result7), 
    &fl);

delete [] result7;
예제에서 string과 Integer와 Float와 Char이 섞인 경우에 값을 가져오는 방법이다.
sscanf_s에서 string외에는 사이즈를 표시하지 않아도 동작한다.(각 타입의 크기가 정해져 있으니 당연히.)
string의 경우에는 string의 바로 다음에 크기를 알려줘야 한다. 

3. sprintf 대신 _snprintf를 사용한다.
참고 : http://msdn.microsoft.com/ko-kr/library/2ts7cx93(VS.80).aspx
Example>
char buf[256];
char name[] = "-_-v";
_snprintf(buf, _countof(buf), "%s", name);
Destination의 크기를 알려주어 Buffer Overflow를 방지. 
_snprintf 대신에 _snprintf_s도 있군요. _snprintf_s 써 보고 다시 포스팅~!
strncpy_s와 비슷한 이유일꺼라고 생각하고 있습니다.


※ _countof(Arrray) : 
참고 : http://msdn.microsoft.com/ko-kr/library/ms175773.aspx
내용을 보면 알겠지만 sizeof()와 _countof의 값은 틀릴 수가 있다. 
1byte가 아니라면 _countof(Array) * sizeof(Array[0]) 로 하면 될 듯.

String 관련 함수들은 결국 Destination의 크기와 Source의 크기를 Parameter를 이용하여 넘겨서
Buffer 관련한 문제를 최소화 하려고 하나 봅니다.
이미 알고 있는 String 관련 함수들도 일단 한번씩 찾아보고 써야 할 것 같군요.