[FarGroup/FarManager] master: Refactoring (258e65ad8)

0 views
Skip to first unread message

farg...@farmanager.com

unread,
Jan 17, 2026, 6:31:01 PMJan 17
to farco...@googlegroups.com
Repository : https://github.com/FarGroup/FarManager
On branch : master
Link : https://github.com/FarGroup/FarManager/commit/258e65ad8ca318461ee4284db9c8641d88842fec

>---------------------------------------------------------------

commit 258e65ad8ca318461ee4284db9c8641d88842fec
Author: Alex Alabuzhev <alab...@gmail.com>
Date: Sat Jan 17 23:14:43 2026 +0000

Refactoring

Make checking struct sizes easier


>---------------------------------------------------------------

258e65ad8ca318461ee4284db9c8641d88842fec
far/common.hpp | 5 +++--
far/common.tests.cpp | 26 ++++++++++++++++++++------
far/dialog.cpp | 13 ++++++++-----
far/editor.cpp | 7 +++----
far/fileedit.cpp | 8 ++++----
far/panel.cpp | 38 +++++++++++++++++++++-----------------
far/plugin.hpp | 25 -------------------------
7 files changed, 59 insertions(+), 63 deletions(-)

diff --git a/far/common.hpp b/far/common.hpp
index 61ff20bc8..07169676c 100644
--- a/far/common.hpp
+++ b/far/common.hpp
@@ -42,9 +42,10 @@ bool CheckStructSize(const auto* s)
return s && (s->StructSize >= sizeof(*s));
}

-bool CheckNullOrStructSize(const auto* s)
+template<typename T, typename U>
+bool CheckStructSize(T const* const s, U T::* const Member)
{
- return !s || CheckStructSize(s);
+ return s && s->StructSize >= std::bit_cast<size_t>(&(s->*Member)) + sizeof(U) - std::bit_cast<size_t>(s);
}

template<class T>
diff --git a/far/common.tests.cpp b/far/common.tests.cpp
index 56af3e2a6..5d99af746 100644
--- a/far/common.tests.cpp
+++ b/far/common.tests.cpp
@@ -56,18 +56,32 @@ TEST_CASE("common.CheckStructSize")
struct s
{
size_t StructSize;
+
+ int OldField;
+ int NewField1;
+ int NewField2;
}
- const S1{ 1 }, S2{ sizeof(s) }, S3{ sizeof(s) + 1 };
+ const
+ S1{ 1 },
+ S2{ sizeof(s) },
+ S3{ sizeof(s) + 1 },
+ SLegacy1{ offsetof(s, NewField1) },
+ SLegacy2{ offsetof(s, NewField2) };

REQUIRE(!CheckStructSize(static_cast<s const*>(nullptr)));
REQUIRE(!CheckStructSize(&S1));
REQUIRE(CheckStructSize(&S2));
REQUIRE(CheckStructSize(&S3));
-
- REQUIRE(CheckNullOrStructSize(static_cast<s const*>(nullptr)));
- REQUIRE(!CheckNullOrStructSize(&S1));
- REQUIRE(CheckNullOrStructSize(&S2));
- REQUIRE(CheckNullOrStructSize(&S3));
+ REQUIRE(!CheckStructSize(&SLegacy1));
+ REQUIRE(!CheckStructSize(&SLegacy2));
+
+ REQUIRE(!CheckStructSize(&S1, &s::OldField));
+ REQUIRE(CheckStructSize(&S2, &s::NewField2));
+ REQUIRE(CheckStructSize(&S3, &s::NewField2));
+ REQUIRE(!CheckStructSize(&SLegacy1, &s::NewField1));
+ REQUIRE(!CheckStructSize(&SLegacy1, &s::NewField2));
+ REQUIRE(CheckStructSize(&SLegacy2, &s::NewField1));
+ REQUIRE(!CheckStructSize(&SLegacy2, &s::NewField2));
}

TEST_CASE("common.NullToEmpty")
diff --git a/far/dialog.cpp b/far/dialog.cpp
index fb9e105af..2bf8dc0e2 100644
--- a/far/dialog.cpp
+++ b/far/dialog.cpp
@@ -4848,13 +4848,16 @@ intptr_t Dialog::SendMessage(intptr_t Msg,intptr_t Param1,void* Param2)
case DM_LISTDELETE: // Param1=ID Param2=FarListDelete: StartIndex=BeginIndex, Count=количество (<=0 - все!)
{
const auto ListItems = static_cast<const FarListDelete*>(Param2);
- if(CheckNullOrStructSize(ListItems))
+ if (!ListItems)
{
- int Count;
- if (!ListItems || (Count=ListItems->Count) <= 0)
+ ListBox->clear();
+ }
+ else if (CheckStructSize(ListItems))
+ {
+ if (ListItems->Count <= 0)
ListBox->clear();
else
- ListBox->DeleteItem(ListItems->StartIndex,Count);
+ ListBox->DeleteItem(ListItems->StartIndex, ListItems->Count);
}
else return FALSE;

@@ -5731,7 +5734,7 @@ intptr_t Dialog::SendMessage(intptr_t Msg,intptr_t Param1,void* Param2)
case DM_GETDLGITEM:
{
const auto Item = static_cast<FarGetDialogItem*>(Param2);
- return (CheckNullOrStructSize(Item))? static_cast<intptr_t>(ConvertItemEx2(CurItem, Item, true)) : 0;
+ return !Item || CheckStructSize(Item)? static_cast<intptr_t>(ConvertItemEx2(CurItem, Item, true)) : 0;
}
/*****************************************************************/
case DM_GETDLGITEMSHORT:
diff --git a/far/editor.cpp b/far/editor.cpp
index 1bf34fd96..51eccccf5 100644
--- a/far/editor.cpp
+++ b/far/editor.cpp
@@ -5590,10 +5590,9 @@ int Editor::EditorControl(int Command, intptr_t Param1, void *Param2)

case ECTL_GETINFO:
{
- const auto InfoV1 = static_cast<EditorInfoV1*>(Param2);
- if (!CheckStructSize(InfoV1))
- return false;
const auto Info = static_cast<EditorInfo*>(Param2);
+ if (!CheckStructSize(Info, &EditorInfo::CodePage))
+ return false;

Info->EditorID = EditorID;
Info->WindowSizeX=ObjWidth();
@@ -5659,7 +5658,7 @@ int Editor::EditorControl(int Command, intptr_t Param1, void *Param2)
Info->CurState |= m_Flags.Check(FEDITOR_MODIFIED)? 0 : ECSTATE_SAVED;
Info->CodePage = GetCodePage();

- if (Info->StructSize > offsetof(EditorInfo, ClientArea))
+ if (CheckStructSize(Info, &EditorInfo::ClientArea))
{
Info->ClientArea = GetPosition().as<RECT>();
Info->ClientArea.left += LineNumbersWidth();
diff --git a/far/fileedit.cpp b/far/fileedit.cpp
index 9de27694c..e7b5aaf99 100644
--- a/far/fileedit.cpp
+++ b/far/fileedit.cpp
@@ -2411,7 +2411,7 @@ intptr_t FileEditor::EditorControl(int Command, intptr_t Param1, void *Param2)
case ECTL_GETBOOKMARKS:
{
const auto ebm = static_cast<EditorBookmarks*>(Param2);
- if (!m_Flags.Check(FFILEEDIT_OPENFAILED) && CheckNullOrStructSize(ebm))
+ if (!m_Flags.Check(FFILEEDIT_OPENFAILED) && (!ebm || CheckStructSize(ebm)))
{
size_t size;
if(Editor::InitSessionBookmarksForPlugin(ebm, m_editor->m_SavePos.size(), size))
@@ -2466,8 +2466,8 @@ intptr_t FileEditor::EditorControl(int Command, intptr_t Param1, void *Param2)
}
case ECTL_GETSESSIONBOOKMARKS:
{
- return CheckNullOrStructSize(static_cast<const EditorBookmarks*>(Param2))?
- m_editor->GetSessionBookmarksForPlugin(static_cast<EditorBookmarks*>(Param2)) : 0;
+ const auto ebm = static_cast<EditorBookmarks*>(Param2);
+ return !ebm || CheckStructSize(ebm)? m_editor->GetSessionBookmarksForPlugin(ebm) : 0;
}
case ECTL_GETTITLE:
{
@@ -2646,7 +2646,7 @@ intptr_t FileEditor::EditorControl(int Command, intptr_t Param1, void *Param2)
Info->Options|=EOPT_SHOWTITLEBAR;
if (Global->Opt->EdOpt.ShowKeyBar)
Info->Options|=EOPT_SHOWKEYBAR;
- if (Info->StructSize > offsetof(EditorInfo, WindowArea))
+ if (CheckStructSize(Info, &EditorInfo::WindowArea))
Info->WindowArea = GetPosition().as<RECT>();
}
return result;
diff --git a/far/panel.cpp b/far/panel.cpp
index a1d17e857..d40f36b2a 100644
--- a/far/panel.cpp
+++ b/far/panel.cpp
@@ -752,27 +752,31 @@ int Panel::SetPluginCommand(int Command,int Param1,void* Param2)
break;

case FCTL_GETPANELITEM:
- {
- if (GetType() == panel_type::FILE_PANEL && CheckNullOrStructSize(static_cast<FarGetPluginPanelItem*>(Param2)))
- Result = static_cast<int>(static_cast<FileList*>(this)->PluginGetPanelItem(Param1, static_cast<FarGetPluginPanelItem*>(Param2)));
- break;
- }
-
case FCTL_GETSELECTEDPANELITEM:
- {
- if (GetType() == panel_type::FILE_PANEL && CheckNullOrStructSize(static_cast<FarGetPluginPanelItem*>(Param2)))
- Result = static_cast<int>(static_cast<FileList*>(this)->PluginGetSelectedPanelItem(Param1, static_cast<FarGetPluginPanelItem*>(Param2)));
- break;
- }
-
case FCTL_GETCURRENTPANELITEM:
{
- if (GetType() == panel_type::FILE_PANEL && CheckNullOrStructSize(static_cast<FarGetPluginPanelItem*>(Param2)))
+ if (GetType() == panel_type::FILE_PANEL)
{
- PanelInfo Info{ sizeof(Info) };
- const auto DestPanel = static_cast<FileList*>(this);
- DestPanel->PluginGetPanelInfo(Info);
- Result = static_cast<int>(DestPanel->PluginGetPanelItem(static_cast<int>(Info.CurrentItem), static_cast<FarGetPluginPanelItem*>(Param2)));
+ if (const auto gppi = static_cast<FarGetPluginPanelItem*>(Param2); !gppi || CheckStructSize(gppi))
+ {
+ switch (Command)
+ {
+ case FCTL_GETCURRENTPANELITEM:
+ {
+ PanelInfo Info{ sizeof(Info) };
+ static_cast<FileList*>(this)->PluginGetPanelInfo(Info);
+ Param1 = static_cast<int>(Info.CurrentItem);
+ }
+ [[fallthrough]];
+ case FCTL_GETPANELITEM:
+ Result = static_cast<int>(static_cast<FileList*>(this)->PluginGetPanelItem(Param1, gppi));
+ break;
+
+ case FCTL_GETSELECTEDPANELITEM:
+ Result = static_cast<int>(static_cast<FileList*>(this)->PluginGetSelectedPanelItem(Param1, gppi));
+ break;
+ }
+ }
}
break;
}
diff --git a/far/plugin.hpp b/far/plugin.hpp
index 0948eac19..881b2e881 100644
--- a/far/plugin.hpp
+++ b/far/plugin.hpp
@@ -1976,31 +1976,6 @@ enum EDITOR_CURRENTSTATE
ECSTATE_LOCKED = 0x00000004,
};

-#ifdef FAR_USE_INTERNALS
-struct EditorInfoV1
-{
- size_t StructSize;
- intptr_t EditorID;
- intptr_t WindowSizeX;
- intptr_t WindowSizeY;
- intptr_t TotalLines;
- intptr_t CurLine;
- intptr_t CurPos;
- intptr_t CurTabPos;
- intptr_t TopScreenLine;
- intptr_t LeftPos;
- intptr_t Overtype;
- intptr_t BlockType;
- intptr_t BlockStartLine;
- uintptr_t Options;
- intptr_t TabSize;
- size_t BookmarkCount;
- size_t SessionBookmarkCount;
- uintptr_t CurState;
- uintptr_t CodePage;
-};
-#endif // END FAR_USE_INTERNALS
-
struct EditorInfo
{
size_t StructSize;


Reply all
Reply to author
Forward
0 new messages