From 8939999deef4f77f19d7b2d31df09260a34affe1 Mon Sep 17 00:00:00 2001 From: Michael Weghorn Date: Fri, 26 Apr 2024 14:39:14 +0200 Subject: [PATCH] qt: Avoid race on QtTransferable member As Michael Stahl pointed out in [1], there is a data race on `QtTransferable::m_bProvideUTF16FromOtherEncoding`. Adjust the code a bit to no longer make use of the member and drop it. The QtClipboard case was fine because both methods making use of the member always run in the main thread with the SolarMutex held. For anything else, the `m_pMimeData` doesn't change don't change, so access to that member doesn't need to be guarded by a mutex and thus dropping `QtTransferable::m_bProvideUTF16FromOtherEncoding` should be sufficient to address that race at least. (Another one will be addressed separately.) [1] https://gerrit.libreoffice.org/c/core/+/166140/comment/bc1c9f11_6ad630b7 Change-Id: Iaf2fb460b129493f5627c95b6968aa57da368b4c Reviewed-on: https://gerrit.libreoffice.org/c/core/+/166749 Reviewed-by: Michael Stahl Tested-by: Jenkins --- vcl/inc/qt5/QtTransferable.hxx | 1 - vcl/qt5/QtTransferable.cxx | 35 +++++++++++++++++----------------- 2 files changed, 17 insertions(+), 19 deletions(-) diff --git a/vcl/inc/qt5/QtTransferable.hxx b/vcl/inc/qt5/QtTransferable.hxx index 38cb4d92005b..c58490e90460 100644 --- a/vcl/inc/qt5/QtTransferable.hxx +++ b/vcl/inc/qt5/QtTransferable.hxx @@ -34,7 +34,6 @@ class QtTransferable : public cppu::WeakImplHelper SAL_CALL QtTransferable::getTr nMimeTypeCount++; } - m_bProvideUTF16FromOtherEncoding = (bHaveNoCharset || bHaveUTF8) && !bHaveUTF16; - if (m_bProvideUTF16FromOtherEncoding) + // in case of text/plain data, but no UTF-16 encoded one, + // QtTransferable::getTransferData converts from existing encoding to UTF-16 + const bool bProvideUTF16FromOtherEncoding = (bHaveNoCharset || bHaveUTF8) && !bHaveUTF16; + if (bProvideUTF16FromOtherEncoding) { aFlavor.MimeType = "text/plain;charset=utf-16"; aFlavor.DataType = cppu::UnoType::get(); @@ -127,26 +128,24 @@ css::uno::Any SAL_CALL QtTransferable::getTransferData(const css::datatransfer:: if (rFlavor.MimeType == "text/plain;charset=utf-16") { OUString aString; - if (m_bProvideUTF16FromOtherEncoding) - { - if (m_pMimeData->hasFormat("text/plain;charset=utf-8")) - { - QByteArray aByteData(m_pMimeData->data(QStringLiteral("text/plain;charset=utf-8"))); - aString = OUString::fromUtf8(reinterpret_cast(aByteData.data())); - } - else - { - QByteArray aByteData(m_pMimeData->data(QStringLiteral("text/plain"))); - aString = OUString(reinterpret_cast(aByteData.data()), - aByteData.size(), osl_getThreadTextEncoding()); - } - } - else + // use existing UTF-16 encoded text/plain or convert to UTF-16 as needed + if (m_pMimeData->hasFormat("text/plain;charset=utf-16")) { QByteArray aByteData(m_pMimeData->data(toQString(rFlavor.MimeType))); aString = OUString(reinterpret_cast(aByteData.data()), aByteData.size() / 2); } + else if (m_pMimeData->hasFormat("text/plain;charset=utf-8")) + { + QByteArray aByteData(m_pMimeData->data(QStringLiteral("text/plain;charset=utf-8"))); + aString = OUString::fromUtf8(reinterpret_cast(aByteData.data())); + } + else + { + QByteArray aByteData(m_pMimeData->data(QStringLiteral("text/plain"))); + aString = OUString(reinterpret_cast(aByteData.data()), aByteData.size(), + osl_getThreadTextEncoding()); + } aAny <<= aString; } else