Bug 757366 - Don't cast pointers to 'name'-table data to uint16_t*, as they may not be 16-bit-aligned. r=jrmuizel
authorJonathan Kew <jkew@mozilla.com>
Mon, 26 Sep 2016 18:05:14 +0100
changeset 315304 30de72d3b0399315a841a960eeb761e1131da118
parent 315303 66b8ea362db884bd5d74937cf294395fc436999a
child 315305 c33c1775fe24fe536a408719ef5f6283ef075533
push id30747
push usercbook@mozilla.com
push dateTue, 27 Sep 2016 09:22:00 +0000
treeherdermozilla-central@66a77b9bfe5d [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjrmuizel
bugs757366
milestone52.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 757366 - Don't cast pointers to 'name'-table data to uint16_t*, as they may not be 16-bit-aligned. r=jrmuizel
gfx/thebes/gfxFontUtils.cpp
--- a/gfx/thebes/gfxFontUtils.cpp
+++ b/gfx/thebes/gfxFontUtils.cpp
@@ -913,26 +913,28 @@ IsValidSFNTVersion(uint32_t version)
 {
     // normally 0x00010000, CFF-style OT fonts == 'OTTO' and Apple TT fonts = 'true'
     // 'typ1' is also possible for old Type 1 fonts in a SFNT container but not supported
     return version == 0x10000 ||
            version == TRUETYPE_TAG('O','T','T','O') ||
            version == TRUETYPE_TAG('t','r','u','e');
 }
 
-// copy and swap UTF-16 values, assume no surrogate pairs, can be in place
+// Copy and swap UTF-16 values, assume no surrogate pairs, can be in place.
+// aInBuf and aOutBuf are NOT necessarily 16-bit-aligned, so we should avoid
+// accessing them directly as uint16_t* values.
+// aLen is count of UTF-16 values, so the byte buffers are twice that.
 static void
-CopySwapUTF16(const uint16_t *aInBuf, uint16_t *aOutBuf, uint32_t aLen)
+CopySwapUTF16(const char* aInBuf, char* aOutBuf, uint32_t aLen)
 {
-    const uint16_t *end = aInBuf + aLen;
+    const char* end = aInBuf + aLen * 2;
     while (aInBuf < end) {
-        uint16_t value = *aInBuf;
-        *aOutBuf = (value >> 8) | (value & 0xff) << 8;
-        aOutBuf++;
-        aInBuf++;
+        uint8_t b0 = *aInBuf++;
+        *aOutBuf++ = *aInBuf++;
+        *aOutBuf++ = b0;
     }
 }
 
 gfxUserFontType
 gfxFontUtils::DetermineFontDataType(const uint8_t *aFontData, uint32_t aFontDataLength)
 {
     // test for OpenType font data
     // problem: EOT-Lite with 0x10000 length will look like TrueType!
@@ -1441,23 +1443,23 @@ gfxFontUtils::DecodeFontName(const char 
         NS_WARNING(warnBuf);
 #endif
         return false;
     }
 
     if (csName[0] == 0) {
         // empty charset name: data is utf16be, no need to instantiate a converter
         uint32_t strLen = aByteLen / 2;
+        aName.SetLength(strLen);
 #ifdef IS_LITTLE_ENDIAN
-        aName.SetLength(strLen);
-        CopySwapUTF16(reinterpret_cast<const uint16_t*>(aNameData),
-                      reinterpret_cast<uint16_t*>(aName.BeginWriting()), strLen);
+        CopySwapUTF16(aNameData, reinterpret_cast<char*>(aName.BeginWriting()),
+                      strLen);
 #else
-        aName.Assign(reinterpret_cast<const char16_t*>(aNameData), strLen);
-#endif    
+        memcpy(aName.BeginWriting(), aNameData, strLen * 2);
+#endif
         return true;
     }
 
     nsCOMPtr<nsIUnicodeDecoder> decoder =
         mozilla::dom::EncodingUtils::DecoderForEncoding(csName);
     if (!decoder) {
         NS_WARNING("failed to get the decoder for a font name string");
         return false;