Есть очень нехороший баг в паре мест с использованием неинициализированной памяти при матчинге макроподстановок. Конечный эффект зависит от того, у кого что в этой неинициализированной памяти было (на стеке), но в общем случае это рэндомная макроподстановка на случайные нажатия клавиш типа Ctrl.
Проявляется в разных местах, например, если при создании нового .txt нажать первой клавишей Ctrl или любой другой модификатор. Другое проявление бага - повтор предыдущего нажатия Enter на клавиши типа Ctrl и тп.
Суть бага в том, что
FSF.FarInputRecordToName не изменяет результирующий буфер, если не может определить имя клавиши (как то происходит на пресловутый Ctrl). В итоге
FindMacroKey постоянно сравнивает неинициализированную память с именем хоткея макросов.
Место бага 1 (рэндомный матчинг макро):
Code: Select all
static const TMacro *FindMacroKey (const TLang *lng, const INPUT_RECORD *Rec)
{
wchar_t rKeyp[MAX_STR_LEN];
FSF.FarInputRecordToName (Rec, rKeyp, MAX_STR_LEN);
for (size_t i = 0; i < lng->macroColl.getCount(); i++)
{
const TMacro *mm = lng->macroColl[i];
if (wcscmp(mm->FARKey, rKeyp) == 0) return (mm);
}
return (nullptr);
}
место бага 2 (повтор предыдущего нажатия клавиши):
Code: Select all
wchar_t fKey[256];
FSF.FarInputRecordToName (&Info->Rec, fKey, _countof(fKey));
vState &= (SHIFT_PRESSED | RIGHT_ALT_PRESSED | LEFT_ALT_PRESSED | RIGHT_CTRL_PRESSED | LEFT_CTRL_PRESSED);
bool spORret = ((wcscmp(fKey, L"Enter") == 0) || (wcscmp(fKey, defExpandFKey) == 0));
Пофиксить можно так:
(
macro.cpp)
Code: Select all
static const TMacro *FindMacroKey (const TLang *lng, const INPUT_RECORD *Rec)
{
wchar_t rKeyp[MAX_STR_LEN];
rKeyp[0] = 0;
if (!FSF.FarInputRecordToName (Rec, rKeyp, MAX_STR_LEN))
return nullptr;
for (size_t i = 0; i < lng->macroColl.getCount(); i++)
{
const TMacro *mm = lng->macroColl[i];
if (mm->FARKey.empty())
continue;
if (wcscmp(mm->FARKey, rKeyp) == 0)
return (mm);
}
return (nullptr);
}
и в
editorinput.cpp:
Code: Select all
fKey[0] = 0;
FSF.FarInputRecordToName (&Info->Rec, fKey, _countof(fKey));