- C和C++安全編碼(原書第2版)
- (美)Robert C.Seacord
- 485字
- 2020-10-30 17:56:43
2.4.5 使字符串對象的引用失效
修改字符串的操作會使引用、指針和引用字符串對象的迭代器失效,這可能會導致錯誤。使用無效的迭代器是未定義的行為,并可能會導致安全漏洞。
例如,下面的程序片段試圖清洗存儲在input字符數組的e-mail地址,再將它傳遞給命令shell,方法是把以空字符結尾的字節串拷貝到一個字符串對象(email)中,同時把每個分號替換為空格字符,如下所示。
01 char input[]; 02 string email; 03 string::iterator loc = email.begin(); 04 // 復制到 string 對象,同時把";" 轉換成 " " 05 for (size_t i=0; i < strlen(input); i++) { 06 if (input[i] != ';') { 07 email.insert(loc++, input[i]); // 非法迭代器 08 } 09 else email.insert(loc++, ' '); // 非法迭代器 10 }
這段代碼的問題是第一次調用insert()后,迭代器loc失效,以后每次調用insert()都導致未定義的行為。如果程序員意識到這個問題,就可以很容易地修復這個問題,如下所示。
01 char input[]; 02 string email; 03 string::iterator loc = email.begin(); 04 // 復制到 string 對象,同時把";" 轉換成 " " 05 for (size_t i=0; i < strlen(input); ++i) { 06 if (input[i] != ';') { 07 loc = email.insert(loc, input[i]); 08 } 09 else loc = email.insert(loc, ' '); 10 ++loc; 11 }
在這個版本的程序中,每次插入后,迭代器loc的值都被正確地更新,從而消除了未定義的行為。大部分被檢查過的標準模板庫(STL)實現都自動檢測常見的錯誤。至少,在使用你的完整測試做預發布測試期間,在單一平臺上使用一個被檢查過的STL實現來運行你的代碼。
basic_string類一般可以防止緩沖區溢出,但仍存在編程錯誤可能會導致緩沖區溢出的情況。雖然當操作引用字符串的范圍之外的內存時,C++一般拋出一個std::out_of_range類型的異常,但是為了使效率最高,下標成員std::string::operator[](不執行邊界檢查)不會拋出異常。例如,下面的程序片段在f()>= bs.size()時會導致在bs字符串對象分配的存儲空間的邊界之外的一個寫操作。
1 string bs("01234567"); 2 size_t i = f(); 3 bs[i] = '\0';
at()方法的行為方式與索引operator[]類似,但如果pos>=size(),它會拋出一個out_of_range異常,如下所示。
1 string bs("01234567"); 2 try { 3 size_t i = f(); 4 bs.at(i) = '\0'; 5 } 6 catch (out_of_range& oor) { 7 cerr << "Out of Range error: " << oor.what() << '\n'; 8 }
雖然basic_string類一般更安全,但在一個C++程序中使用以空字符結尾的字節字符串一般是不可避免的,除了在罕見的情況下,其中既沒有字符串字面值,又沒有與接受以空字符結尾的字節字符串的現有庫的相互作用。c_str()方法可以用來生成一個與字符串對象內容相同的以空字符結尾的字符序列,并把它作為一個字符數組的指針返回。
string str = x; cout << strlen(str.c_str());
c_str()方法返回一個const值,這意味著調用free()或delet返回的字符串都是一個錯誤。修改返回的字符串,也會導致一個錯誤,所以如果你需要修改字符串,就先復制一份,然后修改副本。
- C++面向對象程序設計(微課版)
- GitLab Repository Management
- Mastering Kali Linux for Web Penetration Testing
- MySQL數據庫管理與開發(慕課版)
- Apache Mahout Clustering Designs
- Python數據結構與算法(視頻教學版)
- Azure Serverless Computing Cookbook
- Arduino Wearable Projects
- PyQt編程快速上手
- Python一行流:像專家一樣寫代碼
- 零基礎學SQL(升級版)
- C++面向對象程序設計
- Raspberry Pi開發實戰
- JavaScript全棧開發
- Unity與C++網絡游戲開發實戰:基于VR、AI與分布式架構