C++ 프로그래머의 일상: 모종의 디버깅
Berryz WebShare의 RAR 다운로드 플러그인에서 생기던 버그를 수정하는데 성공. + 약간의 버그를 추가로 잡았음.
Format 문자열이 당신을 속일지라도 노여워 말라
vsnprinf_s
를 이용해서 로그 문자열을 출력하는 코드가 있다. 이걸 래핑한 함수가
WriteLog(const char* fmt, ...);
처럼 생겼는데, 포맷 문자열인 fmt 값으로 HTTP 요청으로 들어온 URI를 넣는 부분이 있더라. (WriteLog(URI)
모양)
- URI에 ASCII 영역을 벗어나는 문자가 있다면 이 문자는 “%e3%80%90…” 하는 모양이 된다.
vsprinf
류의 함수들은%s
처럼%
와 일부 영문자가 연속으로 오는 것을 어떤 “형식화된 출력” 문자로 간주한다.
이 두 가지가 합쳐지면? VS 2005가 부적절한 문자열 형식화라고 프로그램을 죽인다[…].
Buffer 길이를 잘 확인하자
문제가 좀 어이없을만큼 간단했는데(…), HTTP 요청에 대한 응답을 보낼 때 HTTP header의 각 행1 을 전송하는데, 이 때 고정길이 버퍼를 사용한게 문제. HTTP요청에 대한 응답으로 Content-Disposition이나 Location 같은 값은 굉장히 길어질 수 있는데(URI가 들어가서), 이게 다국어 문자가 많이 포함된 꽤 긴 문자열이면 4000바이트는 우습지도 않은 크기가 되는 경우가 생겼다. 이런 경우에 헤더가 짤려서 전송되는 문제 때문에 특정 웹부라우져에서 다운로드된 파일의 이름이 이상하거나 / 다운로드 자체가 안되거나 하는 문제가 있었다. 이 부분을 수정.2
STL 디버깅 + IE의 알 수 없는 동작
VS 2003에서 VS 2005로 넘어오면서 STL 디버깅 기능3 덕분에 몇 가지 버그를 더 잡았는데, 아마도 IE의 비표준 행위 때문에 생기는 듯하다. 대충 다음과 같은 작업을 하면 생기는데,
- IE에서 HTTP 요청을 보낸다. 일부가 POST method로 전송되야 한다.
- IE에서 F5로 refresh
- 다시 HTTP요청을 보낸다. 이때는 GET으로…
- POST로 0bytes가 전송된다. (정확히는 2bytes의 \r\n 가 가지만 이건 구분자)
이런 현상이 생기는듯하다. 그래서 some_vector<char> v
에 대해서 v[2]
의 주소를 얻는 코드에서 STL 디버깅 코드가 assert-fail을 낸다.
-
HTTP 요청/응답은 모두 \r\n 을 기준으로 구분되는 행들로 이루어져 있다. 예를 들어
Content-Type: application/x-rar-compressed\r\n Content-Disposition: attachment; filename="SomeFile.rar"\r\n
하는 식이다. (근데 이건 IE의 응답에 대한 요청이라 content-disposition이 좀 특이하다. FF/Opera쪽으로 보내는 응답형태가 표준인듯?) ↩︎
-
물론 길이를 체크하는 문자열 함수를 사용했기 때문에 overflow 오류같은 것은 없다 :p ↩︎
-
index 체크나 iterator가 살아있는지 여부 등등을 검사해준다. 무척 맘에 드는 기능이다. VS 2005이상을 써야하는 이유 중 하나라고 생각함 ↩︎