diff options
author | Dimitri van Heesch <dimitri@stack.nl> | 2015-01-02 08:56:45 (GMT) |
---|---|---|
committer | Dimitri van Heesch <dimitri@stack.nl> | 2015-01-02 09:45:18 (GMT) |
commit | 312bef563a5be72f6423377247db1b80044bf711 (patch) | |
tree | 3a656445fa67469b2f1783932fe127e9f39af69a /qtools/qcstring.h | |
parent | ed39dab59f8af2c5b42cfac0b3140cf594412121 (diff) | |
download | Doxygen-312bef563a5be72f6423377247db1b80044bf711.zip Doxygen-312bef563a5be72f6423377247db1b80044bf711.tar.gz Doxygen-312bef563a5be72f6423377247db1b80044bf711.tar.bz2 |
Fixed a couple of cases where sharing string data could lead to corruption
Also made dangerous string access more visible by introducing rawData().
This replaces data() which will now return a constant string.
Diffstat (limited to 'qtools/qcstring.h')
-rw-r--r-- | qtools/qcstring.h | 50 |
1 files changed, 34 insertions, 16 deletions
diff --git a/qtools/qcstring.h b/qtools/qcstring.h index bc3a091..8854aa7 100644 --- a/qtools/qcstring.h +++ b/qtools/qcstring.h @@ -204,11 +204,20 @@ public: } /** Returns a pointer to the contents of the string in the form of a 0-terminated C string */ - char *data() const + const char *data() const { return m_rep.data(); } + /** Returns a writable pointer to the data. + * @warning if the string is shared it will modifying the string directly and + * this will overwrite all copies as well! + */ + char *rawData() const + { + return m_rep.rawData(); + } + /** Resizes the string to hold \a newlen characters * (this value should include the 0-terminator). If the string is enlarged the contents will * be left unmodified. @@ -242,7 +251,7 @@ public: { if (length()==0) return QCString(); QCString cs(length()+1); - memcpy(cs.data(),data(),length()); + memcpy(cs.rawData(),data(),length()); return cs; } @@ -299,7 +308,7 @@ public: int len1 = length(); int len2 = (int)strlen(str); resize(len1+len2+1); - memcpy(data()+len1,str,len2); + memcpy(rawData()+len1,str,len2); return *this; } @@ -308,7 +317,7 @@ public: { int len = length(); resize(len+2); - data()[len]=c; + rawData()[len]=c; return *this; } @@ -568,9 +577,21 @@ public: } uint length() const { - return u.s.isShort ? u.s.len : u.l.d->len; + uint l = u.s.isShort ? u.s.len : u.l.d->len; + return l; } - char *data() const + const char *data() const + { + if (u.s.isShort) + { + return u.s.len==0 ? 0 : u.s.str; + } + else + { + return u.l.d->len==0 ? 0 : u.l.d->toStr(); + } + } + char *rawData() const { if (u.s.isShort) { @@ -578,6 +599,7 @@ public: } else { + //assert(u.l.d->refCount==0); // string may not be shared when accessed raw return u.l.d->len==0 ? 0 : u.l.d->toStr(); } } @@ -645,24 +667,20 @@ public: bool fill( char c, int len ) { if (len<0) len=length(); - if (len!=(int)length()) + if (!u.s.isShort) // detach from shared string + { + resize(len+1); + } + else if (len!=(int)length()) { if (len>0) { resize(len+1); } - else - { - if (!u.s.isShort) - { - u.l.d->dispose(); - } - initEmpty(); - } } if (len>0) { - memset(data(),c,len); + memset(rawData(),c,len); } return TRUE; } |