浏览代码

Merge pull request #3746 from IvanSavenko/fix_undefined_behavior

Fix discovered undefined behavior cases
Ivan Savenko 1 年之前
父节点
当前提交
0bd1c3c95d

+ 5 - 0
CMakeLists.txt

@@ -393,6 +393,11 @@ if(CMAKE_CXX_COMPILER_ID STREQUAL "GNU" OR NOT WIN32)
 		set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-error=array-bounds") # false positives in boost::multiarray during release build, keep as warning-only
 		set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-error=array-bounds") # false positives in boost::multiarray during release build, keep as warning-only
 	endif()
 	endif()
 
 
+	if(CMAKE_CXX_COMPILER_ID STREQUAL "GNU" AND NOT WIN32)
+		# For gcc 14+ we can use -fhardened instead
+		set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -D_FORTIFY_SOURCE=2 -D_GLIBCXX_ASSERTIONS -fstack-protector-strong -fstack-clash-protection -fcf-protection=full")
+	endif()
+
 	# Fix string inspection with lldb
 	# Fix string inspection with lldb
 	# https://stackoverflow.com/questions/58578615/cannot-inspect-a-stdstring-variable-in-lldb
 	# https://stackoverflow.com/questions/58578615/cannot-inspect-a-stdstring-variable-in-lldb
 	if(CMAKE_CXX_COMPILER_ID STREQUAL "Clang")
 	if(CMAKE_CXX_COMPILER_ID STREQUAL "Clang")

+ 0 - 6
Global.h

@@ -104,12 +104,6 @@ static_assert(sizeof(bool) == 1, "Bool needs to be 1 byte in size.");
 
 
 #define _USE_MATH_DEFINES
 #define _USE_MATH_DEFINES
 
 
-#ifndef NDEBUG
-// Enable additional debug checks from glibc / libstdc++ when building with enabled assertions
-// Since these defines must be declared BEFORE including glibc header we can not check for __GLIBCXX__ macro to detect that glibc is in use
-#  define _GLIBCXX_ASSERTIONS
-#endif
-
 #include <algorithm>
 #include <algorithm>
 #include <any>
 #include <any>
 #include <array>
 #include <array>

+ 7 - 0
client/CMusicHandler.cpp

@@ -322,6 +322,13 @@ void CSoundHandler::setCallback(int channel, std::function<void()> function)
 		iter->second.push_back(function);
 		iter->second.push_back(function);
 }
 }
 
 
+void CSoundHandler::resetCallback(int channel)
+{
+	boost::mutex::scoped_lock lockGuard(mutexCallbacks);
+
+	callbacks.erase(channel);
+}
+
 void CSoundHandler::soundFinishedCallback(int channel)
 void CSoundHandler::soundFinishedCallback(int channel)
 {
 {
 	boost::mutex::scoped_lock lockGuard(mutexCallbacks);
 	boost::mutex::scoped_lock lockGuard(mutexCallbacks);

+ 1 - 0
client/CMusicHandler.h

@@ -85,6 +85,7 @@ public:
 	void stopSound(int handler);
 	void stopSound(int handler);
 
 
 	void setCallback(int channel, std::function<void()> function);
 	void setCallback(int channel, std::function<void()> function);
+	void resetCallback(int channel);
 	void soundFinishedCallback(int channel);
 	void soundFinishedCallback(int channel);
 
 
 	int ambientGetRange() const;
 	int ambientGetRange() const;

+ 13 - 4
client/gui/EventDispatcher.cpp

@@ -213,12 +213,21 @@ void EventDispatcher::handleLeftButtonClick(const Point & position, int toleranc
 		if( i->receiveEvent(position, AEventsReceiver::LCLICK) || i == nearestElement)
 		if( i->receiveEvent(position, AEventsReceiver::LCLICK) || i == nearestElement)
 		{
 		{
 			if(isPressed)
 			if(isPressed)
+			{
+				i->mouseClickedState = isPressed;
 				i->clickPressed(position, lastActivated);
 				i->clickPressed(position, lastActivated);
+			}
+			else
+			{
+				if (i->mouseClickedState)
+				{
+					i->mouseClickedState = isPressed;
+					i->clickReleased(position, lastActivated);
+				}
+				else
+					i->mouseClickedState = isPressed;
+			}
 
 
-			if (i->mouseClickedState && !isPressed)
-				i->clickReleased(position, lastActivated);
-
-			i->mouseClickedState = isPressed;
 			lastActivated = false;
 			lastActivated = false;
 		}
 		}
 		else
 		else

+ 1 - 1
client/lobby/SelectionTab.cpp

@@ -155,12 +155,12 @@ SelectionTab::SelectionTab(ESelectionScreen Type)
 	OBJ_CONSTRUCTION;
 	OBJ_CONSTRUCTION;
 		
 		
 	generalSortingBy = getSortBySelectionScreen(tabType);
 	generalSortingBy = getSortBySelectionScreen(tabType);
+	sortingBy = _format;
 
 
 	bool enableUiEnhancements = settings["general"]["enableUiEnhancements"].Bool();
 	bool enableUiEnhancements = settings["general"]["enableUiEnhancements"].Bool();
 
 
 	if(tabType != ESelectionScreen::campaignList)
 	if(tabType != ESelectionScreen::campaignList)
 	{
 	{
-		sortingBy = _format;
 		background = std::make_shared<CPicture>(ImagePath::builtin("SCSELBCK.bmp"), 0, 6);
 		background = std::make_shared<CPicture>(ImagePath::builtin("SCSELBCK.bmp"), 0, 6);
 		pos = background->pos;
 		pos = background->pos;
 		inputName = std::make_shared<CTextInput>(inputNameRect, Point(-32, -25), ImagePath::builtin("GSSTRIP.bmp"), 0);
 		inputName = std::make_shared<CTextInput>(inputNameRect, Point(-32, -25), ImagePath::builtin("GSSTRIP.bmp"), 0);

+ 1 - 0
client/mainmenu/CPrologEpilogVideo.cpp

@@ -74,6 +74,7 @@ void CPrologEpilogVideo::show(Canvas & to)
 void CPrologEpilogVideo::clickPressed(const Point & cursorPosition)
 void CPrologEpilogVideo::clickPressed(const Point & cursorPosition)
 {
 {
 	close();
 	close();
+	CCS->soundh->resetCallback(voiceSoundHandle); // reset callback to avoid memory corruption since 'this' will be destroyed
 	CCS->soundh->stopSound(voiceSoundHandle);
 	CCS->soundh->stopSound(voiceSoundHandle);
 	CCS->soundh->stopSound(videoSoundHandle);
 	CCS->soundh->stopSound(videoSoundHandle);
 	if(exitCb)
 	if(exitCb)

+ 1 - 1
lib/CGameInterface.h

@@ -71,7 +71,7 @@ using TTeleportExitsList = std::vector<std::pair<ObjectInstanceID, int3>>;
 class DLL_LINKAGE CBattleGameInterface : public IBattleEventsReceiver
 class DLL_LINKAGE CBattleGameInterface : public IBattleEventsReceiver
 {
 {
 public:
 public:
-	bool human;
+	bool human = false;
 	PlayerColor playerID;
 	PlayerColor playerID;
 	std::string dllName;
 	std::string dllName;