¿Por qué strcpy y strncpy no son seguros de usar?

función strcpy()

La función strcpy() se usa para copiar la string de origen a la string de destino. Si el tamaño del búfer de la string de destino es mayor que la string src, copie la string src en la string de destino con el carácter NULL de terminación. Pero si el búfer dest es menor que src, copiará el contenido sin terminar con el carácter NULL. Las strings no pueden superponerse y la string de destino debe ser lo suficientemente grande para recibir la copia. 

Sintaxis:

char *strcpy( char *dest, const char *src )

Parámetros: esta función acepta dos parámetros, como se mencionó anteriormente y se describe a continuación:

  • src: La string que se copiará.
  • dest: Puntero a la array de destino donde se copiará el contenido.

Valor devuelto: Devuelve un puntero a la string de destino. 

C++

// C++ Program to illustrate the
// strcpy() function in C/C++
 
#include <iostream>
#include <cstring>
using namespace std;
 
int main()
{
    char src[] = "geeksforgeeks";
 
    // Here destination is large enough
    // to store the src with Null
    // character at the end
    char dest[14];
 
    // copying src into dest.
    strcpy(dest, src);
    cout << "Copied string: " << dest << endl;
     
    return 0;
}
 
// This code is contributed by sarajadhav12052009

C

// C Program to illustrate the
// strcpy() function in C/C++
#include <stdio.h>
#include <string.h>
int main()
{
    char src[] = "geeksforgeeks";
 
    // Here destination is large enough
    // to store the src with Null
    // character at the end
    char dest[14];
 
    // copying src into dest.
    strcpy(dest, src);
    printf("Copied string: %s\n", dest);
     
    return 0;
}
Producción:

Copied string: geeksforgeeks

Problema con strcpy(): la función strcpy() no especifica el tamaño de la array de destino, por lo que la saturación del búfer suele ser un riesgo. Usar la función strcpy() para copiar una array de caracteres grande en una más pequeña es peligroso, pero si la string cabe, no valdrá la pena correr el riesgo. Si la string de destino no es lo suficientemente grande para almacenar la string de origen, entonces el comportamiento de strcpy() no se especifica ni se define. 

C++

// C++ Program to illustrate the problem in
// strcpy() function in C/C++
 
#include <iostream>
#include <cstring>
using namespace std;
 
int main()
{
    char src[] = "geeksforgeeks";
 
    // Here destination is not large
    // enough to store the src. so the
    // behaviour of strcpy is unspecified.
    // program may crashed, but its
    // printing geeksforgeeks
    char dest[2];
     
    // copying src into dest.
    strcpy(dest, src);
    cout << "Copied string: " << dest << endl;
     
    return 0;
}
 
// This code is contributed by sarajadhav12052009

C

// C Program to illustrate the problem in
// strcpy() function in C/C++
#include <stdio.h>
#include <string.h>
int main()
{
    char src[] = "geeksforgeeks";
 
    // Here destination is not large
    // enough to store the src. so the
    // behaviour of strcpy is unspecified.
    // program may crashed, but its
    // printing geeksforgeeks
    char dest[2];
     
    // copying src into dest.
    strcpy(dest, src);
    printf("Copied string: %s\n", dest);
     
    return 0;
}
Producción:

Copied string: geeksforgeeks

función strncpy()

La función strncpy() es similar a la función strcpy(), excepto que se copian como máximo n bytes de src. Si no hay ningún carácter NULL entre los primeros n caracteres de src, la string colocada en dest no terminará en NULL. Si la longitud de src es menor que n, strncpy() escribe caracteres NULL adicionales en dest para garantizar que se escriban un total de n caracteres. Sintaxis:

char *strncpy( char *dest, const char *src, size_t n )

Parámetros: esta función acepta tres parámetros, como se mencionó anteriormente y se describe a continuación:

  • src: La string que se copiará.
  • dest: Puntero a la array de destino donde se copiará el contenido.
  • n: el primer carácter n copiado de src a dest.

Valor devuelto: Devuelve un puntero a la string de destino. 

Ejemplo: 

C++

// C++ Program to illustrate the
// strcpy() function in C/C++
 
#include <iostream>
#include <cstring>
using namespace std;
 
int main()
{
    char src[] = "geeksforgeeks";
     
    // The destination string size is 14.
    char dest[14];
     
    // copying n bytes of src into dest.
    strncpy(dest, src, 14);
    cout << "Copied string: " << dest << endl;
     
    return 0;
}
 
// This code is contributed by sarajadhav12052009

C

// C Program to illustrate the
// strcpy() function in C/C++
#include <stdio.h>
#include <string.h>
int main()
{
    char src[] = "geeksforgeeks";
     
    // The destination string size is 14.
    char dest[14];
     
    // copying n bytes of src into dest.
    strncpy(dest, src, 14);
    printf("Copied string: %s\n", dest);
     
    return 0;
}
Producción:

Copied string: geeksforgeeks

Problema con strncpy(): si no hay ningún carácter nulo entre los primeros n caracteres de src, la string colocada en dest no terminará en nulo. Por lo tanto, strncpy() no garantiza que la string de destino termine en NULL. La string no terminada strlen() puede causar un error de segmentación. En otras palabras, una string no terminada en C/C++ es una bomba de tiempo que espera destruir el código. 

C++

// C++ Program to illustrate the problem in
// strcpy() function in C/C++
 
#include <iostream>
#include <cstring>
using namespace std;
 
int main()
{
    char src[] = "geeksforgeeks";
     
    // The destination string size is 8
    // which is less than length of src.
    char dest[8];
     
    // copying 8 bytes of src into dest.
    // dest is not NULL terminated.
    strncpy(dest, src, 8);
     
    // using strlen function on non terminated.
    // string which can cause segfault.
    int len = strlen(dest);
     
    cout << "Copied string: " << dest << endl;
    cout << "Length of destination string: " << len << endl;
     
    return 0;
}
 
// This code is contributed by sarajadhav12052009

C

// C Program to illustrate the problem in
// strcpy() function in C/C++
#include <stdio.h>
#include <string.h>
int main()
{
    char src[] = "geeksforgeeks";
     
    // The destination string size is 8
    // which is less than length of src.
    char dest[8];
     
    // copying 8 bytes of src into dest.
    // dest is not NULL terminated.
    strncpy(dest, src, 8);
     
    // using strlen function on non terminated.
    // string which can cause segfault.
    int len = strlen(dest);
     
    printf("Copied string: %s\n", dest);
    printf("Length of destination string: %d\n", len);
     
    return 0;
}
Producción:

Copied string: geeksfor
Length of destination string: 8

Ahora, la siguiente pregunta es, ¿cualquier función que garantice que la string de destino terminará en NULL y no habrá posibilidad de saturación del búfer? Entonces, la respuesta a la pregunta anterior es «SÍ», hay varias funciones en la biblioteca «stdio.h» que garantizan que se cumplirá la condición anterior.

Ambas funciones garantizan que la string de destino terminará en NULL . De manera similar, la función snprintf() , la función strlcpy copiaron como máximo caracteres dest_size-1 (dest_size es el tamaño del búfer de la string de destino) de src a dst, truncando src si es necesario. El resultado siempre termina en nulo. La función devuelve strlen(src). El desbordamiento de búfer se puede comprobar de la siguiente manera:

 if (strlcpy(dst, src, dstsize) >= dest_size)
         return -1;

Clasificación de las funciones según el nivel de cordura:

strcpy < strncpy < snprintf < strlcpy

Publicación traducida automáticamente

Artículo escrito por vivek kumar 9 y traducido por Barcelona Geeks. The original can be accessed here. Licence: CCBY-SA

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *