2010-06-21 22 views
11

Traté de buscar en el sitio para esta pregunta, pero no encontramos que esto exactamente, aunque este tema se está discutiendo mucho ...¿Cuándo se inicializan las variables de const estático globales?

que tienen esta declaración en un archivo CPP, no dentro de cualquier función:

static const char* gText = "xxxxxxxxxxx"; 

pesar de que tiene un tamaño fijo, recibo una advertencia de una herramienta de análisis estático (Klocwork) cuando estoy tratando de copiarlo en otra variable char * - por la posible fuera de los límites violación:

char xText[32]; 
SecureZeroMemory(xText, 32); 
memcpy(xText, gText, strlen(gText)); 

Es un falso postulado ¿o se está inicializando la variable global más tarde?

Gracias!

+0

¿Cuál es la línea exacta a la que se está refiriendo KLOCWORKS? – ckv

+0

memcpy() uno. – IUnknownPointer

+3

Por cierto, el puntero en sí no es const, por lo tanto, podría cambiarse para apuntar a otra cadena más larga – sellibitze

Respuesta

1

Es un falso positivo. strlen probablemente se haya abstraído al devolver un número positivo desconocido, por lo que al analizar el patrón memcpy(dest,src,strlen(src)); el analizador no se da cuenta de que la parte de lectura de la copia es segura tan pronto como src es una cadena bien formada.

Si estaba usando strcpy, el analizador probablemente concluiría que está bien en este caso. ¿Tienes una razón para no hacerlo? La función strcpy se considera "insegura" pero su memcpy(..,src,strlen(src)) es bastante insegura también.

EDIT: También, sellibitze plantea un punto muy bueno en los comentarios: el atributo const en el código original sólo se aplica a los caracteres apuntados por gText y no a gText sí.

+0

gracias. Strcpy no resuelve esto, pero condicioné la copia para que se haga solo si la longitud no es mayor que los límites. ¡Gracias! – IUnknownPointer

1

Yo diría que no es un falso positivo. Existe el riesgo potencial de que alguien venga y cambie la longitud de gText sin darse cuenta de que no puede tener más de 32 caracteres. Definitivamente pondré algún tipo de control antes de la memcpy para asegurarme de que no pueda haber un desbordamiento del búfer.

p. Ej.

char xText[32]; 
SecureZeroMemory(xText, 32); 
size_t lenToCopy = MIN(strlen(gText), 32); 
memcpy(xText, gText, lenToCopy); 

También reemplazaría el número mágico 32 con una constante.

+0

Comenté una observación muy similar y la respuesta fue eliminada por su autor. Así que no repetiré lo mismo otra vez, pero como has decidido trabajar con todos los valores posibles de 'gText', ¿por qué asumir que' gText' es una cadena bien formada (es ilegal llamar 'strlen' a un char matriz que no es una cadena bien formada)? –

+1

Y el '32' en' MIN (.., 32) 'debe ser' 31' si se supone que 'xText' contiene una cadena bien formada después de la copia. –

+0

@Pascal: El uso de memcpy en lugar de una función de cadena implica para mí que la intención era obtener algo que se trataría como un bloque de bytes de tamaño fijo en lugar de una cadena C. Es por eso que establecí el límite en 32. Si tratara de duplicar una cadena, usaría strncpy (o equivalente) para hacerlo, o como esto es C++ std :: string. – JeremyP

Cuestiones relacionadas