Bug 299603 part.2 IMContextWrapper::SetTextRange() should initialize the range offsets and fail if the range is collapsed r=m_kato
authorMasayuki Nakano <masayuki@d-toybox.com>
Wed, 19 Aug 2015 16:37:39 +0900
changeset 280247 02ab221ff043df27e820b2630a412d796c8f1e8d
parent 280246 1a1992d30ee3ff10c30577f5a9fff8fa97c1272c
child 280248 66c718b99d9482c8a272a00f14c154aa5347625a
push idunknown
push userunknown
push dateunknown
reviewersm_kato
bugs299603
milestone43.0a1
Bug 299603 part.2 IMContextWrapper::SetTextRange() should initialize the range offsets and fail if the range is collapsed r=m_kato
widget/gtk/IMContextWrapper.cpp
--- a/widget/gtk/IMContextWrapper.cpp
+++ b/widget/gtk/IMContextWrapper.cpp
@@ -1467,16 +1467,64 @@ IMContextWrapper::CreateTextRangeArray(G
     return textRangeArray.forget();
 }
 
 bool
 IMContextWrapper::SetTextRange(PangoAttrIterator* aPangoAttrIter,
                                const gchar* aUTF8CompositionString,
                                TextRange& aTextRange) const
 {
+    // Set the range offsets in UTF-16 string.
+    gint utf8ClauseStart, utf8ClauseEnd;
+    pango_attr_iterator_range(aPangoAttrIter, &utf8ClauseStart, &utf8ClauseEnd);
+    if (utf8ClauseStart == utf8ClauseEnd) {
+        MOZ_LOG(gGtkIMLog, LogLevel::Error,
+            ("GTKIM: %p   SetTextRange(), FAILED, due to collapsed range",
+             this));
+        return false;
+    }
+
+    if (!utf8ClauseStart) {
+        aTextRange.mStartOffset = 0;
+    } else {
+        glong utf16PreviousClausesLength;
+        gunichar2* utf16PreviousClausesString =
+            g_utf8_to_utf16(aUTF8CompositionString, utf8ClauseStart, nullptr,
+                            &utf16PreviousClausesLength, nullptr);
+
+        if (NS_WARN_IF(!utf16PreviousClausesString)) {
+            MOZ_LOG(gGtkIMLog, LogLevel::Error,
+                ("GTKIM: %p   SetTextRange(), FAILED, due to g_utf8_to_utf16() "
+                 "failure (retrieving previous string of current clause)",
+                 this));
+            return false;
+        }
+
+        aTextRange.mStartOffset = utf16PreviousClausesLength;
+        g_free(utf16PreviousClausesString);
+    }
+
+    glong utf16CurrentClauseLength;
+    gunichar2* utf16CurrentClauseString =
+        g_utf8_to_utf16(aUTF8CompositionString + utf8ClauseStart,
+                        utf8ClauseEnd - utf8ClauseStart,
+                        nullptr, &utf16CurrentClauseLength, nullptr);
+
+    if (NS_WARN_IF(!utf16CurrentClauseString)) {
+        MOZ_LOG(gGtkIMLog, LogLevel::Error,
+            ("GTKIM: %p   SetTextRange(), FAILED, due to g_utf8_to_utf16() "
+             "failure (retrieving current clause)",
+             this));
+        return false;
+    }
+
+    aTextRange.mEndOffset = aTextRange.mStartOffset + utf16CurrentClauseLength;
+    g_free(utf16CurrentClauseString);
+    utf16CurrentClauseString = nullptr;
+
     /**
      * Depend on gtk2's implementation on XIM support.
      * In aFeedback got from gtk2, there are only three types of data:
      * PANGO_ATTR_UNDERLINE, PANGO_ATTR_FOREGROUND, PANGO_ATTR_BACKGROUND.
      * Corresponding to XIMUnderline, XIMReverse.
      * Don't take PANGO_ATTR_BACKGROUND into account, since
      * PANGO_ATTR_BACKGROUND and PANGO_ATTR_FOREGROUND are always
      * a couple.
@@ -1487,60 +1535,31 @@ IMContextWrapper::SetTextRange(PangoAttr
     PangoAttribute* attrForeground =
         pango_attr_iterator_get(aPangoAttrIter, PANGO_ATTR_FOREGROUND);
     if (!attrUnderline && !attrForeground) {
         MOZ_LOG(gGtkIMLog, LogLevel::Warning,
             ("GTKIM: %p   SetTextRange(), FAILED, due to no attr", this));
         return false;
     }
 
-    // Get the range of the current attribute(s)
-    gint start, end;
-    pango_attr_iterator_range(aPangoAttrIter, &start, &end);
-
     // XIMReverse | XIMUnderline
     if (attrUnderline && attrForeground) {
         aTextRange.mRangeType = NS_TEXTRANGE_SELECTEDCONVERTEDTEXT;
     }
     // XIMUnderline
     else if (attrUnderline) {
         aTextRange.mRangeType = NS_TEXTRANGE_CONVERTEDTEXT;
     }
     // XIMReverse
     else if (attrForeground) {
         aTextRange.mRangeType = NS_TEXTRANGE_SELECTEDRAWTEXT;
     } else {
         aTextRange.mRangeType = NS_TEXTRANGE_RAWINPUT;
     }
 
-    gunichar2* uniStr = nullptr;
-    if (start == 0) {
-        aTextRange.mStartOffset = 0;
-    } else {
-        glong uniStrLen;
-        uniStr = g_utf8_to_utf16(aUTF8CompositionString, start,
-                                 nullptr, &uniStrLen, nullptr);
-        if (uniStr) {
-            aTextRange.mStartOffset = uniStrLen;
-            g_free(uniStr);
-            uniStr = nullptr;
-        }
-    }
-
-    glong uniStrLen;
-    uniStr = g_utf8_to_utf16(aUTF8CompositionString + start, end - start,
-                             nullptr, &uniStrLen, nullptr);
-    if (!uniStr) {
-        aTextRange.mEndOffset = aTextRange.mStartOffset;
-    } else {
-        aTextRange.mEndOffset = aTextRange.mStartOffset + uniStrLen;
-        g_free(uniStr);
-        uniStr = nullptr;
-    }
-
     MOZ_LOG(gGtkIMLog, LogLevel::Debug,
         ("GTKIM: %p   SetTextRange(), succeeded, aTextRange= { "
          "mStartOffset=%u, mEndOffset=%u, mRangeType=%s }",
          this, aTextRange.mStartOffset, aTextRange.mEndOffset,
          GetRangeTypeName(aTextRange.mRangeType)));
 
     return true;
 }