summaryrefslogtreecommitdiffstats
path: root/qtools/qcstring.h
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/qcstring.h
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/qcstring.h')
-rw-r--r--qtools/qcstring.h50
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;
}