summaryrefslogtreecommitdiffstats
path: root/qtools
diff options
context:
space:
mode:
authorDimitri van Heesch <dimitri@stack.nl>2015-01-02 08:56:45 (GMT)
committerDimitri van Heesch <dimitri@stack.nl>2015-01-02 09:45:18 (GMT)
commit312bef563a5be72f6423377247db1b80044bf711 (patch)
tree3a656445fa67469b2f1783932fe127e9f39af69a /qtools
parented39dab59f8af2c5b42cfac0b3140cf594412121 (diff)
downloadDoxygen-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')
-rw-r--r--qtools/qcstring.cpp48
-rw-r--r--qtools/qcstring.h50
-rw-r--r--qtools/qtextcodec.cpp4
-rw-r--r--qtools/qtextstream.cpp6
-rw-r--r--qtools/qutfcodec.cpp6
5 files changed, 66 insertions, 48 deletions
diff --git a/qtools/qcstring.cpp b/qtools/qcstring.cpp
index 49bf842..26df166 100644
--- a/qtools/qcstring.cpp
+++ b/qtools/qcstring.cpp
@@ -31,7 +31,7 @@ QCString &QCString::sprintf( const char *format, ... )
const int minlen=256;
int l = length();
if (l<minlen) { resize(minlen); l=minlen; }
- int n=vsnprintf( data(), l, format, ap);
+ int n=vsnprintf( rawData(), l, format, ap);
if (n<0) n=l;
resize(n+1);
va_end( ap );
@@ -62,7 +62,7 @@ int QCString::find( const char *str, int index, bool cs ) const
if (index<0 || index>=l) return -1; // index outside string
if (!str) return -1; // no string to search for
if (!*str) return index; // empty string matching at index
- register char *pos;
+ register const char *pos;
if (cs) // case sensitive
{
pos = strstr(data()+index,str);
@@ -132,7 +132,7 @@ int QCString::findRev( const char *str, int index, bool cs) const
else if (index>len) return -1; // bad index
else if (index+slen>len) index=len-slen; // str would be too long
if (index<0) return -1; // no match possible
- register char *pos = data()+index;
+ register const char *pos = data()+index;
if (cs) // case sensitive
{
for (int i=index; i>=0; i--) if (qstrncmp(pos--,str,slen)==0) return i;
@@ -204,9 +204,7 @@ bool QCString::stripPrefix(const char *prefix)
int len = qstrlen(prefix);
if (qstrncmp(prefix,data(),len)==0)
{
- int newlen = length()-len+1;
- qmemmove(data(),data()+len,newlen);
- resize(newlen);
+ m_rep=mid(len,length()-len).m_rep; // need to make a deep copy
return TRUE;
}
return FALSE;
@@ -225,7 +223,7 @@ QCString QCString::left( uint len ) const
else
{
QCString s( len+1 );
- memcpy( s.data(), data(), len);
+ memcpy( s.rawData(), data(), len);
return s;
}
}
@@ -255,9 +253,9 @@ QCString QCString::mid( uint index, uint len) const
}
else
{
- register char *p = data()+index;
+ register const char *p = data()+index;
QCString s(len+1);
- qstrncpy( s.data(), p, len+1 );
+ qstrncpy( s.rawData(), p, len+1 );
return s;
}
}
@@ -266,7 +264,7 @@ QCString QCString::lower() const
{
if (length()==0) return QCString();
QCString s(data());
- register char *pos = s.data();
+ register char *pos = s.rawData();
if (pos)
{
while (*pos)
@@ -282,7 +280,7 @@ QCString QCString::upper() const
{
if (length()==0) return QCString();
QCString s(data());
- register char *pos = s.data();
+ register char *pos = s.rawData();
if (pos)
{
while (*pos)
@@ -299,13 +297,13 @@ QCString QCString::stripWhiteSpace() const
if ( isEmpty() ) // nothing to do
return *this;
- register char *s = data();
+ register const char *cs = data();
int reslen = length();
- if ( !isspace((uchar)s[0]) && !isspace((uchar)s[reslen-1]) )
+ if ( !isspace((uchar)cs[0]) && !isspace((uchar)cs[reslen-1]) )
return *this; // returns a copy
- QCString result(s);
- s = result.data();
+ QCString result(cs);
+ register char *s = result.rawData();
int start = 0;
int end = reslen - 1;
while ( isspace((uchar) s[start]) ) // skip white space from start
@@ -317,7 +315,7 @@ QCString QCString::stripWhiteSpace() const
while ( end && isspace((uchar) s[end]) ) // skip white space from end
end--;
end -= start - 1;
- qmemmove( result.data(), &s[start], end );
+ qmemmove( s, &s[start], end );
result.resize( end + 1 );
return result;
}
@@ -328,8 +326,8 @@ QCString QCString::simplifyWhiteSpace() const
return *this;
QCString result( length()+1 );
- char *from = data();
- char *to = result.data();
+ const char *from = data();
+ char *to = result.rawData();
char *first = to;
while ( TRUE )
{
@@ -363,14 +361,14 @@ QCString &QCString::insert( uint index, const char *s )
if ((int)index>=olen)
{
resize(nlen+index-olen+1);
- memset(data()+olen, ' ', index-olen);
- memcpy(data()+index,s, len+1);
+ memset(rawData()+olen, ' ', index-olen);
+ memcpy(rawData()+index,s, len+1);
}
else
{
resize(nlen+1);
- qmemmove(data()+index+len,data()+index,olen-index+1);
- memcpy(data()+index,s,len);
+ qmemmove(rawData()+index+len,data()+index,olen-index+1);
+ memcpy(rawData()+index,s,len);
}
return *this;
}
@@ -402,8 +400,10 @@ QCString &QCString::remove( uint index, uint len )
}
else if ( len != 0 )
{
- qmemmove( data()+index, data()+index+len, olen-index-len+1 );
+ QCString tmp(olen-index-len+1);
+ qmemmove( tmp.rawData(), data()+index+len, olen-index-len+1 );
resize( olen-len+1 );
+ memcpy( rawData()+index,tmp.data(),tmp.length() );
}
return *this;
}
@@ -635,7 +635,7 @@ QDataStream &operator>>( QDataStream &s, QCString &str )
len = 0;
}
if ( len > 0 ) // not null array
- s.readRawBytes( str.data(), (uint)len );
+ s.readRawBytes( str.rawData(), (uint)len );
return s;
}
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;
}
diff --git a/qtools/qtextcodec.cpp b/qtools/qtextcodec.cpp
index 168445f..bd874bb 100644
--- a/qtools/qtextcodec.cpp
+++ b/qtools/qtextcodec.cpp
@@ -1192,7 +1192,7 @@ public:
lenInOut = uc.length();
int rlen = lenInOut*max_bytes_per_char;
QCString rstr(rlen);
- char* cursor = rstr.data();
+ char* cursor = rstr.rawData();
char* s=0;
int l = lenInOut;
int lout = 0;
@@ -1881,7 +1881,7 @@ QCString QSimpleTextCodec::fromUnicode(const QString& uc, int& len ) const
int i = len;
int u;
const QChar* ucp = uc.unicode();
- char* rp = r.data();
+ char* rp = r.rawData();
char* rmp = reverseMap->data();
int rmsize = (int) reverseMap->size();
while( i-- )
diff --git a/qtools/qtextstream.cpp b/qtools/qtextstream.cpp
index bae072d..4ebf59e 100644
--- a/qtools/qtextstream.cpp
+++ b/qtools/qtextstream.cpp
@@ -1443,17 +1443,17 @@ QTextStream &QTextStream::operator>>( QCString &str )
if ( i >= buflen-1 ) {
if ( !dynbuf ) { // create dynamic buffer
dynbuf = new QCString(buflen*2);
- memcpy( dynbuf->data(), s, i ); // copy old data
+ memcpy( dynbuf->rawData(), s, i ); // copy old data
} else if ( i >= (int)dynbuf->size()-1 ) {
dynbuf->resize( dynbuf->size()*2 );
}
- s = dynbuf->data();
+ s = dynbuf->rawData();
}
s[i++] = c;
c = ts_getc();
}
str.resize( i+1 );
- memcpy( str.data(), s, i );
+ memcpy( str.rawData(), s, i );
delete dynbuf;
return *this;
}
diff --git a/qtools/qutfcodec.cpp b/qtools/qutfcodec.cpp
index c7094ad..a37e37f 100644
--- a/qtools/qutfcodec.cpp
+++ b/qtools/qutfcodec.cpp
@@ -203,14 +203,14 @@ public:
if ( headerdone ) {
len_in_out = uc.length()*(int)sizeof(QChar);
QCString d(len_in_out);
- memcpy(d.data(),uc.unicode(),len_in_out);
+ memcpy(d.rawData(),uc.unicode(),len_in_out);
return d;
} else {
headerdone = TRUE;
len_in_out = (1+uc.length())*(int)sizeof(QChar);
QCString d(len_in_out);
- memcpy(d.data(),&QChar::byteOrderMark,sizeof(QChar));
- memcpy(d.data()+sizeof(QChar),uc.unicode(),uc.length()*sizeof(QChar));
+ memcpy(d.rawData(),&QChar::byteOrderMark,sizeof(QChar));
+ memcpy(d.rawData()+sizeof(QChar),uc.unicode(),uc.length()*sizeof(QChar));
return d;
}
}