summaryrefslogtreecommitdiffstats
path: root/qmake/library/proitems.h
diff options
context:
space:
mode:
authorOswald Buddenhagen <oswald.buddenhagen@qt.io>2017-08-14 12:06:35 +0200
committerOswald Buddenhagen <oswald.buddenhagen@qt.io>2018-06-27 17:24:09 +0000
commitd550ba4e9628cf67880a1c8596629ec598718b3e (patch)
treee5f12958a8aab6bcc4bef7cd701aa354098cc716 /qmake/library/proitems.h
parentd68016c739f5e406fcd43f8fcfc94cc6fb76dded (diff)
qmake: make access to raw data temporaries safe
make sure the access is properly scoped and does not recurse. Change-Id: Iaa345cd2771811281b9ed6f634c70235a78c3c33 Reviewed-by: Joerg Bornemann <joerg.bornemann@qt.io>
Diffstat (limited to 'qmake/library/proitems.h')
-rw-r--r--qmake/library/proitems.h49
1 files changed, 49 insertions, 0 deletions
diff --git a/qmake/library/proitems.h b/qmake/library/proitems.h
index 1d7ebed3aa..fcb6869780 100644
--- a/qmake/library/proitems.h
+++ b/qmake/library/proitems.h
@@ -229,6 +229,55 @@ inline bool operator!=(const QString &that, const ProString &other)
QTextStream &operator<<(QTextStream &t, const ProString &str);
+// This class manages read-only access to a ProString via a raw data QString
+// temporary, ensuring that the latter is accessed exclusively.
+class ProStringRoUser
+{
+public:
+ ProStringRoUser(QString &rs)
+ {
+ Q_ASSERT(rs.isDetached() || rs.isEmpty());
+ m_rs = &rs;
+ }
+ ProStringRoUser(const ProString &ps, QString &rs)
+ : ProStringRoUser(rs)
+ {
+ ps.toQString(rs);
+ }
+ // No destructor, as a RAII pattern cannot be used: references to the
+ // temporary string can legitimately outlive instances of this class
+ // (if they are held by Qt, e.g. in QRegExp).
+ QString &set(const ProString &ps) { return ps.toQString(*m_rs); }
+ QString &str() { return *m_rs; }
+
+protected:
+ QString *m_rs;
+};
+
+// This class manages read-write access to a ProString via a raw data QString
+// temporary, ensuring that the latter is accessed exclusively, and that raw
+// data does not leak outside its source's refcounting.
+class ProStringRwUser : public ProStringRoUser
+{
+public:
+ ProStringRwUser(QString &rs)
+ : ProStringRoUser(rs), m_ps(0) {}
+ ProStringRwUser(const ProString &ps, QString &rs)
+ : ProStringRoUser(ps, rs), m_ps(&ps) {}
+ QString &set(const ProString &ps) { m_ps = &ps; return ProStringRoUser::set(ps); }
+ ProString extract(const QString &s) const
+ { return s.isSharedWith(*m_rs) ? *m_ps : ProString(s).setSource(*m_ps); }
+ ProString extract(const QString &s, const ProStringRwUser &other) const
+ {
+ if (other.m_ps && s.isSharedWith(*other.m_rs))
+ return *other.m_ps;
+ return extract(s);
+ }
+
+private:
+ const ProString *m_ps;
+};
+
class ProStringList : public QVector<ProString> {
public:
ProStringList() {}