Convert attribute value to UTF-8 when passing it to libxml2
authorStephan Bergmann <sbergman@redhat.com>
Wed, 23 Sep 2020 09:41:05 +0000 (11:41 +0200)
committerRene Engelhard <rene@debian.org>
Sun, 1 Nov 2020 21:20:53 +0000 (21:20 +0000)
Using toUtf8, requiring the OUString to actually contain well-formed data, but
which is likely OK for this test-code--only function, and is also what similar
dumpAsXml functions e.g. in editeng/source/items/textitem.cxx already use.

This appears to have been broken ever since the code's introduction in
553f10c71a2cc92f5f5890e24948f5277e3d2758 "add dumpAsXml() to more pool items",
and it would typically only have written the leading zero or one
(depending on the architecture's endianness) characters.  (I ran across it on
big-endian s390x, where CppunitTest_sd_tiledrendering
SdTiledRenderingTest::testTdf104405 failed because of

> Entity: line 2: parser error : Input is not proper UTF-8, indicate encoding !
> Bytes: 0xCF 0x22 0x2F 0x3E
> ation=""/><SfxPoolItem whichId="4017" typeName="13SvxBulletItem" presentation="%
>                                                                                ^

apparently reported from within libxml2.)

Change-Id: I4b116d3be84098bd8b8a13b6937da70a1ee02c7f
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/103236
Reviewed-by: Noel Grandin <noel.grandin@collabora.co.uk>
Reviewed-by: Stephan Bergmann <sbergman@redhat.com>
Tested-by: Jenkins
Gbp-Pq: Name bigendian.diff

oox/source/crypto/AgileEngine.cxx
oox/source/crypto/Standard2007Engine.cxx
svl/source/items/poolitem.cxx
svl/source/misc/msodocumentlockfile.cxx
vcl/qa/cppunit/pdfexport/pdfexport.cxx
vcl/source/filter/png/PngImageReader.cxx

index f4eb9d21ea6f21bd09917c1087bc7ec5829edc6b..4aacc2a2cf5b03d78e317224aeca66fb05adaa25 100644 (file)
@@ -459,9 +459,11 @@ bool AgileEngine::decrypt(BinaryXInputStream& aInputStream,
 
     while ((inputLength = aInputStream.readMemory(inputBuffer.data(), inputBuffer.size())) > 0)
     {
-        sal_uInt8* segmentBegin = reinterpret_cast<sal_uInt8*>(&segment);
-        sal_uInt8* segmentEnd   = segmentBegin + sizeof(segment);
-        std::copy(segmentBegin, segmentEnd, saltWithBlockKey.begin() + saltSize);
+        auto p = saltWithBlockKey.begin() + saltSize;
+        p[0] = segment & 0xFF;
+        p[1] = (segment >> 8) & 0xFF;
+        p[2] = (segment >> 16) & 0xFF;
+        p[3] = segment >> 24;
 
         hashCalc(hash, saltWithBlockKey, mInfo.hashAlgorithm);
 
@@ -802,9 +804,11 @@ void AgileEngine::encrypt(const css::uno::Reference<css::io::XInputStream> &  rx
                         inputLength : oox::crypto::roundUp(inputLength, sal_uInt32(mInfo.blockSize));
 
         // Update Key
-        sal_uInt8* segmentBegin = reinterpret_cast<sal_uInt8*>(&nSegment);
-        sal_uInt8* segmentEnd   = segmentBegin + nSegmentByteSize;
-        std::copy(segmentBegin, segmentEnd, saltWithBlockKey.begin() + saltSize);
+        auto p = saltWithBlockKey.begin() + saltSize;
+        p[0] = nSegment & 0xFF;
+        p[1] = (nSegment >> 8) & 0xFF;
+        p[2] = (nSegment >> 16) & 0xFF;
+        p[3] = nSegment >> 24;
 
         hashCalc(hash, saltWithBlockKey, mInfo.hashAlgorithm);
 
index 2aaf6f4ec3f3e8ed76eb80c1fe63c63fc1fc942e..e070bf37cec3c25ccd9bfdc16d1c80e9f9d55636 100644 (file)
@@ -77,12 +77,12 @@ bool Standard2007Engine::calculateEncryptionKey(const OUString& rPassword)
     std::vector<sal_uInt8> initialData(saltSize + passwordByteLength);
     std::copy(saltArray, saltArray + saltSize, initialData.begin());
 
-    const sal_uInt8* passwordByteArray = reinterpret_cast<const sal_uInt8*>(rPassword.getStr());
-
-    std::copy(
-        passwordByteArray,
-        passwordByteArray + passwordByteLength,
-        initialData.begin() + saltSize);
+    auto p = initialData.begin() + saltSize;
+    for (sal_Int32 i = 0; i != rPassword.getLength(); ++i) {
+        auto c = rPassword[i];
+        *p++ = c & 0xFF;
+        *p++ = c >> 8;
+    }
 
     // use "hash" vector for result of sha1 hashing
     // calculate SHA1 hash of initialData
@@ -221,11 +221,23 @@ void Standard2007Engine::writeEncryptionInfo(BinaryXOutputStream& rStream)
     sal_uInt32 headerSize = encryptionHeaderSize + cspNameSize;
     rStream.WriteUInt32(headerSize);
 
-    rStream.writeMemory(&mInfo.header, encryptionHeaderSize);
+    rStream.WriteUInt32(mInfo.header.flags);
+    rStream.WriteUInt32(mInfo.header.sizeExtra);
+    rStream.WriteUInt32(mInfo.header.algId);
+    rStream.WriteUInt32(mInfo.header.algIdHash);
+    rStream.WriteUInt32(mInfo.header.keyBits);
+    rStream.WriteUInt32(mInfo.header.providedType);
+    rStream.WriteUInt32(mInfo.header.reserved1);
+    rStream.WriteUInt32(mInfo.header.reserved2);
     rStream.writeUnicodeArray(lclCspName);
     rStream.WriteUInt16(0);
 
-    rStream.writeMemory(&mInfo.verifier, sizeof(msfilter::EncryptionVerifierAES));
+    rStream.WriteUInt32(mInfo.verifier.saltSize);
+    rStream.writeMemory(&mInfo.verifier.salt, sizeof mInfo.verifier.salt);
+    rStream.writeMemory(&mInfo.verifier.encryptedVerifier, sizeof mInfo.verifier.encryptedVerifier);
+    rStream.WriteUInt32(mInfo.verifier.encryptedVerifierHashSize);
+    rStream.writeMemory(
+        &mInfo.verifier.encryptedVerifierHash, sizeof mInfo.verifier.encryptedVerifierHash);
 }
 
 void Standard2007Engine::encrypt(const css::uno::Reference<css::io::XInputStream> &  rxInputStream,
index c5e09ddf9048a8afed41275cc98344509cdd9333..25f2720b547ced82359ba89f2940ae293b71471a 100644 (file)
@@ -549,7 +549,8 @@ void SfxPoolItem::dumpAsXml(xmlTextWriterPtr pWriter) const
     OUString rText;
     IntlWrapper aIntlWrapper(SvtSysLocale().GetUILanguageTag());
     if (GetPresentation( SfxItemPresentation::Complete, MapUnit::Map100thMM, MapUnit::Map100thMM, rText, aIntlWrapper))
-        xmlTextWriterWriteAttribute(pWriter, BAD_CAST("presentation"), BAD_CAST(rText.getStr()));
+        xmlTextWriterWriteAttribute(
+            pWriter, BAD_CAST("presentation"), BAD_CAST(rText.toUtf8().getStr()));
     xmlTextWriterEndElement(pWriter);
 }
 
index 9650db03999f2e0c991ed1f793c7ffb26ea2cbd9..0c857ffb53ec82645fea3273c74d4ca1a24f480a 100644 (file)
@@ -228,8 +228,16 @@ LockFileEntry MSODocumentLockFile::GetLockData()
                 nUTF16Len = *++pBuf; // use Excel/PowerPoint position
 
             if (nUTF16Len > 0 && nUTF16Len <= 52) // skip wrong format
-                aResult[LockFileComponent::OOOUSERNAME]
-                    = OUString(reinterpret_cast<const sal_Unicode*>(pBuf + 2), nUTF16Len);
+            {
+                OUStringBuffer str(nUTF16Len);
+                sal_uInt8 const* p = reinterpret_cast<sal_uInt8 const*>(pBuf + 2);
+                for (int i = 0; i != nUTF16Len; ++i)
+                {
+                    str.append(sal_Unicode(p[0] | (sal_uInt32(p[1]) << 8)));
+                    p += 2;
+                }
+                aResult[LockFileComponent::OOOUSERNAME] = str.makeStringAndClear();
+            }
         }
     }
     return aResult;
index fe402b4ed8b8646a1a67e2d35fd5b897123acaa4..e6fbce7a19e56d8c8988b965af54a7af39eb93bf 100644 (file)
@@ -29,6 +29,7 @@
 #include <comphelper/scopeguard.hxx>
 #include <comphelper/processfactory.hxx>
 #include <comphelper/propertysequence.hxx>
+#include <osl/endian.h>
 #include <test/bootstrapfixture.hxx>
 #include <unotest/macros_test.hxx>
 #include <unotools/mediadescriptor.hxx>
@@ -1720,6 +1721,12 @@ void PdfExportTest::testTdf115262()
             unsigned long nTextSize = FPDFTextObj_GetText(pPageObject, pTextPage, nullptr, 0);
             std::vector<sal_Unicode> aText(nTextSize);
             FPDFTextObj_GetText(pPageObject, pTextPage, aText.data(), nTextSize);
+#if defined OSL_BIGENDIAN
+            // The data returned by FPDFTextObj_GetText is documented to always be UTF-16LE:
+            for (auto & j: aText) {
+                j = OSL_SWAPWORD(j);
+            }
+#endif
             OUString sText(aText.data(), nTextSize / 2 - 1);
             if (sText == "400")
                 nRowTop = fTop;
@@ -1755,6 +1762,12 @@ void PdfExportTest::testTdf121962()
         unsigned long nTextSize = FPDFTextObj_GetText(pPageObject, pTextPage, nullptr, 0);
         std::vector<sal_Unicode> aText(nTextSize);
         FPDFTextObj_GetText(pPageObject, pTextPage, aText.data(), nTextSize);
+#if defined OSL_BIGENDIAN
+        // The data returned by FPDFTextObj_GetText is documented to always be UTF-16LE:
+        for (auto & j: aText) {
+            j = OSL_SWAPWORD(j);
+        }
+#endif
         OUString sText(aText.data(), nTextSize / 2 - 1);
         CPPUNIT_ASSERT(sText != "** Expression is faulty **");
     }
@@ -1787,6 +1800,12 @@ void PdfExportTest::testTdf115967()
         unsigned long nTextSize = FPDFTextObj_GetText(pPageObject, pTextPage, nullptr, 2);
         std::vector<sal_Unicode> aText(nTextSize);
         FPDFTextObj_GetText(pPageObject, pTextPage, aText.data(), nTextSize);
+#if defined OSL_BIGENDIAN
+        // The data returned by FPDFTextObj_GetText is documented to always be UTF-16LE:
+        for (auto & j: aText) {
+            j = OSL_SWAPWORD(j);
+        }
+#endif
         OUString sChar(aText.data(), nTextSize / 2 - 1);
         sText += sChar.trim();
     }
index 958cae34eb466533c8e39fe31a9de980bc531298..6e9f3825faced1c77bf54a9d1b5e7860fd9f52ac 100644 (file)
@@ -188,6 +188,8 @@ bool reader(SvStream& rStream, BitmapEx& rBitmapEx, bool bUseBitmap32)
                     for (auto& rRow : aRows)
                         rRow.resize(aRowSizeBytes, 0);
 
+                    auto const alphaFirst = (eFormat == ScanlineFormat::N32BitTcAbgr
+                                             || eFormat == ScanlineFormat::N32BitTcArgb);
                     for (int pass = 0; pass < nNumberOfPasses; pass++)
                     {
                         for (png_uint_32 y = 0; y < height; y++)
@@ -199,10 +201,17 @@ bool reader(SvStream& rStream, BitmapEx& rBitmapEx, bool bUseBitmap32)
                             for (size_t i = 0; i < aRowSizeBytes; i += 4)
                             {
                                 sal_Int8 alpha = pRow[i + 3];
+                                if (alphaFirst)
+                                {
+                                    pScanline[iColor++] = alpha;
+                                }
                                 pScanline[iColor++] = vcl::bitmap::premultiply(pRow[i + 0], alpha);
                                 pScanline[iColor++] = vcl::bitmap::premultiply(pRow[i + 1], alpha);
                                 pScanline[iColor++] = vcl::bitmap::premultiply(pRow[i + 2], alpha);
-                                pScanline[iColor++] = alpha;
+                                if (!alphaFirst)
+                                {
+                                    pScanline[iColor++] = alpha;
+                                }
                             }
                         }
                     }