vsnprintf_s 예제

vprintf_s(), vfprintf_s(), vsnprintf_s() 및 vsprintf_s() 함수는 C11 표준인 부속서 K에 지정된 C11 경계 검사 인터페이스의 일부입니다. C11 표준에 정의된 명시적 런타임 제약 조건의 형태로 추가 안전 검사를 제외하고 함수는 각각의 비경계 검사 함수와 유사합니다. runtime_constraint_handler(3C) 및 INCITS/ISO/IEC 9899:2011을 참조하십시오. vsnprintf_s는 vsprintf_s와 달리 버퍼로 가리키는 배열 에 맞게 결과를 잘립니다. calloc() 예제에는 calloc()에서 처리되지 않은 NULL 포인터뿐만 아니라 많은 문제가 있습니다. 이 비준수 코드 예제에서 함수 utf8_to_wcs()는 UTF-8 문자 시퀀스를 넓은 문자로 변환하려고 시도합니다. 먼저 setlocale()를 호출하여 전역 로캘을 구현 정의 en_US로 설정합니다. UTF-8하지만 실패를 확인하지 않습니다. setlocale() 함수는 로캘이 설치되지 않은 경우와 같은 null 포인터를 반환하여 실패합니다. 리소스 부족과 같은 다른 이유로 인해 함수가 실패할 수도 있습니다.

utf8이 가리키는 문자의 시퀀스에 따라 mbstowcs() 후속 호출이 실패하거나 제공된 버퍼 wcs에 예기치 않은 와이드 문자 시퀀스를 저장하는 함수가 발생할 수 있습니다. 이 비준수 코드 예제에서는 fseek() 함수가 파일에서 바이트 시퀀스를 읽기 전에 파일에서 참조하는 파일의 위치 오프셋으로 파일 위치를 설정하는 데 사용됩니다. 그러나 검색 작업 중에 I/O 오류가 발생하면 후속 읽기가 버퍼에 잘못된 내용으로 채워집니다. 이 비준수 코드 예제에서는 realloc()를 호출하여 p에서 참조하는 메모리의 크기를 조정합니다. 그러나 realloc()가 실패하면 null 포인터가 반환되고 원래 메모리 블록과 p 사이의 연결이 손실되어 메모리 누수됩니다. 이 비준수 코드 예제에서는 snprintf()가 성공하는 것으로 가정합니다. 그러나 호출이 실패하는 경우(예: GNU libc bug 441945에 설명된 대로 메모리 부족으로 인해) character 버퍼가 초기화되지 않고 null-terminated가 필요하지 않기 때문에 log_message()에 대한 후속 호출에는 정의되지 않은 동작이 있습니다. 소수점 정수 변환(i, d, u)의 경우 출력은 로캘의 대체 출력 숫자(있는 경우)를 사용합니다. 예를 들어 glibc 2.2.3 이후 페르시아어(“fa_IR”) 로캘에서 아랍어-인도어 자릿수를 지정합니다. 이 코드 예제는 MEM04-C를 준수합니다. 길이 가영을 0으로 할당하지 마십시오.

이 비준수 코드 예제에서 temp_num, tmp2 및 num_of_레코드는 오염된 소스에서 파생됩니다. 따라서 공격자는 num_of_records에 큰 값을 제공하여 calloc()가 쉽게 실패할 수 있습니다. vprintf_s(), vfprintf_s(), vsprintf_s() 및 vsnprintf_s() 함수는 런타임 제약 조건 처리기로 인해 다중 스레드 응용 프로그램에서 안전하게 사용할 수 없습니다. 자세한 내용은 runtime_constraint_handler(3C) man 페이지를 참조하십시오. I/O 함수 및 메모리 할당 함수를 포함한 대부분의 표준 라이브러리 함수는 오류를 나타내는 올바른 반환 형식의 유효한 값 또는 값을 반환합니다(예: -1 또는 null 포인터). 이러한 함수에 대한 모든 호출이 성공하고 오류 표시에 대한 반환 값을 확인하지 못했다고 가정하면 오류가 발생할 때 예기치 않거나 정의되지 않은 동작으로 이어질 수 있는 위험한 방법입니다. 프로그램은 오류 처리 정책에 따라 모든 오류를 감지하고 적절하게 처리해야 합니다. 매크로 va_alist()는 아래 예제에서 error()라고 하는 함수에서와 같이 함수 정의의 매개 변수 목록으로 사용됩니다.

ap형식 va_list와 이름이 가장 적합한 매개 변수인 매크로 va_start(ap, name)는 이름이 지정되지 않은 인수를 트래버스하고 액세스하려는 시도가 이루어지기 전에 호출해야 합니다. 원하는 모든 인수에 액세스한 경우 va_end(ap) 매크로를 호출해야 합니다.

Share on FacebookPin on PinterestTweet about this on TwitterShare on TumblrShare on Google+Digg this