2017-08-10 6 views
1

Aujourd'hui, j'ai découvert que les compiles et les impressions suivantes: 42Lire char * à partir de flux - un autre fiasco de débordement de tampon?

#include <iostream> 
#include <sstream> 

int main() 
{ 
    std::stringstream s; 
    s << 42; 
    char c[8]; 
    s >> c; 
    std::cout << c; 
} 

Mais ceci est une attaque de débordement de tampon potentiel, non? Si nous lisons à partir du flux fourni par l'utilisateur, nous ne pouvons pas facilement connaître la taille des données et ne pouvons donc pas allouer suffisamment de stockage. std::gets a été retiré, peut-être que cela devrait être aussi?

+0

Peut-être que dans le cadre de https://stackoverflow.com/questions/3203452/how-to-read-entire-stream-into-a-stdstring? – lz96

+0

Cela montre la bonne façon de faire cela, ma question est plus sur pourquoi C++ permet de me tirer dans le pied si facilement. – Lyberta

+0

@ M.M 'fgets' a un paramètre de taille, celui-ci ne le fait pas. – Lyberta

Répondre

1

Eh bien, vous pouvez éviter le débordement de la mémoire tampon dans ce cas par écrit:

s >> setw(sizeof c) >> c; 

Je pense donc qu'il est plus proche de l'affaire de fgets qui peut être utilisé pour vous tirer dans le pied, mais peut également être utilisé correctement et c'est une option parfaitement viable lorsqu'il est utilisé correctement.

Je pense il y a suffisamment de code en direct encore qui utilise cette surcharge de operator>> que ce n'est pas vraiment viable pour désapprouver il, par exemple:

void func(char *buf, size_t buf_len) 
{ 
    std::cin >> setw(buf_len) >> buf; 
} 

Mais pour écrire un nouveau code, mon conseil serait d'éviter d'utiliser entièrement les tableaux (Tableaux de style C, c'est-à-dire). Au lieu de cela, utilisez std::string, ou std::array, ou d'autres conteneurs de ce type qui sont plus difficiles à provoquer des dépassements de tampon.

+0

Je ne vois pas comment utiliser 'std :: array' change quoi que ce soit ici –

+0

@MooingDuck J'espérais qu'il y aurait une surcharge pour' operator >> 'avec' std :: istream' et 'std :: array'. .. sinon il devrait y avoir :) –

+0

Malheureusement, aucun conteneur C++ n'a une telle surcharge, sauf 'std :: string' et' std :: wstring' –