Pergunta

Quando tento fazer coisas como esta:

char* prefix = "Sector_Data\\sector";
char* s_num = "0";
std::strcat(prefix, s_num);
std::strcat(prefix, "\\");

e assim por diante e assim por diante, eu recebo um aviso

warning C4996: 'strcat': This function or variable may be unsafe. Consider using strcat_s instead.

Por que strcat considerado inseguro, e se existe uma maneira de se livrar de este aviso sem usar strcat_s?

Além disso, se a única maneira de se livrar do alerta é usar strcat_s, como ele funciona (sintaxe-wise: aparentemente ele não leva dois argumentos).

Foi útil?

Solução

Porque o buffer, prefixo, poderia ter menos espaço do que você está copiando para ele, causando uma saturação de buffer. Portanto, um hacker poderia passar uma cadeia especialmente criado que substitui o endereço do remetente ou outra memória crítica e iniciar a execução de código no contexto do seu programa.

strcat_s resolve este por forçá-lo a passar no comprimento do buffer no qual você está copiando o string; ele irá truncar a string se necessário, para se certificar de que o buffer não é superação.

O Google strcat_s para ver exatamente como usá-lo.

Outras dicas

Se você estiver usando c ++, por que não evitar toda a confusão e uso std::string. O mesmo exemplo sem erros ficaria assim:

std::string prefix = "Sector_Data\\sector";
prefix += "0";
prefix += "\\"

Não há necessidade de se preocupar com o tamanho do buffer e todas essas coisas. E se você tem uma API que leva um const char *, você pode simplesmente usar o membro .c_str();

some_c_api(prefix.c_str());

Essa é uma das funções de manipulação de string em C / C ++ que podem levar à saturação de buffer erros.

O problema é que a função não sabe o que o tamanho dos buffers são. A partir da documentação MSDN:

O primeiro argumento, strDestination, deve ser grande o suficiente para manter o atual strDestination e strSource combinado e um fechamento '\ 0'; de outra forma, um transbordo na memória intermédia pode ocorrer.

strcat_s leva um argumento extra dizendo que o tamanho do buffer. Isso permite que ele para validar os tamanhos antes de fazer o concat, e vai impedir derrapagens. Consulte http://msdn.microsoft.com/en-us/library/d45bbxx4 aspx

Você pode se livrar destes aviso, acrescentando:

_CRT_SECURE_NO_WARNINGS

e

_SCL_SECURE_NO_WARNINGS

para definições pré-processador do seu projeto.

Para ativar o aviso de fora, você pode fazer isso.

#pragma warning(disable:4996)

btw, eu recomendo fortemente que você use strcat_s ().

Porque ele não tem meios de verificação para ver se a cadeia de destino (prefixo) no seu caso será escrito passado seus limites. strcat funciona essencialmente por looping, copiar byte a byte a cadeia de origem para o destino. Seus pára quando vê um valor "0" (anotado por '\ 0') chamado um terminal nulo. Desde C não tem construído em verificação de limites, eo str dest é apenas um lugar na memória, strcat continuará indo ad-infinidium mesmo que sopra passado o str fonte ou o dest. se str não tem um terminal nulo.

As soluções acima são específicos da plataforma para o ambiente Windows. Se você quer algo independente de plataforma, você tem que disputa com strncat:

strncat(char* dest, const char* src, size_t count)

Esta é outra opção quando usado de forma inteligente. Você pode usar contagem para especificar o número máximo de caracteres para copiar. Para fazer isso, você tem que descobrir o quanto de espaço disponível em dest (quanto você alocado - strlen (dest)). E passar isso como count

Há dois problemas com strcat. Primeiro, você tem que fazer toda a sua validação fora da função, fazendo o trabalho que é quase o mesmo que a função:

if(pDest+strlen(pDest)+strlen(pScr) < destSize)

Você tem que caminhar toda a extensão de ambas as cordas só para ter certeza que vai se encaixar, antes de caminhar para baixo toda a sua extensão novamente para fazer a cópia. Devido a isso, muitos programadores vão simplesmente assumir que vai se encaixar e ignorar o teste. Pior ainda, pode ser que quando o código é escrito em primeiro lugar é garantido para caber, mas quando alguém acrescenta outra strcat, ou muda o tamanho do buffer ou em algum lugar constante mais no programa, agora você tem problemas.

O outro problema é se pSrc e PDST sobreposição. Dependendo do seu compilador, strcat pode muito bem ser loop simples que verifica um carácter de cada vez para um 0 no pSrc. Se PDST substitui que 0, então você vai entrar em um loop que será executado até que seus programa falhar.

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