Permalink
Browse files

Fixed a couple of cases where sharing string data could lead to corru…

…ption

Also made dangerous string access more visible by introducing rawData().
This replaces data() which will now return a constant string.
  • Loading branch information...
Dimitri van Heesch
Dimitri van Heesch committed Jan 2, 2015
1 parent ed39dab commit 312bef563a5be72f6423377247db1b80044bf711
View
@@ -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;
}
View
@@ -204,11 +204,20 @@ class QCString
}
/** 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 @@ class QCString
{
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 @@ class QCString
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 @@ class QCString
{
int len = length();
resize(len+2);
data()[len]=c;
rawData()[len]=c;
return *this;
}
@@ -568,16 +577,29 @@ class QCString
}
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)
{
return u.s.len==0 ? 0 : (char*)u.s.str;
}
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 @@ class QCString
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;
}
View
@@ -1192,7 +1192,7 @@ class QTextCodecFromIOD : public QTextCodec {
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-- )
View
@@ -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;
}
View
@@ -203,14 +203,14 @@ class QUtf16Encoder : public QTextEncoder {
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;
}
}
View
@@ -211,7 +211,7 @@ void CiteDict::generatePage() const
QCString doc;
QFileInfo fi(citeListFile);
QCString input(fi.size()+1);
f.readBlock(input.data(),fi.size());
f.readBlock(input.rawData(),fi.size());
f.close();
input.at(fi.size())='\0';
int p=0,s;
View
@@ -85,7 +85,7 @@ static QCString convertToComment(const QCString &s, const QCString &u)
if (!s.isEmpty())
{
QCString tmp=s.stripWhiteSpace();
char *p=tmp.data();
const char *p=tmp.data();
char c;
result+="#";
if (*p && *p!='\n')
@@ -495,8 +495,8 @@ static QCString configStringRecode(
}
size_t iLeft=(size_t)inputSize;
size_t oLeft=(size_t)outputSize;
char *inputPtr = str.data();
char *outputPtr = output.data();
char *inputPtr = str.rawData();
char *outputPtr = output.rawData();
if (!portable_iconv(cd, &inputPtr, &iLeft, &outputPtr, &oLeft))
{
outputSize-=(int)oLeft;
@@ -1695,7 +1695,7 @@ static QCString configFileToString(const char *name)
QCString contents(bSize);
int totalSize=0;
int size;
while ((size=f.readBlock(contents.data()+totalSize,bSize))==bSize)
while ((size=f.readBlock(contents.rawData()+totalSize,bSize))==bSize)
{
totalSize+=bSize;
contents.resize(totalSize+bSize);
@@ -1721,7 +1721,7 @@ static QCString configFileToString(const char *name)
{
int fsize=f.size();
QCString contents(fsize+2);
f.readBlock(contents.data(),fsize);
f.readBlock(contents.rawData(),fsize);
f.close();
if (fsize==0 || contents[fsize-1]=='\n')
contents[fsize]='\0';
View
@@ -543,7 +543,7 @@ bool Definition::_docsAlreadyAdded(const QCString &doc,QCString &sigList)
// double whitespaces...
QCString docStr = doc.simplifyWhiteSpace();
MD5Buffer((const unsigned char *)docStr.data(),docStr.length(),md5_sig);
MD5SigToString(md5_sig,sigStr.data(),33);
MD5SigToString(md5_sig,sigStr.rawData(),33);
//printf("%s:_docsAlreadyAdded doc='%s' sig='%s' docSigs='%s'\n",
// name().data(),doc.data(),sigStr.data(),sigList.data());
if (sigList.find(sigStr)==-1) // new docs, add signature to prevent re-adding it
View
@@ -86,7 +86,7 @@ static QCString encodeDirName(const QCString &anchor)
uchar md5_sig[16];
QCString sigStr(33);
MD5Buffer((const unsigned char *)anchor.data(),anchor.length(),md5_sig);
MD5SigToString(md5_sig,sigStr.data(),33);
MD5SigToString(md5_sig,sigStr.rawData(),33);
return sigStr;
// old algorithm
Oops, something went wrong.

0 comments on commit 312bef5

Please sign in to comment.