diff --git a/packages/core/StringLib.cpp b/packages/core/StringLib.cpp index 86df2e5aa..e94ca529b 100644 --- a/packages/core/StringLib.cpp +++ b/packages/core/StringLib.cpp @@ -126,583 +126,6 @@ long StringLib::FormattedString::size(void) const return length(); } -/****************************************************************************** - * STRING PUBLIC METHODS - ******************************************************************************/ - -/*---------------------------------------------------------------------------- - * Constructor - *----------------------------------------------------------------------------*/ -SafeString::String(long _maxlen) -{ - if(_maxlen <= 0) maxlen = DEFAULT_STR_SIZE; - else maxlen = _maxlen; - carray = new char[maxlen]; - carray[0] ='\0'; - len = 1; -} - -/*---------------------------------------------------------------------------- - * Constructor - *----------------------------------------------------------------------------*/ -SafeString::String(long _maxlen, const char* _str, ...) -{ - if(_str != NULL) - { - va_list args; - va_start(args, _str); - len = vsnprintf(NULL, _maxlen, _str, args) + 1; // get length - va_end(args); - carray = new char[len]; // allocate memory - maxlen = len; - va_start(args, _str); - vsprintf(carray, _str, args); // copy in formatted contents - va_end(args); - carray[maxlen - 1] ='\0'; // null terminate - } - else - { - maxlen = DEFAULT_STR_SIZE; - carray = new char[maxlen]; - carray[0] = '\0'; - len = 1; - } -} - -/*---------------------------------------------------------------------------- - * Constructor - *----------------------------------------------------------------------------*/ -SafeString::String(const char* _str) -{ - maxlen = strlen(_str) + 1; - carray = new char[maxlen]; - len = maxlen; - StringLib::copy(carray, _str, len); - carray[len - 1] = '\0'; -} - -/*---------------------------------------------------------------------------- - * Constructor (COPY) - *----------------------------------------------------------------------------*/ -SafeString::String(const SafeString& other) -{ - maxlen = other.maxlen; - carray = new char[maxlen]; - len = other.len; - StringLib::copy(carray, other.carray, len); - carray[len - 1] = '\0'; -} - -/*---------------------------------------------------------------------------- - * Constructor (ENCODE) - *----------------------------------------------------------------------------*/ -SafeString::String (int base, unsigned char* buffer, int size) -{ - if(base == 64) - { - int encoded_len = size; - carray = StringLib::b64encode(buffer, &encoded_len); - maxlen = encoded_len; - len = encoded_len; - } - else - { - maxlen = DEFAULT_STR_SIZE; - carray = new char[maxlen]; - memset(carray, 0, maxlen); - len = 1; - } -} - -/*---------------------------------------------------------------------------- - * Destructor - *----------------------------------------------------------------------------*/ -SafeString::~String(void) -{ - delete [] carray; -} - -/*---------------------------------------------------------------------------- - * getString - *----------------------------------------------------------------------------*/ -const char* SafeString::str(bool duplicate) -{ - if(duplicate) - { - char* new_str = new char[len]; - StringLib::copy(new_str, carray, len); - return new_str; - } - - return carray; -} - -/*---------------------------------------------------------------------------- - * length - number of non-null characters in string - *----------------------------------------------------------------------------*/ -long SafeString::length(void) const -{ - return len - 1; // remove null terminator in length -} - -/*---------------------------------------------------------------------------- - * bytes - size of memory needed to store string (includes null terminator) - *----------------------------------------------------------------------------*/ -long SafeString::bytes(void) const -{ - return len; -} - -/*---------------------------------------------------------------------------- - * appendChar - *----------------------------------------------------------------------------*/ -void SafeString::appendChar(char c) -{ - if(len >= maxlen) - { - maxlen *= 2; // optimization - char* new_str = new char[maxlen]; - memset(new_str, 0, maxlen); - StringLib::copy(new_str, carray, len); - delete [] carray; - carray = new_str; - } - - carray[len-1] = c; - carray[len] = '\0'; - len++; -} - -/*---------------------------------------------------------------------------- - * findChar - *----------------------------------------------------------------------------*/ -int SafeString::findChar (char c, int start) -{ - if(start >= 0) - { - for(int i = start; i < len; i++) - { - if(carray[i] == c) - { - return i; - } - } - } - - return -1; -} - -/*---------------------------------------------------------------------------- - * setChar - *----------------------------------------------------------------------------*/ -SafeString& SafeString::setChar (char c, int index) -{ - if(index >= 0 && index < len) - { - carray[index] = c; - } - return *this; -} - -/*---------------------------------------------------------------------------- - * replace - * - * replaces all occurrences - *----------------------------------------------------------------------------*/ -bool SafeString::replace(const char* oldtxt, const char* newtxt) -{ - bool status = false; - - int newtxtlen = (int)strlen(newtxt); - char* startptr = strstr(carray, oldtxt); - char* endptr = startptr + strlen(oldtxt); - - while(startptr != NULL) - { - status = true; - - maxlen += newtxtlen; - char* newstr = new char[maxlen]; - memset(newstr, 0, maxlen); - - memcpy(newstr, carray, (startptr - carray)); - memcpy(newstr + (startptr - carray), newtxt, newtxtlen); - memcpy(newstr + (startptr - carray) + newtxtlen, endptr, len - (endptr - carray)); - - delete [] carray; - carray = newstr; - - len = (int)strlen(carray) + 1; - - startptr = strstr(carray, oldtxt); - endptr = startptr + strlen(oldtxt); - } - - return status; -} - -/*---------------------------------------------------------------------------- - * inreplace - * - * replaces all occurrences in place - *----------------------------------------------------------------------------*/ -bool SafeString::inreplace (const char* oldtxt[], const char* newtxt[], int num_replacements) -{ - /* Check Number of Replacements */ - if(num_replacements > MAX_REPLACEMENTS) - { - return false; - } - - /* Get Delta Sizes for each Replacement */ - int replacement_size_delta[MAX_REPLACEMENTS]; - for(int r = 0; r < num_replacements; r++) - { - replacement_size_delta[r] = strlen(newtxt[r]) - strlen(oldtxt[r]); - } - - /* Count Number of Replacements */ - int replacement_count[MAX_REPLACEMENTS]; - for(int r = 0; r < num_replacements; r++) - { - replacement_count[r] = 0; - int i = 0; - while(i < (len - 1)) - { - int j = i; - int k = 0; - while((j < (len - 1)) && oldtxt[r][k] && (carray[j] == oldtxt[r][k])) - { - j++; - k++; - } - - if(oldtxt[r][k] == '\0') - { - replacement_count[r]++; - i = j; - } - else - { - i++; - } - } - } - - /* Calculate Size of New String */ - int total_size_delta = 0; - for(int r = 0; r < num_replacements; r++) - { - total_size_delta += replacement_size_delta[r] * replacement_count[r]; - } - - /* Set New Size */ - int new_size = len + total_size_delta; - if(new_size > 0) - { - len = new_size; - maxlen = new_size; - } - else - { - len = 1; - maxlen = 1; - carray[0] = '\0'; - return true; - } - - /* Allocate New String */ - char* newstr = new char [maxlen]; - - /* Populate New String */ - int orig_i = 0; - int new_i = 0; - while(carray[orig_i]) - { - /* For Each Possible Replacement */ - bool replacement = false; - for(int r = 0; r < num_replacements; r++) - { - /* Check for Match */ - int j = orig_i; - int k = 0; - while(carray[j] && oldtxt[r][k] && (carray[j] == oldtxt[r][k])) - { - j++; - k++; - } - - /* Replace Matched Text */ - if(oldtxt[r][k] == '\0') - { - int i = 0; - while(newtxt[r][i]) - { - newstr[new_i++] = newtxt[r][i++]; - } - orig_i = j; - replacement = true; - break; - } - } - - /* Copy Over and Advance String Indices */ - if(!replacement) - { - newstr[new_i++] = carray[orig_i++]; - } - } - - /* Terminate New String and Replace Existing String */ - newstr[new_i] = '\0'; - delete [] carray; - carray = newstr; - - return true; -} - -/*---------------------------------------------------------------------------- - * urlize - * - * ! # $ & ' ( ) * + - * %21 %23 %24 %26 %27 %28 %29 %2A %2B - * - * , / : ; = ? @ [ ] - * %2C %2F %3A %3B %3D %3F %40 %5B %5D - *----------------------------------------------------------------------------*/ -SafeString& SafeString::urlize(void) -{ - /* Allocate enough room to hold urlized string */ - if(maxlen < (len * 3)) - { - maxlen = len * 3; - } - - /* Setup pointers to new and old strings */ - char* alloc_str = new char [maxlen]; - char* new_str = alloc_str; - char* old_str = carray; - - /* Translate old string into new string */ - while(*old_str != '\0') - { - switch (*old_str) - { - case '!': *(new_str++) = '%'; *(new_str++) = '2'; *(new_str++) = '1'; break; - case '#': *(new_str++) = '%'; *(new_str++) = '2'; *(new_str++) = '3'; break; - case '$': *(new_str++) = '%'; *(new_str++) = '2'; *(new_str++) = '4'; break; - case '&': *(new_str++) = '%'; *(new_str++) = '2'; *(new_str++) = '6'; break; - case '\'': *(new_str++) = '%'; *(new_str++) = '2'; *(new_str++) = '7'; break; - case '(': *(new_str++) = '%'; *(new_str++) = '2'; *(new_str++) = '8'; break; - case ')': *(new_str++) = '%'; *(new_str++) = '2'; *(new_str++) = '9'; break; - case '*': *(new_str++) = '%'; *(new_str++) = '2'; *(new_str++) = 'A'; break; - case '+': *(new_str++) = '%'; *(new_str++) = '2'; *(new_str++) = 'B'; break; - case ',': *(new_str++) = '%'; *(new_str++) = '2'; *(new_str++) = 'C'; break; - case '/': *(new_str++) = '%'; *(new_str++) = '2'; *(new_str++) = 'F'; break; - case ':': *(new_str++) = '%'; *(new_str++) = '3'; *(new_str++) = 'A'; break; - case ';': *(new_str++) = '%'; *(new_str++) = '3'; *(new_str++) = 'B'; break; - case '=': *(new_str++) = '%'; *(new_str++) = '3'; *(new_str++) = 'D'; break; - case '?': *(new_str++) = '%'; *(new_str++) = '3'; *(new_str++) = 'F'; break; - case '@': *(new_str++) = '%'; *(new_str++) = '4'; *(new_str++) = '0'; break; - case '[': *(new_str++) = '%'; *(new_str++) = '5'; *(new_str++) = 'B'; break; - case ']': *(new_str++) = '%'; *(new_str++) = '5'; *(new_str++) = 'D'; break; - default: *(new_str++) = *old_str; break; - } - old_str++; - } - *(new_str++) = '\0'; - - /* Calculate length of new string */ - len = new_str - alloc_str; - - /* Replace member string */ - delete [] carray; - carray = alloc_str; - - /* Return Self */ - return *this; -} - -/*---------------------------------------------------------------------------- - * split - *----------------------------------------------------------------------------*/ -List* SafeString::split(char separator, bool strip) -{ - List* tokens = new List; - - int i = 0; - while(i < length() && carray[i] != '\0') - { - char token[MAX_STR_SIZE]; - int t = 0; - - /* Create Token */ - while( (i < length()) && (carray[i] != '\0') && (carray[i] == separator) ) i++; // find first character - while( (i < length()) && (carray[i] != '\0') && (carray[i] != separator) && (t < (MAX_STR_SIZE - 1))) token[t++] = carray[i++]; // copy characters in - token[t++] = '\0'; - - /* Strip Leading and Trailing Spaces */ - int s1 = 0; - if(strip) - { - int s2 = t-1; - while( (s1 < t) && isspace(token[s1]) ) s1++; - while( (s2 > s1) && isspace(token[s2]) ) s2--; - token[++s2] = '\0'; - } - - /* Add Token to List */ - if(t > 1) - { - string* s = new string(&token[s1]); - tokens->add(s); - } - } - - return tokens; -} - -/*---------------------------------------------------------------------------- - * operator[] - *----------------------------------------------------------------------------*/ -char SafeString::operator[](int index) -{ - if(index >= 0 && index < len) - { - return carray[index]; - } - - return '\0'; -} - -/*---------------------------------------------------------------------------- - * operator+= - *----------------------------------------------------------------------------*/ -SafeString& SafeString::operator+=(const SafeString& rhs) -{ - if((len + rhs.len) < (maxlen - 1)) - { - StringLib::concat(carray, rhs.carray, maxlen); - len += rhs.len; - } - else - { - maxlen += rhs.maxlen; - char* new_str = new char[maxlen]; - memset(new_str, 0, maxlen); - StringLib::copy(new_str, carray, maxlen); - StringLib::concat(new_str, rhs.carray, maxlen); - len = (int)strlen(new_str) + 1; - delete [] carray; - carray = new_str; - } - - return *this; -} - -/*---------------------------------------------------------------------------- - * operator+= - *----------------------------------------------------------------------------*/ -SafeString& SafeString::operator+=(const char* rstr) -{ - int rlen = (int)strlen(rstr); - - if((len + rlen) < (maxlen - 1)) - { - StringLib::concat(carray, rstr, maxlen); - len += rlen; - } - else - { - maxlen += rlen + 1; - maxlen *= 2; // optimization - char* new_str = new char[maxlen]; - memset(new_str, 0, maxlen); - StringLib::copy(new_str, carray, maxlen); - StringLib::concat(new_str, rstr, maxlen); - len = (int)strlen(new_str) + 1; - delete [] carray; - carray = new_str; - } - - return *this; -} - -/*---------------------------------------------------------------------------- - * operator= - *----------------------------------------------------------------------------*/ -StringLib::String& SafeString::operator=(const SafeString& rhs) -{ - if(maxlen < rhs.len) - { - delete [] carray; - maxlen = rhs.maxlen; - carray = new char[maxlen]; - } - - StringLib::copy(carray, rhs.carray, rhs.len); - len = rhs.len; - - return *this; -} - -/*---------------------------------------------------------------------------- - * operator= - *----------------------------------------------------------------------------*/ -StringLib::String& SafeString::operator=(const char* rstr) -{ - if(rstr) - { - int rlen = (int)strlen(rstr); - if(rlen <= 0) - { - carray[0] = '\0'; - len = 1; - } - else if(maxlen < rlen) - { - delete [] carray; - maxlen = rlen; - carray = new char[maxlen]; - } - - StringLib::copy(carray, rstr, rlen); - len = rlen + 1; - } - else - { - delete [] carray; - maxlen = DEFAULT_STR_SIZE; - carray = new char[maxlen]; - memset(carray, 0, maxlen); - len = 1; - } - - return *this; -} - -/*---------------------------------------------------------------------------- - * operator+ - *----------------------------------------------------------------------------*/ -SafeString operator+(SafeString lhs, const SafeString& rhs) -{ - lhs += rhs; - return lhs; -} - -/*---------------------------------------------------------------------------- - * reset - *----------------------------------------------------------------------------*/ -void SafeString::reset(void) -{ - delete [] carray; - maxlen = DEFAULT_STR_SIZE; - carray = new char[maxlen]; - memset(carray, 0, maxlen); - len = 1; -} - - /****************************************************************************** * PUBLIC METHODS ******************************************************************************/ diff --git a/packages/core/StringLib.h b/packages/core/StringLib.h index 69a3b4ca9..f77c8e851 100644 --- a/packages/core/StringLib.h +++ b/packages/core/StringLib.h @@ -47,48 +47,6 @@ class StringLib { public: - /*-------------------------------------------------------------------- - * String (subclass) - *--------------------------------------------------------------------*/ - - class String - { - public: - - static const long DEFAULT_STR_SIZE = 64; - static const int MAX_REPLACEMENTS = 16; - - String (long _maxlen=DEFAULT_STR_SIZE); - String (long _maxlen, const char* _str, ...) VARG_CHECK(printf, 3, 4); - explicit String (const char* _str); - String (const String& other); - String (int base, unsigned char* buffer, int size); - ~String (void); - - const char* str (bool duplicate = false); - long length (void) const; - long bytes (void) const; - void appendChar (char c); - int findChar (char c, int start=0); - String& setChar (char c, int index); - bool replace (const char* oldtxt, const char* newtxt); - bool inreplace (const char* oldtxt[], const char* newtxt[], int num_replacements); - String& urlize (void); - List* split (char separator, bool strip=true); - char operator[] (int index); - String& operator+= (const String& rhs); - String& operator+= (const char* rstr); - String& operator= (const String& rhs); - String& operator= (const char* rstr); - void reset (void); - - private: - - char* carray; - long len; - long maxlen; - }; - class FormattedString { public: @@ -105,8 +63,6 @@ class StringLib char* carray; long bufsize; }; - - static const int MAX_NUM_REPLACEMENTS = 16; /*-------------------------------------------------------------------- * Methods @@ -151,6 +107,7 @@ class StringLib * Constants *--------------------------------------------------------------------*/ + static const int MAX_NUM_REPLACEMENTS = 16; static const char* B64CHARS; static const int B64INDEX[256]; }; @@ -160,7 +117,5 @@ class StringLib *----------------------------------------------------------------------------*/ typedef StringLib::FormattedString FString; -typedef StringLib::String SafeString; -SafeString operator+ (SafeString lhs, const SafeString& rhs); #endif /* __string_lib__ */ diff --git a/packages/legacy/UT_String.cpp b/packages/legacy/UT_String.cpp index 4e47b7334..78511990e 100644 --- a/packages/legacy/UT_String.cpp +++ b/packages/legacy/UT_String.cpp @@ -137,21 +137,20 @@ int UT_String::testReplace(int argc, char argv[][MAX_CMD_SIZE]) failures = 0; // 1) Replace Single Character - SafeString test1("Hello World"); - test1.replace("o", "X"); - ut_assert(StringLib::match(test1.str(), "HellX WXrld"), "Failed single character test: %s", test1.str()); - + char* test1 = StringLib::replace("Hello World", "o", "X"); + ut_assert(StringLib::match(test1, "HellX WXrld"), "Failed single character test: %s", test1); + delete [] test1; // 2) Replace String - SafeString test2("Hello World"); - test2.replace("ello", "eal"); - ut_assert(StringLib::match(test2.str(), "Heal World"), "Failed to replace string: %s", test2.str()); + char* test2 = StringLib::replace("Hello World", "ello", "eal"); + ut_assert(StringLib::match(test2, "Heal World"), "Failed to replace string: %s", test2); + delete [] test2; // 3) Replace Strings - SafeString test3("This is a long $1 and I am $2 sure if this $1 will work or $2"); const char* oldtxt[2] = { "$1", "$2" }; const char* newtxt[2] = { "sentence", "not" }; - test3.inreplace(oldtxt, newtxt, 2); - ut_assert(StringLib::match(test3.str(), "This is a long sentence and I am not sure if this sentence will work or not"), "Failed multiple replacements: %s", test3.str()); + char* test3 = StringLib::replace("This is a long $1 and I am $2 sure if this $1 will work or $2", oldtxt, newtxt, 2); + ut_assert(StringLib::match(test3, "This is a long sentence and I am not sure if this sentence will work or not"), "Failed multiple replacements: %s", test3); + delete test3; // return success or failure return failures == 0 ? 0 : -1; diff --git a/plugins/atlas/CMakeLists.txt b/plugins/atlas/CMakeLists.txt index 659a9a8b1..0fb2bf166 100644 --- a/plugins/atlas/CMakeLists.txt +++ b/plugins/atlas/CMakeLists.txt @@ -38,6 +38,7 @@ target_sources(atlas ${CMAKE_CURRENT_LIST_DIR}/plugin/CmdEchoProcessorModule.cpp ${CMAKE_CURRENT_LIST_DIR}/plugin/DiagLogProcessorModule.cpp ${CMAKE_CURRENT_LIST_DIR}/plugin/HstvsSimulator.cpp + ${CMAKE_CURRENT_LIST_DIR}/plugin/SafeString.cpp ) # Include Directories # diff --git a/plugins/atlas/plugin/SafeString.cpp b/plugins/atlas/plugin/SafeString.cpp new file mode 100644 index 000000000..16cca4a49 --- /dev/null +++ b/plugins/atlas/plugin/SafeString.cpp @@ -0,0 +1,619 @@ +/* + * Copyright (c) 2021, University of Washington + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. Neither the name of the University of Washington nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE UNIVERSITY OF WASHINGTON AND CONTRIBUTORS + * “AS IS” AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE UNIVERSITY OF WASHINGTON OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/****************************************************************************** + * INCLUDES + ******************************************************************************/ + +#include "SafeString.h" +#include "StringLib.h" +#include "OsApi.h" + +#include +#include +#include + + +/****************************************************************************** + * SAFE STRING PUBLIC METHODS + ******************************************************************************/ + +/*---------------------------------------------------------------------------- + * Constructor + *----------------------------------------------------------------------------*/ +SafeString::SafeString(long _maxlen) +{ + if(_maxlen <= 0) maxlen = DEFAULT_STR_SIZE; + else maxlen = _maxlen; + carray = new char[maxlen]; + carray[0] ='\0'; + len = 1; +} + +/*---------------------------------------------------------------------------- + * Constructor + *----------------------------------------------------------------------------*/ +SafeString::SafeString(long _maxlen, const char* _str, ...) +{ + if(_str != NULL) + { + va_list args; + va_start(args, _str); + len = vsnprintf(NULL, _maxlen, _str, args) + 1; // get length + va_end(args); + carray = new char[len]; // allocate memory + maxlen = len; + va_start(args, _str); + vsprintf(carray, _str, args); // copy in formatted contents + va_end(args); + carray[maxlen - 1] ='\0'; // null terminate + } + else + { + maxlen = DEFAULT_STR_SIZE; + carray = new char[maxlen]; + carray[0] = '\0'; + len = 1; + } +} + +/*---------------------------------------------------------------------------- + * Constructor + *----------------------------------------------------------------------------*/ +SafeString::SafeString(const char* _str) +{ + maxlen = strlen(_str) + 1; + carray = new char[maxlen]; + len = maxlen; + StringLib::copy(carray, _str, len); + carray[len - 1] = '\0'; +} + +/*---------------------------------------------------------------------------- + * Constructor (COPY) + *----------------------------------------------------------------------------*/ +SafeString::SafeString(const SafeString& other) +{ + maxlen = other.maxlen; + carray = new char[maxlen]; + len = other.len; + StringLib::copy(carray, other.carray, len); + carray[len - 1] = '\0'; +} + +/*---------------------------------------------------------------------------- + * Constructor (ENCODE) + *----------------------------------------------------------------------------*/ +SafeString::SafeString (int base, unsigned char* buffer, int size) +{ + if(base == 64) + { + int encoded_len = size; + carray = StringLib::b64encode(buffer, &encoded_len); + maxlen = encoded_len; + len = encoded_len; + } + else + { + maxlen = DEFAULT_STR_SIZE; + carray = new char[maxlen]; + memset(carray, 0, maxlen); + len = 1; + } +} + +/*---------------------------------------------------------------------------- + * Destructor + *----------------------------------------------------------------------------*/ +SafeString::~SafeString(void) +{ + delete [] carray; +} + +/*---------------------------------------------------------------------------- + * getString + *----------------------------------------------------------------------------*/ +const char* SafeString::str(bool duplicate) +{ + if(duplicate) + { + char* new_str = new char[len]; + StringLib::copy(new_str, carray, len); + return new_str; + } + + return carray; +} + +/*---------------------------------------------------------------------------- + * length - number of non-null characters in string + *----------------------------------------------------------------------------*/ +long SafeString::length(void) const +{ + return len - 1; // remove null terminator in length +} + +/*---------------------------------------------------------------------------- + * bytes - size of memory needed to store string (includes null terminator) + *----------------------------------------------------------------------------*/ +long SafeString::bytes(void) const +{ + return len; +} + +/*---------------------------------------------------------------------------- + * appendChar + *----------------------------------------------------------------------------*/ +void SafeString::appendChar(char c) +{ + if(len >= maxlen) + { + maxlen *= 2; // optimization + char* new_str = new char[maxlen]; + memset(new_str, 0, maxlen); + StringLib::copy(new_str, carray, len); + delete [] carray; + carray = new_str; + } + + carray[len-1] = c; + carray[len] = '\0'; + len++; +} + +/*---------------------------------------------------------------------------- + * findChar + *----------------------------------------------------------------------------*/ +int SafeString::findChar (char c, int start) +{ + if(start >= 0) + { + for(int i = start; i < len; i++) + { + if(carray[i] == c) + { + return i; + } + } + } + + return -1; +} + +/*---------------------------------------------------------------------------- + * setChar + *----------------------------------------------------------------------------*/ +SafeString& SafeString::setChar (char c, int index) +{ + if(index >= 0 && index < len) + { + carray[index] = c; + } + return *this; +} + +/*---------------------------------------------------------------------------- + * replace + * + * replaces all occurrences + *----------------------------------------------------------------------------*/ +bool SafeString::replace(const char* oldtxt, const char* newtxt) +{ + bool status = false; + + int newtxtlen = (int)strlen(newtxt); + char* startptr = strstr(carray, oldtxt); + char* endptr = startptr + strlen(oldtxt); + + while(startptr != NULL) + { + status = true; + + maxlen += newtxtlen; + char* newstr = new char[maxlen]; + memset(newstr, 0, maxlen); + + memcpy(newstr, carray, (startptr - carray)); + memcpy(newstr + (startptr - carray), newtxt, newtxtlen); + memcpy(newstr + (startptr - carray) + newtxtlen, endptr, len - (endptr - carray)); + + delete [] carray; + carray = newstr; + + len = (int)strlen(carray) + 1; + + startptr = strstr(carray, oldtxt); + endptr = startptr + strlen(oldtxt); + } + + return status; +} + +/*---------------------------------------------------------------------------- + * inreplace + * + * replaces all occurrences in place + *----------------------------------------------------------------------------*/ +bool SafeString::inreplace (const char* oldtxt[], const char* newtxt[], int num_replacements) +{ + /* Check Number of Replacements */ + if(num_replacements > MAX_REPLACEMENTS) + { + return false; + } + + /* Get Delta Sizes for each Replacement */ + int replacement_size_delta[MAX_REPLACEMENTS]; + for(int r = 0; r < num_replacements; r++) + { + replacement_size_delta[r] = strlen(newtxt[r]) - strlen(oldtxt[r]); + } + + /* Count Number of Replacements */ + int replacement_count[MAX_REPLACEMENTS]; + for(int r = 0; r < num_replacements; r++) + { + replacement_count[r] = 0; + int i = 0; + while(i < (len - 1)) + { + int j = i; + int k = 0; + while((j < (len - 1)) && oldtxt[r][k] && (carray[j] == oldtxt[r][k])) + { + j++; + k++; + } + + if(oldtxt[r][k] == '\0') + { + replacement_count[r]++; + i = j; + } + else + { + i++; + } + } + } + + /* Calculate Size of New String */ + int total_size_delta = 0; + for(int r = 0; r < num_replacements; r++) + { + total_size_delta += replacement_size_delta[r] * replacement_count[r]; + } + + /* Set New Size */ + int new_size = len + total_size_delta; + if(new_size > 0) + { + len = new_size; + maxlen = new_size; + } + else + { + len = 1; + maxlen = 1; + carray[0] = '\0'; + return true; + } + + /* Allocate New String */ + char* newstr = new char [maxlen]; + + /* Populate New String */ + int orig_i = 0; + int new_i = 0; + while(carray[orig_i]) + { + /* For Each Possible Replacement */ + bool replacement = false; + for(int r = 0; r < num_replacements; r++) + { + /* Check for Match */ + int j = orig_i; + int k = 0; + while(carray[j] && oldtxt[r][k] && (carray[j] == oldtxt[r][k])) + { + j++; + k++; + } + + /* Replace Matched Text */ + if(oldtxt[r][k] == '\0') + { + int i = 0; + while(newtxt[r][i]) + { + newstr[new_i++] = newtxt[r][i++]; + } + orig_i = j; + replacement = true; + break; + } + } + + /* Copy Over and Advance String Indices */ + if(!replacement) + { + newstr[new_i++] = carray[orig_i++]; + } + } + + /* Terminate New String and Replace Existing String */ + newstr[new_i] = '\0'; + delete [] carray; + carray = newstr; + + return true; +} + +/*---------------------------------------------------------------------------- + * urlize + * + * ! # $ & ' ( ) * + + * %21 %23 %24 %26 %27 %28 %29 %2A %2B + * + * , / : ; = ? @ [ ] + * %2C %2F %3A %3B %3D %3F %40 %5B %5D + *----------------------------------------------------------------------------*/ +SafeString& SafeString::urlize(void) +{ + /* Allocate enough room to hold urlized string */ + if(maxlen < (len * 3)) + { + maxlen = len * 3; + } + + /* Setup pointers to new and old strings */ + char* alloc_str = new char [maxlen]; + char* new_str = alloc_str; + char* old_str = carray; + + /* Translate old string into new string */ + while(*old_str != '\0') + { + switch (*old_str) + { + case '!': *(new_str++) = '%'; *(new_str++) = '2'; *(new_str++) = '1'; break; + case '#': *(new_str++) = '%'; *(new_str++) = '2'; *(new_str++) = '3'; break; + case '$': *(new_str++) = '%'; *(new_str++) = '2'; *(new_str++) = '4'; break; + case '&': *(new_str++) = '%'; *(new_str++) = '2'; *(new_str++) = '6'; break; + case '\'': *(new_str++) = '%'; *(new_str++) = '2'; *(new_str++) = '7'; break; + case '(': *(new_str++) = '%'; *(new_str++) = '2'; *(new_str++) = '8'; break; + case ')': *(new_str++) = '%'; *(new_str++) = '2'; *(new_str++) = '9'; break; + case '*': *(new_str++) = '%'; *(new_str++) = '2'; *(new_str++) = 'A'; break; + case '+': *(new_str++) = '%'; *(new_str++) = '2'; *(new_str++) = 'B'; break; + case ',': *(new_str++) = '%'; *(new_str++) = '2'; *(new_str++) = 'C'; break; + case '/': *(new_str++) = '%'; *(new_str++) = '2'; *(new_str++) = 'F'; break; + case ':': *(new_str++) = '%'; *(new_str++) = '3'; *(new_str++) = 'A'; break; + case ';': *(new_str++) = '%'; *(new_str++) = '3'; *(new_str++) = 'B'; break; + case '=': *(new_str++) = '%'; *(new_str++) = '3'; *(new_str++) = 'D'; break; + case '?': *(new_str++) = '%'; *(new_str++) = '3'; *(new_str++) = 'F'; break; + case '@': *(new_str++) = '%'; *(new_str++) = '4'; *(new_str++) = '0'; break; + case '[': *(new_str++) = '%'; *(new_str++) = '5'; *(new_str++) = 'B'; break; + case ']': *(new_str++) = '%'; *(new_str++) = '5'; *(new_str++) = 'D'; break; + default: *(new_str++) = *old_str; break; + } + old_str++; + } + *(new_str++) = '\0'; + + /* Calculate length of new string */ + len = new_str - alloc_str; + + /* Replace member string */ + delete [] carray; + carray = alloc_str; + + /* Return Self */ + return *this; +} + +/*---------------------------------------------------------------------------- + * split + *----------------------------------------------------------------------------*/ +List* SafeString::split(char separator, bool strip) +{ + List* tokens = new List; + + int i = 0; + while(i < length() && carray[i] != '\0') + { + char token[MAX_STR_SIZE]; + int t = 0; + + /* Create Token */ + while( (i < length()) && (carray[i] != '\0') && (carray[i] == separator) ) i++; // find first character + while( (i < length()) && (carray[i] != '\0') && (carray[i] != separator) && (t < (MAX_STR_SIZE - 1))) token[t++] = carray[i++]; // copy characters in + token[t++] = '\0'; + + /* Strip Leading and Trailing Spaces */ + int s1 = 0; + if(strip) + { + int s2 = t-1; + while( (s1 < t) && isspace(token[s1]) ) s1++; + while( (s2 > s1) && isspace(token[s2]) ) s2--; + token[++s2] = '\0'; + } + + /* Add Token to List */ + if(t > 1) + { + string* s = new string(&token[s1]); + tokens->add(s); + } + } + + return tokens; +} + +/*---------------------------------------------------------------------------- + * operator[] + *----------------------------------------------------------------------------*/ +char SafeString::operator[](int index) +{ + if(index >= 0 && index < len) + { + return carray[index]; + } + + return '\0'; +} + +/*---------------------------------------------------------------------------- + * operator+= + *----------------------------------------------------------------------------*/ +SafeString& SafeString::operator+=(const SafeString& rhs) +{ + if((len + rhs.len) < (maxlen - 1)) + { + StringLib::concat(carray, rhs.carray, maxlen); + len += rhs.len; + } + else + { + maxlen += rhs.maxlen; + char* new_str = new char[maxlen]; + memset(new_str, 0, maxlen); + StringLib::copy(new_str, carray, maxlen); + StringLib::concat(new_str, rhs.carray, maxlen); + len = (int)strlen(new_str) + 1; + delete [] carray; + carray = new_str; + } + + return *this; +} + +/*---------------------------------------------------------------------------- + * operator+= + *----------------------------------------------------------------------------*/ +SafeString& SafeString::operator+=(const char* rstr) +{ + int rlen = (int)strlen(rstr); + + if((len + rlen) < (maxlen - 1)) + { + StringLib::concat(carray, rstr, maxlen); + len += rlen; + } + else + { + maxlen += rlen + 1; + maxlen *= 2; // optimization + char* new_str = new char[maxlen]; + memset(new_str, 0, maxlen); + StringLib::copy(new_str, carray, maxlen); + StringLib::concat(new_str, rstr, maxlen); + len = (int)strlen(new_str) + 1; + delete [] carray; + carray = new_str; + } + + return *this; +} + +/*---------------------------------------------------------------------------- + * operator= + *----------------------------------------------------------------------------*/ +SafeString& SafeString::operator=(const SafeString& rhs) +{ + if(maxlen < rhs.len) + { + delete [] carray; + maxlen = rhs.maxlen; + carray = new char[maxlen]; + } + + StringLib::copy(carray, rhs.carray, rhs.len); + len = rhs.len; + + return *this; +} + +/*---------------------------------------------------------------------------- + * operator= + *----------------------------------------------------------------------------*/ +SafeString& SafeString::operator=(const char* rstr) +{ + if(rstr) + { + int rlen = (int)strlen(rstr); + if(rlen <= 0) + { + carray[0] = '\0'; + len = 1; + } + else if(maxlen < rlen) + { + delete [] carray; + maxlen = rlen; + carray = new char[maxlen]; + } + + StringLib::copy(carray, rstr, rlen); + len = rlen + 1; + } + else + { + delete [] carray; + maxlen = DEFAULT_STR_SIZE; + carray = new char[maxlen]; + memset(carray, 0, maxlen); + len = 1; + } + + return *this; +} + +/*---------------------------------------------------------------------------- + * operator+ + *----------------------------------------------------------------------------*/ +SafeString operator+(SafeString lhs, const SafeString& rhs) +{ + lhs += rhs; + return lhs; +} + +/*---------------------------------------------------------------------------- + * reset + *----------------------------------------------------------------------------*/ +void SafeString::reset(void) +{ + delete [] carray; + maxlen = DEFAULT_STR_SIZE; + carray = new char[maxlen]; + memset(carray, 0, maxlen); + len = 1; +} diff --git a/plugins/atlas/plugin/SafeString.h b/plugins/atlas/plugin/SafeString.h new file mode 100644 index 000000000..8a288b673 --- /dev/null +++ b/plugins/atlas/plugin/SafeString.h @@ -0,0 +1,84 @@ +/* + * Copyright (c) 2021, University of Washington + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. Neither the name of the University of Washington nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE UNIVERSITY OF WASHINGTON AND CONTRIBUTORS + * “AS IS” AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE UNIVERSITY OF WASHINGTON OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef __safe_string__ +#define __safe_string__ + +/****************************************************************************** + * INCLUDES + ******************************************************************************/ + +#include "OsApi.h" +#include "List.h" + +/****************************************************************************** + * SAFE STRING CLASS + ******************************************************************************/ + +class SafeString +{ + public: + + static const long DEFAULT_STR_SIZE = 64; + static const int MAX_REPLACEMENTS = 16; + + SafeString (long _maxlen=DEFAULT_STR_SIZE); + SafeString (long _maxlen, const char* _str, ...) VARG_CHECK(printf, 3, 4); + explicit SafeString (const char* _str); + SafeString (const SafeString& other); + SafeString (int base, unsigned char* buffer, int size); + ~SafeString (void); + + const char* str (bool duplicate = false); + long length (void) const; + long bytes (void) const; + void appendChar (char c); + int findChar (char c, int start=0); + SafeString& setChar (char c, int index); + bool replace (const char* oldtxt, const char* newtxt); + bool inreplace (const char* oldtxt[], const char* newtxt[], int num_replacements); + SafeString& urlize (void); + List* split (char separator, bool strip=true); + char operator[] (int index); + SafeString& operator+= (const SafeString& rhs); + SafeString& operator+= (const char* rstr); + SafeString& operator= (const SafeString& rhs); + SafeString& operator= (const char* rstr); + void reset (void); + + private: + + char* carray; + long len; + long maxlen; +}; + +#endif /* __string_lib__ */ diff --git a/plugins/atlas/plugin/atlas.h b/plugins/atlas/plugin/atlas.h index b1d4ea188..1307af2e0 100644 --- a/plugins/atlas/plugin/atlas.h +++ b/plugins/atlas/plugin/atlas.h @@ -56,6 +56,7 @@ #include "CmdEchoProcessorModule.h" #include "DiagLogProcessorModule.h" #include "HstvsSimulator.h" +#include "SafeString.h" /****************************************************************************** * PROTOTYPES