fix: buffer handling consistency

This commit is contained in:
METANEOCORTEX\Kotti 2026-05-04 17:08:26 +02:00
parent b830fdf534
commit 8072f8f7fc
4 changed files with 24 additions and 40 deletions

View File

@ -8,7 +8,6 @@ Scripts under `Build\` (PowerShell under `Build\scripts\`):
- `Build\Build_x64.cmd [Release|Debug]` — single platform (also `_Win32`, `_ARM64`, `_x64_AVX2`)
- `Build\BuildAll.cmd` — all four platforms
- `msbuild Notepad3.sln /m /p:Configuration=Release /p:Platform=x64` — CI equivalent
- `Build\Clean.cmd` — clean outputs
- `nuget restore` once before first build
- `Version.ps1` regenerates `src\VersionEx.h` (`Major.YY.Mdd.Build`, build number in `Versions\build.txt`)
@ -16,6 +15,20 @@ Scripts under `Build\` (PowerShell under `Build\scripts\`):
Default config is Release.
### Invoking MSBuild from PowerShell
`msbuild` is **not** on the PATH in PowerShell. Do **not** call it directly — it will fail with "not recognized". Locate it via `vswhere.exe` first:
```powershell
$msbuild = & "${env:ProgramFiles(x86)}\Microsoft Visual Studio\Installer\vswhere.exe" `
-latest -requires Microsoft.Component.MSBuild `
-find MSBuild\**\Bin\MSBuild.exe | Select-Object -First 1
& $msbuild Notepad3.sln /m /p:Configuration=Release /p:Platform=x64 /nologo /v:minimal
Write-Host "Exit code: $LASTEXITCODE"
```
Check `$LASTEXITCODE` (0 = success) and scan the last output lines for `-> Notepad3.exe` or `error C` entries. The verbose output is long — use `Select-String` or tail filtering rather than reading it all.
## Core Modules (`src\`)
- `Notepad3.c/h``wWinMain`, `MainWndProc`, global state structs (`Globals`, `Settings`, `Settings2`, `Flags`, `Paths`), `MsgCommand()` dispatcher with static sub-handlers (`_HandleFileCommands`, `_HandleEditBasicCommands`, `_HandleViewAndSettingsCommands`, etc.).

View File

@ -2848,7 +2848,7 @@ bool MRU_Load(LPMRULIST pmru, bool bFileProps)
for (int i = 0; i < pmru->iSize; ++i) {
WCHAR tchName[32] = { L'\0' };
StringCchPrintf(tchName, COUNTOF(tchName), L"%.2i", i + 1);
WCHAR tchItem[2048] = { L'\0' };
WCHAR tchItem[MRU_FNDRPL_ITEM_LEN] = { L'\0' };
if (IniSectionGetString(RegKey_Section, tchName, L"", tchItem, COUNTOF(tchItem))) {
size_t const len = StringCchLen(tchItem, 0);
if ((len > 1) && (tchItem[0] == L'"') && (tchItem[len - 1] == L'"')) {
@ -2890,7 +2890,7 @@ void MRU_Save(LPMRULIST pmru)
if (OpenSettingsFile(__func__)) {
WCHAR tchName[32] = { L'\0' };
WCHAR tchItem[2048] = { L'\0' };
WCHAR tchItem[MRU_FNDRPL_ITEM_LEN] = { L'\0' };
const WCHAR* const RegKey_Section = pmru->szRegKey;
IniSectionClear(pmru->szRegKey, false);

View File

@ -6241,7 +6241,7 @@ static LPCWSTR _EditGetFindStrg(HWND hwnd, const LPEDITFINDREPLACE lpefr, bool b
}
static HSTRINGW hfind = NULL;
// TODO: get rid of const FNDRPL_BUFFER size and StrgDestroy(hfind);
// TODO: StrgDestroy(hfind);
if (!hfind) {
hfind = StrgCreate(NULL);
@ -6279,7 +6279,10 @@ static LPCWSTR _EditGetFindStrg(HWND hwnd, const LPEDITFINDREPLACE lpefr, bool b
SetFindPattern(StrgGet(hfind));
if (lpefr->bWildcardSearch) {
LPWSTR const buf = StrgWriteAccessBuf(hfind, FNDRPL_BUFFER);
// _EscapeWildcards can expand each char to two (e.g. '|' -> '\|', '*' -> '.*'),
// so ensure the buffer holds at least 2× the current content length.
size_t const expandCap = (StrgGetLength(hfind) * 2) + 2;
LPWSTR const buf = StrgWriteAccessBuf(hfind, max(expandCap, (size_t)FNDRPL_BUFFER));
_EscapeWildcards(buf, StrgGetAllocLength(hfind), lpefr);
StrgSanitize(hfind);
}
@ -6476,38 +6479,6 @@ static void _DelayMarkAll(int delay)
static bool s_SaveMarkOccurrences = false;
static bool s_SaveMarkMatchVisible = false;
//=============================================================================
//
// EditBoxForPasteFixes()
//
static LRESULT CALLBACK EditBoxForPasteFixes(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam,
UINT_PTR uIdSubclass, DWORD_PTR dwRefData)
{
WCHAR* const s_wchBuffer = (WCHAR*)dwRefData;
if (s_wchBuffer) {
switch (uMsg) {
case WM_PASTE: {
EditGetClipboardW(s_wchBuffer, FNDRPL_BUFFER);
SendMessage(hwnd, EM_REPLACESEL, (WPARAM)TRUE, (LPARAM)s_wchBuffer);
}
return TRUE;
//case WM_LBUTTONDOWN:
// SendMessage(hwnd, EM_REPLACESEL, (WPARAM)TRUE, (LPARAM)L"X");
// return TRUE;
case WM_NCDESTROY:
RemoveWindowSubclass(hwnd, EditBoxForPasteFixes, uIdSubclass);
break;
default:
break;
}
}
return DefSubclassProc(hwnd, uMsg, wParam, lParam);
}
//=============================================================================
//
@ -6643,7 +6614,6 @@ static INT_PTR CALLBACK EditFindReplaceDlgProc(HWND hwnd, UINT umsg, WPARAM wPar
COMBOBOXINFO cbInfoF = { sizeof(COMBOBOXINFO) };
GetComboBoxInfo(GetDlgItem(hwnd, IDC_FINDTEXT), &cbInfoF);
if (cbInfoF.hwndItem) {
SetWindowSubclass(cbInfoF.hwndItem, EditBoxForPasteFixes, 0, (DWORD_PTR) &(s_wchBufOut[0]));
SHAutoComplete(cbInfoF.hwndItem, SHACF_FILESYS_ONLY | SHACF_AUTOAPPEND_FORCE_OFF | SHACF_AUTOSUGGEST_FORCE_OFF);
}
@ -6661,7 +6631,6 @@ static INT_PTR CALLBACK EditFindReplaceDlgProc(HWND hwnd, UINT umsg, WPARAM wPar
COMBOBOXINFO cbInfoR = { sizeof(COMBOBOXINFO) };
GetComboBoxInfo(GetDlgItem(hwnd, IDC_REPLACETEXT), &cbInfoR);
if (cbInfoR.hwndItem) {
SetWindowSubclass(cbInfoR.hwndItem, EditBoxForPasteFixes, 0, (DWORD_PTR) &(s_wchBufOut[0]));
SHAutoComplete(cbInfoR.hwndItem, SHACF_FILESYS_ONLY | SHACF_AUTOAPPEND_FORCE_OFF | SHACF_AUTOSUGGEST_FORCE_OFF);
}
}

View File

@ -221,7 +221,7 @@ typedef enum BUFFER_SIZES {
ANSI_CHAR_BUFFER = 258,
STYLE_EXTENSIONS_BUFFER = 512,
EXTENSIONS_FILTER_BUFFER = (STYLE_EXTENSIONS_BUFFER << 1),
FNDRPL_BUFFER = 4096, // TODO: eliminate limit
FNDRPL_BUFFER = 4096,
LONG_LINES_MARKER_LIMIT = 8192,
CMDLN_LENGTH_LIMIT = 8192
@ -327,6 +327,8 @@ typedef const EDITFINDREPLACE* const CLPCEDITFINDREPLACE;
#define MRU_NOCASE 1
#define MRU_UTF8 2
#define MRU_BMRK_SIZE 512
// INI line buffer for find/replace MRU items: pattern + surrounding quotes + NUL + spare
#define MRU_FNDRPL_ITEM_LEN (FNDRPL_BUFFER + 4)
typedef struct MRULIST {