Menu

#2433 ImeOnDocumentFeed() for window mode IME

Bug
closed-fixed
5
2024-04-23
2024-03-20
Zufu Liu
No

app crashed after ImeOnDocumentFeed() called for window mode IME, see https://github.com/zufuliu/notepad2/issues/775 .

I feel this due to wrong information returned to IME:
for window mode IME, std::wstring rcFeed doesn't contains current composition string, so dwCompStrLen (larger than rcFeed.length()) and dwCompStrOffset are invalid.

for typing # then i:

// inline mode
rcFeedLen=6, compStrLen=2, imeCaretPos=2, curPos=3, compStart=1, compStrOffset=1

// window mode
rcFeedLen=2, compStrLen=2, imeCaretPos=2, curPos=1, compStart=-1, compStrOffset=0

Discussion

  • Zufu Liu

    Zufu Liu - 2024-03-20

    Set dwCompStrLen and dwCompStrOffset to zero indeed "fixed" the crash.

     
  • Zufu Liu

    Zufu Liu - 2024-03-20
    • Description has changed:

    Diff:

    --- old
    +++ new
    @@ -1,13 +1,13 @@
     app crashed after `ImeOnDocumentFeed()` called for window mode IME, see https://github.com/zufuliu/notepad2/issues/775.
    
     I feel this due to wrong information returned to IME:
    -for window mode IME, `std::wstring rcFeed` doesn't contains current composition string, so `dwCompStrLen` and `dwCompStrOffset` are invalid.
    +for window mode IME, `std::wstring rcFeed` doesn't contains current composition string, so `dwCompStrLen` (larger than `rcFeed.length()`) and `dwCompStrOffset` are invalid.
    
    -for typing <kbd>#<kbd> then <kbd>i<kbd> then:
    +for typing <kbd>#<kbd> then <kbd>i<kbd>:
     ```
     // inline mode
    -ImeOnDocumentFeed compStrLen=2, imeCaretPos=2, curPos=3, compStart=1, compStrOffset=1
    +rcFeedLen=6, compStrLen=2, imeCaretPos=2, curPos=3, compStart=1, compStrOffset=1
    
     // window mode
    -ImeOnDocumentFeed compStrLen=2, imeCaretPos=2, curPos=1, compStart=-1, compStrOffset=0
    +rcFeedLen=2, compStrLen=2, imeCaretPos=2, curPos=1, compStart=-1, compStrOffset=0
     ```
    
     
  • Neil Hodgson

    Neil Hodgson - 2024-03-20

    compStrLen comes from GCS_COMPSTR, so what is the text of GCS_COMPSTR and how does it relate to the document?

     
  • Zufu Liu

    Zufu Liu - 2024-03-20

    GCS_COMPSTR is ch after typing i, for window mode, rcFeed is #, inline mode rcFeed is #ch.

     
  • Neil Hodgson

    Neil Hodgson - 2024-03-20

    So it needs to detect windowed IME (unsure if imeInteraction is sufficient) and set compStart and compStrOffset to 0 when windowed.

     
  • Zufu Liu

    Zufu Liu - 2024-03-20

    Just got three ideas to fix this:
    1. disable ImeOnDocumentFeed() for window mode IME.
    2. set compStart and compStrOffset to 0 when rcFeed not contains current GCS_COMPSTR.
    3. insert current GCS_COMPSTR into rcFeed at caret position when it not contains the former.

     
  • Neil Hodgson

    Neil Hodgson - 2024-03-20

    The text around the caret may still be useful for the contextual choice of composition, even in windowed mode so (1) seems poor. (2) seems reasonable to me. The IME knows what the composition string is so shouldn't need (3) and may be confused by it.

    Its likely only the main caret-based string (dwStrLen,dwStrOffset) that is useful for context.

     
  • Zufu Liu

    Zufu Liu - 2024-03-21

    Patch to fix the crash (only need to set compStrLen to 0 for window mode).

    DWORD compStrLen = 0;
    Sci::Position compStart = curPos;
    if (pdoc->TentativeActive()) {
        // rcFeed contains current composition string
        compStrLen = imc.GetCompositionStringLength(GCS_COMPSTR);
        const int imeCaretPos = imc.GetImeCaretPos();
        compStart = pdoc->GetRelativePositionUTF16(curPos, -imeCaretPos);
    }
    const Sci::Position compStrOffset = pdoc->CountUTF16(lineStart, compStart);
    

    compStrOffset for window mode is changed to compute from curPos instead of the wrongly imeCaretPos offset.

    imc.GetCompositionString(GCS_COMPSTR).size() is replaced with a new function imc.GetCompositionStringLength(GCS_COMPSTR) to eliminate the temporary string.

     
    • Zufu Liu

      Zufu Liu - 2024-03-21

      The Patch.

       
  • Neil Hodgson

    Neil Hodgson - 2024-03-22
    • Description has changed:

    Diff:

    --- old
    +++ new
    @@ -1,4 +1,4 @@
    -app crashed after `ImeOnDocumentFeed()` called for window mode IME, see https://github.com/zufuliu/notepad2/issues/775.
    +app crashed after `ImeOnDocumentFeed()` called for window mode IME, see https://github.com/zufuliu/notepad2/issues/775 .
    
     I feel this due to wrong information returned to IME:
     for window mode IME, `std::wstring rcFeed` doesn't contains current composition string, so `dwCompStrLen` (larger than `rcFeed.length()`) and `dwCompStrOffset` are invalid.
    
     
  • Neil Hodgson

    Neil Hodgson - 2024-03-22
    • status: open --> open-fixed
     
  • Neil Hodgson

    Neil Hodgson - 2024-03-22

    Committed as [e8da1f].

     

    Related

    Commit: [e8da1f]

  • Neil Hodgson

    Neil Hodgson - 2024-04-23
    • status: open-fixed --> closed-fixed
     

Log in to post a comment.