혹시 gets(), strcpy(), sscanf()를 사용하지 말라고 하는 얘기를 들어 보신 적이 있나요?

사용하지 말라는 얘기는 아니더라도 사용하지 않는 것이 좋다는 권유를 받은 분이 있을지 모르겠네요.

3개 함수 모두 편리한 함수인데 왜 사용하지 말라거나 사용하지 않는 것이 좋다고 할까요?


이유는 매우 간단합니다. 위 3개의 함수는 길이가 정해지지 않는 문자열을 받아 오는 함수임에도

몇 바이트까지 받으라는 길이를 지정하는 인수가 없습니다.


예를 들어 gets()를 보겠습니다. 함수는 아래와 같이 선언되어 있습니다.


      char *gets(char *s);


gets()를 이용하면 표준 입력 장치로 입력된 값을 받을 수 있는데,

그 문자열을 받기 위해 버퍼를 사용해야 합니다.

그래서 1024 바이트의 char buff[1024]; 변수를 정의했습니다.

그리고 아래와 같이 gets()를 호출했습니다.


      gets( buff);


자연스러운 코드이지만, 문제는 표준 입력 장치로 입력하는 사람이 엔터키 포함하여

버퍼 크기 이상으로 키 입력하면 어떻게 될까요?


      *** buffer overflow detected ***: ./o.out terminated


버퍼 오버플로우 에러가 발생하면서 gets() 함수 하나로 프로그램이 종료되어 버립니다.


buffer_overflow.png


이 문제를 해결하기 위해 버퍼 크기를 키우면 되겠지만, 안전한 최대 크기가 얼마일까요?

strcpy(), sscanf()도 같은 문제를 가지고 있습니다.

그러므로 gets() 대신에 read()를 strcpy() 대신에 memcpy()를, sscanf() 대신에 변환함수를 사용하거나

버퍼 크기를 넘기지 않도록 조심해야겠습니다.