diff options
author | Oswald Buddenhagen <oswald.buddenhagen@qt.io> | 2017-08-14 12:06:35 +0200 |
---|---|---|
committer | Oswald Buddenhagen <oswald.buddenhagen@qt.io> | 2018-06-27 17:24:09 +0000 |
commit | d550ba4e9628cf67880a1c8596629ec598718b3e (patch) | |
tree | e5f12958a8aab6bcc4bef7cd701aa354098cc716 /qmake/library/proitems.h | |
parent | d68016c739f5e406fcd43f8fcfc94cc6fb76dded (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.h | 49 |
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() {} |