2014-09-04 3 views
1

sprintf가 일부 버퍼 오버플로를 유발하므로 모든 sprintf를 프로젝트의 snprintf로 변경해야합니다. 하지만 다음과 같은 몇 가지 문제를 가지고 :snprintf dest 버퍼 크기를 결정하는 방법

void foo(char *a, uchar *string) 
{ 
    sprintf(string, 'format', src_str); 
} 

대상 문자열이 우리가 어떻게 현재 snprintf을 변경 한 후 버퍼 크기 또는 문자열의 최대 길이를 결정하는 함수의 매개 변수가있을 때 질문은 ..

+4

버퍼 크기를 함수에 전달해야합니다. – Kevin

+1

'int len ​​= snprintf (NULL, 0, ....)'을 호출하면,'char buf [len]; snprintf (buf, len, ....);'적어도'buf'는 완전한 문자열을 가지고 있습니다. 얼마나 많은 것이'문자열 '에 들어 맞는지에 관해서 - 당신은 당신 자신에 달려 있습니다. – chux

+0

함수에 새로운 크기 매개 변수를 추가하는 것 외에도 포인터와 버퍼 크기를 보유하는'struct ustring'을 만드는 것입니다. 만약 당신이 좋아하면 struct에 문자열 크기를 추가 할 수 있습니다.이 함수는'strcpy' 대신에'memcpy'와 같은 더 빠른 함수를 사용할 수 있도록합니다. –

답변

2

대상 버퍼를 직접 할당 할 수있는 옵션이있는 경우 strlen()으로 소스 문자열의 길이를 검사 할 수 있습니다 (null-terminatd이고 충분히 큰 버퍼와 종료 null 문자를 할당 할 수 있음). 사용할 수있는 경우 asprintf을 직접 사용할 수도 있습니다. 이 옵션을 사용하지 않으면 대상 버퍼의 크기를 인수로 전달해야합니다. 포인터가있는 경우 함수 내부에서 그 크기를 안정적으로 결정할 수 없기 때문입니다 (대상 버퍼가 항상 유일하게 식별 가능한 방법).

+0

예, 문자열의 경우 크기를 확인하기 위해 strlen()을 사용할 수 있지만 배열을 가리키면 strlen()에 문제가 발생합니다. – unnugi

+0

여기에 어떤 종류의 배열이 포함되어 있는지 명확히 설명해 주시겠습니까? strlen은 보통 모든 형태의 널 종료 문자열을 처리합니다. – midor

+0

안녕하세요, Midor, foo가 호출 될 때 * 문자열이 문자열 배열을 가리킬 수 있습니까? – unnugi

1

_scprintf(...)을 호출하면 실제로 버퍼를 사용하지 않고 문자열의 크기를 알 수 있습니다.

그런 다음 해당 크기의 버퍼를 할당하고 snprintf를 호출하십시오.

+1

이 솔루션은 XPG7 또는 C11 표준을 준수하지 않습니다. snprintf() 함수를 사용하면됩니다. –

+0

foo가 호출 될 때 문자열이 배열을 가리키면 -scprintf()가 작동하지 않는 것처럼 보입니다.'string = & Array [len]; foo ((char *) a, string); ' – unnugi

0

올바른 인수를 사용하여 snprintf으로 전화를 걸 수없는 경우 snprintf에 대해 sprintf을 변경하면 도움이되지 않습니다. foo 함수는 snprintf처럼 sprintf 이상의 추가 매개 변수가 필요한 추가 매개 변수를 가져와야합니다. 배열은 함수에 대한 인수로 사용될 때 포인터로 감쇠되므로 모든 크기 정보가 손실됩니다.

프로그램 전체에서 수 백 번 foo을 호출하는 경우 엉망이 될 수 있지만 버퍼 오버런을 방지하려면 배열에서 작동하는 모든 함수가 완전히 인식되는지 확인해야합니다 그들의 크기. 당신이 GCC 또는 연타를 사용하는 경우

, 당신은 1에 프로토 타입을 변경하여 foo 기능에 대한 사용 중단 경고를 넣을 수 있습니다 :

void __attribute__((deprecated)) foo(char *a, uchar *string); 

그런 다음, 예를 새로운 기능을 만들 수 있습니다 foo_n에는 크기에 대한 추가 매개 변수가 있습니다. 코드를 컴파일 할 때, GCC는 함수 foo을 사용할 때마다 경고를 내고, foo_n으로 바꾼다.

1.이 __attribute__((deprecated)) 부분은 후 매개 변수 목록을 을가는 것이 가능하지만 그 소리는 위에 표시된대로 그것을 받아 들일 것으로 보인다.

관련 문제