Skip to content

notepad.activateBufferID can activate incorrect cloned document #382

Closed

Description

@alankilborn

Using 64-bit Notepad++ version: 8.75 and Pythonscript version: 3.0021.

Scenario:

  • have a cloned document (and other documents as well, in both views)
  • obtain the buffer id of the cloned document, e.g. using x = notepad.getCurrentBufferID() when one of the clones is the active tab
  • make the clones be inactive in both view 0 and view 1 by selecting other tabs
  • make view 1 the active view
  • execute notepad.activateBufferID(x)

Note that the clone in view 0 is made active, when it should be the clone in view 1 that is made active.


Some analysis:

The activateBufferID code looks like this:

    void NotepadPlusWrapper::activateBufferID(intptr_t bufferID)
    {
        idx_t index = (idx_t)callNotepad(NPPM_GETPOSFROMBUFFERID, static_cast<WPARAM>(bufferID));
        UINT view = (index & 0xC0000000) >> 30;
        index = index & 0x3FFFFFFF;
        callNotepad(NPPM_ACTIVATEDOC, view, (LPARAM)index);
    }

The NPPM_GETPOSFROMBUFFERID message takes two arguments, but the PS code only supplies one. The second argument should be supplied and should be the currently active view number.

Activity

  1. chcg commented on Apr 7, 2025

    @chcg
    Collaborator

    @alankilborn According to docu:

    lParam [in]
        int priorityView, which must be either 0 (main view) or 1 (secondary view). It will search the chosen view first, but if the given bufferID cannot be found in the chosen view, the other view will also be searched.
    
    Return value:
        Returns -1 if bufferID doesn’t exist, else returns the encoded viewIndex and docIndex.
    

    this should also work without the view. But at least the return value of -1 is not checked.

  2. alankilborn commented on Apr 7, 2025

    @alankilborn
    Author

    @chcg

    I didn’t check, but it could be that ‘callNotepad’ supplies a 2nd argument of zero, causing the bug in the scenario I outlined.

  3. alankilborn commented on Apr 8, 2025

    @alankilborn
    Author

    it could be that ‘callNotepad’ supplies a 2nd argument of zero, causing the bug

    Confirmed:

    callNotepad uses a default argument for lParam and the default argument is zero.

    Thus, that's the bug. @chcg Do you agree?


    Side note:

    the return value of -1 is not checked.

    If a -1 results, there is nothing to do anyway, as there is no following code in the function.

  4. chcg commented on Apr 8, 2025

    @chcg
    Collaborator

    @alankilborn I'm not sure if the bufferID is the same in both views. If yes, then the search order would be set by view parameter which is indeed the default value from callNotepad and 0 aka main view.

    This would require to add getCurrentView() to the method and provide the result as lparam to NPPM_GETPOSFROMBUFFERID

    See NPPM_GETPOSFROMBUFFERID:
    https://github.com/notepad-plus-plus/notepad-plus-plus/blob/5c1813185aa111d6247de39e3d7049ebef0960e0/PowerEditor/src/NppBigSwitch.cpp#L2280

  5. alankilborn commented on Apr 8, 2025

    @alankilborn
    Author

    I'm not sure if the bufferID is the same in both views

    It is.

    return value not checked.

    Oh, I see, you mean the return value from the NPPM_GETPOSFROMBUFFERID, not from NPPM_ACTIVATEDOC, like I first thought...

  6. added a commit that references this issue on Jun 8, 2025
    467c3b9
  7. alankilborn commented on Jul 18, 2025

    @alankilborn
    Author

    Verified as fixed in PS 3.0.23 using Notepad++ 8.8.3.

  8. alankilborn commented on Jul 18, 2025

    @alankilborn
    Author

    Just as a reference, this was also discussed on the Community, starting here: https://community.notepad-plus-plus.org/post/100707

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions