SORU
17 Aralık 2013, Salı


Güvenli bir şekilde cinsel yolla bulaşan bir hastalık bir satır okumayı::ıstream?

İstiyorumgüvenli bir şekildestd::istream Bir satır okuyun. Akış, örneğin, bir Web sunucusu veya bir işleme dosyaları bilinmeyen kaynaklar tarafından sunulan bir bağlantı herhangi bir şey olabilir. Birçok cevap bu kodu ahlaki eşdeğer yapmaya başladı

void read(std::istream& in) {
    std::string line;
    if (std::getline(in, line)) {
        // process the line
    }
}

** 4, bir güvenlik açığına yol açacağını yukarıdaki kodu kullanarak muhtemelen şüpheli, verilen kaynak: kötü niyetli bir ajan bu kod büyük bir satırını kullanarak karşı hizmet reddi saldırısı mount. Böylece, oldukça yüksek bir değer için satır uzunluğunu sınırlamak istiyorum, diyelim ki 4 milyon charler. Birkaç büyük hatları ile karşılaştı olabilir, uygulanabilir her dosya için bir arabellek ayırır ve std::istream::getline() kullanmak için değil.

Nasıl satır boyutu, ideal olarak çok kötü ve ön bellek büyük parçalara ayırmadan kodu deforme olmadan sınırlı olabilir mi?

CEVAP
17 Aralık 2013, Salı


Karakter parametre okuma sayısı, bir şey getline_n aradı falan std::getline kendi versiyonu yazabilirsiniz.

#include <string>
#include <iostream>

template<typename CharT, typename Traits, typename Alloc>
auto getline_n(std::basic_istream<CharT, Traits>& in, std::basic_string<CharT, Traits, Alloc>& str, std::streamsize n) -> decltype(in) {
    std::ios_base::iostate state = std::ios_base::goodbit;
    bool extracted = false;
    const typename std::basic_istream<CharT, Traits>::sentry s(in, true);
    if(s) {
        try {
            str.erase();
            typename Traits::int_type ch = in.rdbuf()->sgetc();
            for(; ; ch = in.rdbuf()->snextc()) {
                if(Traits::eq_int_type(ch, Traits::eof())) {
                    // eof spotted, quit
                    state |= std::ios_base::eofbit;
                    break;
                }
                else if(str.size() == n) {
                    // maximum number of characters met, quit
                    extracted = true;
                    in.rdbuf()->sbumpc();
                    break;
                }
                else if(str.max_size() <= str.size()) {
                    // string too big
                    state |= std::ios_base::failbit;
                    break;
                }
                else {
                    // character valid
                    str  = Traits::to_char_type(ch);
                    extracted = true;
                }
            }
        }
        catch(...) {
            in.setstate(std::ios_base::badbit);
        }
    }

    if(!extracted) {
        state |= std::ios_base::failbit;
    }

    in.setstate(state);
    return in;
}

int main() {
    std::string s;
    getline_n(std::cin, s, 10); // maximum of 10 characters
    std::cout << s << '\n';
}

Abartılı olabilir ama.

Bunu Paylaş:
  • Google+
  • E-Posta
Etiketler:
C++

YORUMLAR

SPONSOR VİDEO

Rastgele Yazarlar

  • emimusic

    emimusic

    10 Mart 2006
  • Jonnyriddlin1

    Jonnyriddlin

    4 Ocak 2007
  • Stanislav Petrov

    Stanislav Pe

    7 ŞUBAT 2009