Pergunta

EDIT: Eu adicionei a fonte para o exemplo.

Eu me deparei este exemplo:

char source[MAX] = "123456789";
char source1[MAX] = "123456789";
char destination[MAX] = "abcdefg";
char destination1[MAX] = "abcdefg";
char *return_string;
int index = 5;

/* This is how strcpy works */
printf("destination is originally = '%s'\n", destination);
return_string = strcpy(destination, source);
printf("after strcpy, dest becomes '%s'\n\n", destination);

/* This is how strncpy works */
printf( "destination1 is originally = '%s'\n", destination1 );
return_string = strncpy( destination1, source1, index );
printf( "After strncpy, destination1 becomes '%s'\n", destination1 );

Que produziu esta saída:

destination is originally = 'abcdefg'
After strcpy, destination becomes '123456789'

destination1 is originally = 'abcdefg'
After strncpy, destination1 becomes '12345fg'

O que me faz pensar por que alguém gostaria desse efeito. Parece que seria confuso. Este programa me faz pensar que você poderia copiar basicamente sobre o nome de alguém (por exemplo, Tom Brokaw) com Tom Bro763.

Quais são as vantagens de usar strncpy() sobre strcpy()?

Foi útil?

Solução

strncpy Combat Buffer Overflow, exigindo que você coloque um comprimento nele. strcpy depende de uma trilha \0, que nem sempre ocorre.

Em segundo lugar, por que você escolheu copiar apenas 5 caracteres na sequência de 7 caracteres está além de mim, mas está produzindo comportamento esperado. É apenas copiar sobre o primeiro n Personagens, onde n é o terceiro argumento.

o n As funções são todas usadas como codificação defensiva contra transbordamentos de buffer. Por favor, use -os em vez de funções mais antigas, como strcpy.

Outras dicas

o strncpy() A função foi projetada com um problema muito particular em mente: manipular strings armazenados na maneira de entradas originais do diretório UNIX. Eles usaram uma matriz de tamanho fixo, e um terminador nua foi usado apenas se o nome do arquivo fosse mais curto que a matriz.

Isso é o que está por trás das duas esquisitices de strncpy():

  • Ele não coloca um terminador nul no destino, se estiver completamente preenchido; e
  • Sempre preenche completamente o destino, com nuls, se necessário.

Para um "mais seguro strcpy()", você está melhor usando strncat() igual a:

if (dest_size > 0)
{
    dest[0] = '\0';
    strncat(dest, source, dest_size - 1);
}

Isso sempre terá terminado com o resultado e não copiará mais do que o necessário.

Enquanto eu conheço a intenção por trás strncpy, não é realmente uma boa função. Evite os dois. Raymond Chen explica.

Pessoalmente, minha conclusão é simplesmente evitar strncpy E todos os seus amigos se você estiver lidando com cordas terminadas nulas. Apesar do "STR" em nome, essas funções não produzem cordas terminadas nulas. Eles convertem uma corda terminada nula em um buffer de caractere bruto. Usando-os onde é esperada uma string terminada nula, pois o segundo buffer está errado. Você não apenas não consegue ter uma terminação nula adequada se a fonte for muito longa, mas se a fonte for curta, você receberá um preenchimento nulo desnecessário.

Veja também Por que o strncpy é inseguro?

Strncpy não é mais seguro que o STRCPY, apenas troca um tipo de bugs com outro. Em C, ao manusear as cordas C, você precisa saber o tamanho dos seus buffers, não há como contornar isso. Strncpy foi justificado para a coisa do diretório mencionada por outros, mas, caso contrário, você nunca deve usá -lo:

  • Se você conhece o comprimento da sua corda e do buffer, por que usar o strncpy? É um desperdício de poder de computação na melhor das hipóteses (adicionando inútil 0)
  • Se você não conhece o comprimento, corre o risco de truncando silenciosamente suas cordas, o que não é muito melhor do que um buffer transbordante

O que você está procurando é a função strlcpy() que termina sempre a string com 0 e inicializa o buffer. Também é capaz de detectar transbordamentos. O único problema, não é (realmente) portátil e está presente apenas em alguns sistemas (BSD, Solaris). O problema com essa função é que ela abre outra lata de vermes, como pode ser visto pelas discussões sobrehttp://en.wikipedia.org/wiki/strlcpy

Minha opinião pessoal é que é muito mais útil do que strncpy() e strcpy(). Tem melhor desempenho e é um bom companheiro para snprintf(). Para plataformas que não o possuem, é relativamente fácil de implementar. (Para a fase de desenvolvimento de um aplicativo, substituo essas duas funções (snprintf() e strlcpy()) com uma versão de aprisionamento que aborta brutalmente o programa sobre transbordamentos ou truncamentos de buffer. Isso permite capturar rapidamente os piores criminosos. Especialmente se você trabalha em uma base de código de outra pessoa.

EDITAR: strlcpy() pode ser implementado facilmente:

size_t strlcpy(char *dst, const char *src, size_t dstsize)
{
  size_t len = strlen(src);
  if(dstsize) {
    size_t bl = (len < dstsize-1 ? len : dstsize-1);
    ((char*)memcpy(dst, src, bl))[bl] = 0;
  }
  return len;
}

o strncpy() A função é a mais segura: você precisa passar no comprimento máximo que o buffer de destino pode aceitar. Caso contrário, pode acontecer que a sequência de origem não seja corretamente 0 terminada; nesse caso, o strcpy() A função poderia escrever mais caracteres no destino, corrompendo qualquer coisa que esteja na memória após o buffer de destino. Este é o problema de buffer-overrun usado em muitas façanhas

Também para funções da API POSIX como read() que não coloca o término 0 no buffer, mas retorna o número de bytes lido, você colocará manualmente o 0 ou copiará usando -o usando strncpy().

No seu código de exemplo, index na verdade não é um índice, mas um count - diz quantos personagens no máximo para copiar de origem para destino. Se não houver byte nulo entre os primeiros n bytes de fonte, a string colocada no destino não será encerrada nula

Strncpy preenche o destino com ' 0' para o tamanho da fonte, embora o tamanho do destino seja menor ....

MANPAGE:

Se o comprimento do SRC for menor que n, strncpy () passa o restante do destes com bytes nulos.

E não apenas o restante ... também depois disso até que N caracteres seja alcançado. E assim você obtém um transbordamento ... (veja a implementação da página do homem)

Isso pode ser usado em muitos outros cenários, onde você precisa copiar apenas uma parte da sua sequência original para o destino. Usando strncpy (), você pode copiar uma parte limitada da string original, em oposição por strcpy (). Eu vejo o código que você colocou vem de publib.boulder.ibm.com.

Isso depende de nosso requisito. Para usuários do Windows

Usamos o strncpy sempre que não queremos copiar a string inteira ou queremos copiar apenas n número de caracteres. Mas cópias estrias de toda a string, incluindo o caractere nulo de encerramento.

Esses links ajudarão você a saber mais sobre o STRCPY e o strncpy e onde podemos usar.

Sobre StrCpy

sobre strncpy

O strncpy é uma versão mais segura do strcpy, na verdade, você nunca deve usar o strcpy, porque seu potencial buffer de transbordamento de vulnerabilidade, o que o torna vulnerável a todos os tipos de ataques

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top