Pregunta

Recientemente he terminado un curso de la universidad en C.Por lo tanto me falta experiencia, por supuesto.

Algunas universidades tienden a enseñar a sus alumnos la programación segura, o al menos algunos de los elementos.Hay incluso un vídeo (tomado de aquí).

Estar en C, copiar cadenas, requiere - que yo sepa - strcpy o cadena.h funciones.¿Cómo se puede utilizar de manera segura en el día a día de programación?¿Tiene algunas funciones, que de asignación de manejar para prevenir desbordamientos de buffer?Hay la CERT seguro de codificación estándar para C.Ofrece ejemplos y soluciones compatibles con:

int main(int argc, char *argv[]) {
  /* ... */
  char prog_name[128];
  strcpy(prog_name, argv[0]);
  /* ... */
}

Y su alternativa es:

int main(int argc, char *argv[]) {
  /* ... */
  char *prog_name = (char *)malloc(strlen(argv[0])+1);
  if (prog_name != NULL) {
    strcpy(prog_name, argv[0]);
  }
  else {
    /* Couldn't get the memory - recover */
  }
  /* ... */
}

Tomados de aquí, 2º ejemplo.

Pero como voy a conseguir que más desafiante, más código, más trabajo.¿Por qué no cambiar la propia biblioteca?O al menos ¿por qué no ofrecer una alternativa segura o de la biblioteca de funciones, que se ocupan de esto en el camino correcto?

Gracias por leer, wishi

¿Fue útil?

Solución

La función Posix para esto (disponible en casi todos los sistemas) es strdup(). strcpy() se usa si no desea asignar nueva memoria y ya tiene un búfer que desea usar, pero entonces sabe mejor qué tan grande es ese búfer y si la cadena encaja en él. Si no sabe si la cadena encaja, hay strncpy() que solo copia un número dado de caracteres. Para que pueda limitar la cantidad copiada al tamaño de sus memorias intermedias.

Y además de eso, hay muchas bibliotecas de picadura que administran los tamaños de cadena de diferentes maneras.

Y desde que lo etiquetó C ++: Hay std::string que hace toda la administración de memoria por usted y no le da estos problemas.

Otros consejos

las funciones l (strlcpy, strlcat) de OpenBSD suelen ser mejores que las funciones n , son más rápidas y fáciles de usar de forma segura, pero no son estándar. Sin embargo, tienen licencia BSD, por lo que puede incluir una buena implementación conocida en cualquier programa para que pueda ser multiplataforma y seguro.

Para Windows, si no le importa la portabilidad, puede usar las funciones * _s.

Use strncpy :

#define BUFSIZE 127
int main(int argc, char *argv[]) {
  /* ... */
  char prog_name[BUFSIZE + 1];
  strncpy(prog_name, argv[0], BUFSIZE);
  progname[BUFSIZE]= '\0';
  /* ... */
}

Hay *n* versiones para la mayoría de las str* funciones.

Si entiendo correctamente, su verdadera pregunta es por qué las funciones API no se hacen más seguras.

Una razón es que la biblioteca C es heredada (demasiado tarde para cambiarla ahora).

Sin embargo, la razón principal es que la biblioteca está diseñada para ser minimalista, por lo que hace lo mínimo y es responsabilidad del usuario asegurarse de que se llama correctamente. Si realizaba controles excesivos, se pagaría un precio cada vez que se llama, incluso si el usuario puede asegurar por otras razones que no ocurrirá ningún problema. Esto es muy muy común en muchas API.

Dicho esto, hay suficientes bibliotecas que ofrecen alternativas más seguras, simplemente no son parte de la biblioteca estándar. Además, muchas personas que hacen cosas de nivel superior trabajan con C ++, que tiene bibliotecas de clases estándar para muchas de esas cosas.

En realidad, Microsoft proporcionó alternativas seguras a las funciones CRT. Sin embargo, todos los que conozco los odian y desactivan la advertencia de que no deben usar las funciones antiguas. Si quieres algo seguro, tal vez deberías usar C ++. Y luego cadenas STL o algo así como Qt.

Bueno, o vas a plataformas como .NET o Java, que generalmente no sufren estos problemas (tu aplicación puede fallar, pero no hay forma de inyectar código en tu aplicación a través de un desbordamiento del búfer).

Editar: Con Data Execution Prevention / NX habilitado (predeterminado para Vista y .NET), esto tampoco debería ser un problema para las plataformas tradicionales.

int main
(
    int argc, 
    char *argV[]
) 
{
   char prog_name[128];
   if (strlen(argV[0]) < sizeof(prog_name))
   {
       strcpy(prog_name, argV[0]);
   }
   else
   {
       printf("%s is too large for the internal buffer\n", argV[0]);
   }

   return 0;
}

Tal vez usted podría encontrar útil la lectura de las respuestas a esta pregunta

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top