From e1573c8467b0d8a470805fc8d19da75fb655bc5d Mon Sep 17 00:00:00 2001 From: Arjen Baart Date: Tue, 5 Nov 2019 22:07:28 +0100 Subject: [PATCH] String: Added boundary checks --- ChangeLog | 1 + TODO | 1 - src/String.h | 17 +++++++++++++++++ src/string.cpp | 12 ++++++++++-- test/string_basics.cpp | 22 ++++++++++++++++++---- test/string_basics.exp | 2 ++ test/string_substring.cpp | 15 +++++++++++++++ test/string_substring.exp | 1 + 8 files changed, 64 insertions(+), 7 deletions(-) diff --git a/ChangeLog b/ChangeLog index f436736..afa2233 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,4 @@ + - String: Boundary checking on index and subtring operators - Ported class Integer from the Gnu libg++ library. Oct 31, 2019 - Release 0.2 diff --git a/TODO b/TODO index fea13d1..70ec276 100644 --- a/TODO +++ b/TODO @@ -1,7 +1,6 @@ Things to do: ============= -- String: Boundary checking on index and subtring operators - String: test cases for numerical conversion - String: Implement String != regex operator - String: index and rindex methods with String argument diff --git a/src/String.h b/src/String.h index 8c154be..02cafc4 100644 --- a/src/String.h +++ b/src/String.h @@ -381,4 +381,21 @@ public: friend bool operator == (const regex &r, const String &s); }; +class StringException +{ + String message; + +public: + + StringException(String m) + { + message = m; + } + + String what() + { + return message; + } +}; + #endif /* STRING_H */ diff --git a/src/string.cpp b/src/string.cpp index 8644e66..742fa1b 100644 --- a/src/string.cpp +++ b/src/string.cpp @@ -351,12 +351,15 @@ String & String::operator>>=(int n) /* Substring selection and assignment */ -// TODO: Boundary check - substring String::operator()(int start, int len) { substring sub; + if (start >= strlen(p->s) || start + len >= strlen(p->s)) + { + throw StringException("Substring Out of bounds: (" + + String(start) + ", " + String(len) + ")"); + } sub.str = this; sub.start = start; sub.len = len; @@ -431,6 +434,11 @@ std::istream& operator>>(std::istream& s, String& x) char& String::operator[](int i) { + if (i >= strlen(p->s)) + { + throw StringException("Out of bounds: " + String(i)); + } + return p->s[i]; } diff --git a/test/string_basics.cpp b/test/string_basics.cpp index 9b2d6cd..e824c6d 100644 --- a/test/string_basics.cpp +++ b/test/string_basics.cpp @@ -72,17 +72,31 @@ int main() assert(c == 'd'); // Out of bounds - //c = s1[-1]; - //std::cout << "Seventh character of " << s1 << " char(" << (int)c << ")\n"; + try + { + c = s1[-1]; + std::cout << "Seventh character of " << s1 << " char(" << (int)c << ")\n"; + } + catch (StringException se) + { + std::cout << "String exception: " << se.what() << "\n"; + } //assert(c == 'a'); s1[2] = 'Z'; std::cout << "After \"abcde\"[2] = 'Z' : " << s1 << "\n"; assert(s1 == "abZde"); - s1[5] = 'X'; + try + { + s1[5] = 'X'; + } + catch (StringException se) + { + std::cout << "String exception: " << se.what() << "\n"; + } std::cout << "After \"abcde\"[5] = 'X' : " << s1 << "\n"; - //assert(s1 == "abZde"); + assert(s1 == "abZde"); return 0; } diff --git a/test/string_basics.exp b/test/string_basics.exp index 8b99b10..cc4d34a 100644 --- a/test/string_basics.exp +++ b/test/string_basics.exp @@ -6,6 +6,8 @@ The default contructor makes an empty string: "" The length of "abcde" is 5 First character of abcde 'a' Fourth character of abcde 'd' +String exception: Out of bounds: -1 After "abcde"[2] = 'Z' : abZde +String exception: Out of bounds: 5 After "abcde"[5] = 'X' : abZde PASS string_basics (exit status: 0) diff --git a/test/string_substring.cpp b/test/string_substring.cpp index ec2df92..a6119b7 100644 --- a/test/string_substring.cpp +++ b/test/string_substring.cpp @@ -42,6 +42,21 @@ int main() std::cout << s5 << "\n"; assert(s5 == "abc12345678ijkl"); + // Select a substring out of bounds + try + { + String s7 = "abcdefghijkl"; + String s8 = s7(9,5); // s7 = "jkl.." + + std::cout << "The substring (9,5) of " << s7 << " is " << s8 << "\n"; + } + catch (StringException se) + { + std::cout << "String exception: " << se.what() << "\n"; + } + + //assert(s2 == "defgh"); + return 0; } diff --git a/test/string_substring.exp b/test/string_substring.exp index 734353e..2fe771e 100644 --- a/test/string_substring.exp +++ b/test/string_substring.exp @@ -2,4 +2,5 @@ The substring (3,5) of abcdefghijkl is defgh Replace substring (3,5) of abcdefghijkl with 12345678 : abc12345678ijkl Insert "12345678" into "abcdefghijkl" : abc12345678defghijkl Remove part of "abc12345678defghijkl" : abc12345678ijkl +String exception: Substring Out of bounds: (9, 5) PASS string_substring (exit status: 0) -- 2.11.0