Bug 636131 iBus freezes when it retrieves surrounding text and if the caret is at end of line r=karlt, a=blocking2.0
authorMasayuki Nakano <masayuki@d-toybox.com>
Mon, 28 Feb 2011 15:00:41 +0900
changeset 63162 fc44e3ee260870625b9cd77685758b16b4db24ed
parent 63161 d24f0712886d325ccb6cbd27cec3bd6725701493
child 63163 554fa6c29f0788b52ceead2f9012b0c623ad85f5
child 63474 f164061ea0d22defdbd730418e683b79040509e8
push id19050
push usermasayuki@d-toybox.com
push dateMon, 28 Feb 2011 06:01:44 +0000
treeherdermozilla-central@fc44e3ee2608 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerskarlt, blocking2
bugs636131
milestone2.0b13pre
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 636131 iBus freezes when it retrieves surrounding text and if the caret is at end of line r=karlt, a=blocking2.0
widget/src/gtk2/nsGtkIMModule.cpp
--- a/widget/src/gtk2/nsGtkIMModule.cpp
+++ b/widget/src/gtk2/nsGtkIMModule.cpp
@@ -1378,43 +1378,62 @@ nsGtkIMModule::GetCurrentParagraph(nsASt
 
     // Query cursor position & selection
     nsQueryContentEvent querySelectedTextEvent(PR_TRUE,
                                                NS_QUERY_SELECTED_TEXT,
                                                mLastFocusedWindow);
     mLastFocusedWindow->DispatchEvent(&querySelectedTextEvent, status);
     NS_ENSURE_TRUE(querySelectedTextEvent.mSucceeded, NS_ERROR_FAILURE);
 
-    aCursorPos = querySelectedTextEvent.mReply.mOffset;
+    PRUint32 selOffset = querySelectedTextEvent.mReply.mOffset;
     PRUint32 selLength = querySelectedTextEvent.mReply.mString.Length();
 
+    // XXX nsString::Find and nsString::RFind take PRInt32 for offset, so,
+    //     we cannot support this request when the current offset is larger
+    //     than PR_INT32_MAX.
+    if (selOffset > PR_INT32_MAX || selLength > PR_INT32_MAX ||
+        selOffset + selLength > PR_INT32_MAX) {
+        PR_LOG(gGtkIMLog, PR_LOG_ALWAYS,
+            ("    FAILED, The selection is out of range"));
+        PR_LOG(gGtkIMLog, PR_LOG_ALWAYS,
+            ("        selOffset=%u, selLength=%u",
+             selOffset, selLength));
+        return NS_ERROR_FAILURE;
+    }
+
     // Get all text contents of the focused editor
     nsQueryContentEvent queryTextContentEvent(PR_TRUE,
                                               NS_QUERY_TEXT_CONTENT,
                                               mLastFocusedWindow);
     queryTextContentEvent.InitForQueryTextContent(0, PR_UINT32_MAX);
     mLastFocusedWindow->DispatchEvent(&queryTextContentEvent, status);
     NS_ENSURE_TRUE(queryTextContentEvent.mSucceeded, NS_ERROR_FAILURE);
 
     nsAutoString textContent(queryTextContentEvent.mReply.mString);
-    if (aCursorPos > textContent.Length()) {
+    if (selOffset + selLength > textContent.Length()) {
         PR_LOG(gGtkIMLog, PR_LOG_ALWAYS,
-          ("GtkIMModule(%p): GetCurrentParagraph, FAILED (The caret offset is invalid)\n",
-           this));
+            ("    FAILED, The selection is invalid"));
+        PR_LOG(gGtkIMLog, PR_LOG_ALWAYS,
+            ("        selOffset=%u, selLength=%u, textContent.Length()=%u",
+             selOffset, selLength, textContent.Length()));
         return NS_ERROR_FAILURE;
     }
 
     // Get only the focused paragraph, by looking for newlines
-    PRInt32 parStart = textContent.RFind("\n", PR_FALSE, aCursorPos, -1) + 1;
-    PRInt32 parEnd = textContent.Find("\n", PR_FALSE, aCursorPos + selLength, -1);
+    PRInt32 parStart = (selOffset == 0) ? 0 :
+        textContent.RFind("\n", PR_FALSE, selOffset - 1, -1) + 1;
+    PRInt32 parEnd = textContent.Find("\n", PR_FALSE, selOffset + selLength, -1);
     if (parEnd < 0) {
         parEnd = textContent.Length();
     }
     aText = nsDependentSubstring(textContent, parStart, parEnd - parStart);
-    aCursorPos -= parStart;
+    aCursorPos = selOffset - PRUint32(parStart);
+
+    PR_LOG(gGtkIMLog, PR_LOG_ALWAYS,
+        ("    aText.Length()=%u, aCursorPos=%u", aText.Length(), aCursorPos));
 
     return NS_OK;
 }
 
 nsresult
 nsGtkIMModule::DeleteText(const PRInt32 aOffset, const PRUint32 aNChars)
 {
     PR_LOG(gGtkIMLog, PR_LOG_ALWAYS,