Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix crashes in 64-bit builds of Notepad++ 8.3 and later #13364

Merged
merged 5 commits into from Feb 22, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
20 changes: 9 additions & 11 deletions source/NVDAObjects/window/scintilla.py
@@ -1,19 +1,16 @@
# -*- coding: UTF-8 -*-
# A part of NonVisual Desktop Access (NVDA)
# Copyright (C) 2009-2019 NV Access Limited, Arnold Loubriat, Babbage B.V., Łukasz Golonka
# Copyright (C) 2007-2022 NV Access Limited, Arnold Loubriat, Babbage B.V., Łukasz Golonka, Joseph Lee,
# Peter Vágner
# This file is covered by the GNU General Public License.
# See the file COPYING for more details.

import ctypes
import speech
import textInfos.offsets
import winKernel
import winUser
import globalVars
import controlTypes
import config
from . import Window
from .. import NVDAObjectTextInfo
from ..behaviors import EditableTextWithAutoSelectDetection
import watchdog
import eventHandler
Expand Down Expand Up @@ -67,14 +64,15 @@ class CharacterRangeStruct(ctypes.Structure):
('cpMax',ctypes.c_long),
]

class TextRangeStruct(ctypes.Structure):
_fields_=[
('chrg',CharacterRangeStruct),
('lpstrText',ctypes.c_char_p),
]

class ScintillaTextInfo(textInfos.offsets.OffsetsTextInfo):

class TextRangeStruct(ctypes.Structure):
_fields_ = [
('chrg', CharacterRangeStruct),
('lpstrText', ctypes.c_char_p),
]

def _get_encoding(self):
cp=watchdog.cancellableSendMessage(self.obj.windowHandle,SCI_GETCODEPAGE,0,0)
if cp==SC_CP_UTF8:
Expand Down Expand Up @@ -171,7 +169,7 @@ def _getLineCount(self):

def _getTextRange(self,start,end):
bufLen = (end - start) + 1
textRange = TextRangeStruct()
textRange = self.TextRangeStruct()
textRange.chrg.cpMin = start
textRange.chrg.cpMax = end
processHandle = self.obj.processHandle
Expand Down
10 changes: 10 additions & 0 deletions source/appModules/notepad++.py
@@ -0,0 +1,10 @@
# A part of NonVisual Desktop Access (NVDA)
# Copyright (C) 2022 NV Access Limited, Łukasz Golonka
# This file may be used under the terms of the GNU General Public License, version 2 or later.
# For more details see: https://www.gnu.org/licenses/gpl-2.0.html

"""This is just an alias which maps the appModule for Notepad++ to the right binary file
by exposing everything from the real module in its namespace.
"""

from .notepadPlusPlus import * # noqa: F401, F403
58 changes: 58 additions & 0 deletions source/appModules/notepadPlusPlus.py
@@ -0,0 +1,58 @@
# A part of NonVisual Desktop Access (NVDA)
# Copyright (C) 2022 NV Access Limited, Łukasz Golonka
# This file may be used under the terms of the GNU General Public License, version 2 or later.
# For more details see: https://www.gnu.org/licenses/gpl-2.0.html

"""AppModule for Notepad++.
Do not rename! The executable file for Notepad++ is named `notepad++` and `+` is not a valid character
in Python's import statements.
This module is mapped to the right binary separately
and the current name makes it possible to expose it from `nvdaBuiltin` for add-on developers.
"""

import ctypes

import appModuleHandler
import NVDAObjects.window.scintilla as ScintillaBase


class CharacterRangeStructLongLong(ctypes.Structure):
"""By default character ranges in Scintilla are represented by longs.
However long is not big enough for files over 2 GB,
therefore in 64-bit builds of Notepad++ 8.3 and later
these ranges are represented by longlong.
"""
_fields_ = [
('cpMin', ctypes.c_longlong),
('cpMax', ctypes.c_longlong),
]


class ScintillaTextInfoNpp83(ScintillaBase.ScintillaTextInfo):
"""Text info for 64-bit builds of Notepad++ 8.3 and later.
"""

class TextRangeStruct(ctypes.Structure):
_fields_ = [
('chrg', CharacterRangeStructLongLong),
('lpstrText', ctypes.c_char_p),
]


class NppEdit(ScintillaBase.Scintilla):

name = None # The name of the editor is not useful.

def _get_TextInfo(self):
if self.appModule.is64BitProcess:
appVerMajor, appVerMinor, *__ = self.appModule.productVersion.split(".")
if int(appVerMajor) >= 8 and int(appVerMinor) >= 3:
return ScintillaTextInfoNpp83
return super().TextInfo


class AppModule(appModuleHandler.AppModule):

def chooseNVDAObjectOverlayClasses(self, obj, clsList):
if obj.windowClassName == "Scintilla" and obj.windowControlID == 0:
clsList.insert(0, NppEdit)
2 changes: 2 additions & 0 deletions user_docs/en/changes.t2t
Expand Up @@ -65,6 +65,7 @@ What's New in NVDA
- Prevents a bug causing double-reporting when using Windows Console and Terminal. (#13261)
- Fixed several cases where list items could not be reported in 64 bit applications, such as REAPER. (#8175)
- In the Microsoft Edge downloads manager, NVDA will now automatically switch to focus mode once the list item with the most recent download gains focus. (#13221)
- NVDA no longer causes 64-bit versions of Notepad++ 8.3 and above to crash. (#13311)
-

== Changes for Developers ==
Expand Down Expand Up @@ -131,6 +132,7 @@ This can dramatically decrease build times on multi core systems. (#13226)
- ``UIAAutomationId`` property for UIA objects should be preferred over ``cachedAutomationId``. (#13125, #11447)
- ``cachedAutomationId`` can be used if obtained directly from the element.
-
- ``NVDAObjects.window.scintilla.CharacterRangeStruct`` has moved to ``NVDAObjects.window.scintilla.Scintilla.CharacterRangeStruct``. (#13364)
-


Expand Down