From 660c3fd46f5b3c05467857f06487a4756c039417 Mon Sep 17 00:00:00 2001 From: scawful Date: Sat, 27 Sep 2025 22:03:03 -0400 Subject: [PATCH] Enhance CMake configuration and improve string safety in source files - Updated CMakeLists.txt to silence C++23 deprecation warnings and added definitions for intrinsic int128 support. - Modified GitHub Actions workflow to handle missing asset directories gracefully and ensure correct versioning in Info.plist. - Refactored string handling in multiple source files to use std::memcpy for safer string copying, preventing potential buffer overflows. - Improved font loading logic and ensured consistent handling of theme properties in the editor. --- .github/workflows/release.yml | 47 +++++++++++++++---- CMakeLists.txt | 12 ++++- cmake/absl.cmake | 7 +++ src/app/core/platform/font_loader.cc | 15 ++++-- .../editor/dungeon/dungeon_object_selector.cc | 7 ++- src/app/editor/editor_manager.cc | 15 ++++-- src/app/gui/theme_manager.cc | 19 +++++--- src/yaze.cc | 5 +- 8 files changed, 98 insertions(+), 29 deletions(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index b9f08684..5219136c 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -152,10 +152,11 @@ jobs: # Use the existing bundle and just update it cp -r build/bin/yaze.app ./Yaze.app # Add additional resources to the bundle - cp -r assets "Yaze.app/Contents/Resources/" - # Update Info.plist if needed + cp -r assets "Yaze.app/Contents/Resources/" 2>/dev/null || echo "assets directory not found" + # Update Info.plist with correct version if [ -f "cmake/yaze.plist.in" ]; then - cp cmake/yaze.plist.in "Yaze.app/Contents/Info.plist" + VERSION_NUM=$(echo "${{ needs.validate-and-prepare.outputs.tag_name }}" | sed 's/^v//') + sed "s/@yaze_VERSION@/$VERSION_NUM/g" cmake/yaze.plist.in > "Yaze.app/Contents/Info.plist" fi else echo "No bundle found, creating manual bundle" @@ -163,8 +164,35 @@ jobs: mkdir -p "Yaze.app/Contents/MacOS" mkdir -p "Yaze.app/Contents/Resources" cp build/bin/yaze "Yaze.app/Contents/MacOS/" - cp -r assets "Yaze.app/Contents/Resources/" - cp cmake/yaze.plist.in "Yaze.app/Contents/Info.plist" + cp -r assets "Yaze.app/Contents/Resources/" 2>/dev/null || echo "assets directory not found" + # Create Info.plist with correct version + if [ -f "cmake/yaze.plist.in" ]; then + VERSION_NUM=$(echo "${{ needs.validate-and-prepare.outputs.tag_name }}" | sed 's/^v//') + sed "s/@yaze_VERSION@/$VERSION_NUM/g" cmake/yaze.plist.in > "Yaze.app/Contents/Info.plist" + else + # Create a basic Info.plist + VERSION_NUM=$(echo "${{ needs.validate-and-prepare.outputs.tag_name }}" | sed 's/^v//') + cat > "Yaze.app/Contents/Info.plist" << EOF + + + + + CFBundleExecutable + yaze + CFBundleIdentifier + com.yaze.editor + CFBundleName + Yaze + CFBundleVersion + $VERSION_NUM + CFBundleShortVersionString + $VERSION_NUM + CFBundlePackageType + APPL + + +EOF + fi fi # Create DMG @@ -225,7 +253,7 @@ jobs: if: runner.os == 'macOS' run: | # Install Homebrew dependencies needed for UI tests and full builds - brew install pkg-config libpng boost abseil ninja + brew install pkg-config libpng boost abseil ninja gtk+3 - name: Setup build environment run: | @@ -248,6 +276,7 @@ jobs: -DYAZE_ENABLE_ROM_TESTS=OFF \ -DYAZE_ENABLE_EXPERIMENTAL_TESTS=OFF \ -DYAZE_INSTALL_LIB=OFF \ + -DYAZE_MINIMAL_BUILD=OFF \ -GNinja # Set up vcpkg for Windows builds with fallback @@ -411,10 +440,10 @@ jobs: $ErrorActionPreference = "Stop" # Determine executable path based on platform - if (${{ runner.os }} -eq "Windows") { + if ("${{ runner.os }}" -eq "Windows") { $exePath = "build\bin\${{ env.BUILD_TYPE }}\yaze.exe" - } elseif (${{ runner.os }} -eq "macOS") { - $exePath = "build/bin/yaze" + } elseif ("${{ runner.os }}" -eq "macOS") { + $exePath = "build/bin/yaze.app/Contents/MacOS/yaze" } else { $exePath = "build/bin/yaze" } diff --git a/CMakeLists.txt b/CMakeLists.txt index 75cf4835..2653aa9a 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -111,13 +111,23 @@ if(MSVC) _CRT_SECURE_NO_WARNINGS _CRT_NONSTDC_NO_WARNINGS SILENCE_CXX23_DEPRECATIONS + _SILENCE_CXX23_DEPRECATION_WARNING NOMINMAX # Disable min/max macros WIN32_LEAN_AND_MEAN # Reduce Windows header bloat strncasecmp=_strnicmp strcasecmp=_stricmp ) else() - target_compile_options(yaze_common INTERFACE -Wall -Wextra -Wpedantic) + target_compile_options(yaze_common INTERFACE + -Wall -Wextra -Wpedantic + -Wno-deprecated-declarations # Silence deprecation warnings + -Wno-c++23-compat # Silence C++23 compatibility warnings + ) + # Add C++23 deprecation silencing for GCC/Clang + target_compile_definitions(yaze_common INTERFACE + _SILENCE_CXX23_DEPRECATION_WARNING + ABSL_HAVE_INTRINSIC_INT128=1 # Enable intrinsic int128 support + ) endif() # Abseil Standard Specifications diff --git a/cmake/absl.cmake b/cmake/absl.cmake index b2702b5c..a9922c27 100644 --- a/cmake/absl.cmake +++ b/cmake/absl.cmake @@ -15,6 +15,13 @@ set(ABSL_PROPAGATE_CXX_STD ON) set(ABSL_CXX_STANDARD 23) set(ABSL_USE_GOOGLETEST_HEAD ON) set(ABSL_ENABLE_INSTALL ON) + +# Silence C++23 deprecation warnings for Abseil int128 +if(MSVC) + add_definitions(-DSILENCE_CXX23_DEPRECATIONS) +else() + add_definitions(-D_SILENCE_CXX23_DEPRECATION_WARNING) +endif() set( ABSL_TARGETS absl::strings diff --git a/src/app/core/platform/font_loader.cc b/src/app/core/platform/font_loader.cc index 8f522685..e3216ee6 100644 --- a/src/app/core/platform/font_loader.cc +++ b/src/app/core/platform/font_loader.cc @@ -3,6 +3,11 @@ #include #include #include +#include +#include +#include +# + #include "absl/status/status.h" #include "absl/strings/str_cat.h" @@ -98,11 +103,11 @@ absl::Status LoadPackageFonts() { if (font_registry.fonts.empty()) { // Initialize the font names and sizes font_registry.fonts = { - {KARLA_REGULAR, FONT_SIZE_DEFAULT}, - {ROBOTO_MEDIUM, FONT_SIZE_DEFAULT}, - {COUSINE_REGULAR, FONT_SIZE_DEFAULT}, - {IBM_PLEX_JP, FONT_SIZE_DEFAULT}, - {DROID_SANS, FONT_SIZE_DROID_SANS}, + FontConfig{KARLA_REGULAR, FONT_SIZE_DEFAULT}, + FontConfig{ROBOTO_MEDIUM, FONT_SIZE_DEFAULT}, + FontConfig{COUSINE_REGULAR, FONT_SIZE_DEFAULT}, + FontConfig{IBM_PLEX_JP, FONT_SIZE_DEFAULT}, + FontConfig{DROID_SANS, FONT_SIZE_DROID_SANS}, }; } diff --git a/src/app/editor/dungeon/dungeon_object_selector.cc b/src/app/editor/dungeon/dungeon_object_selector.cc index fa3c2323..6358d054 100644 --- a/src/app/editor/dungeon/dungeon_object_selector.cc +++ b/src/app/editor/dungeon/dungeon_object_selector.cc @@ -1,5 +1,6 @@ #include "dungeon_object_selector.h" +#include #include #include @@ -1046,8 +1047,10 @@ void DungeonObjectSelector::DrawCompactPropertiesEditor() { static int music_id = 0; // Copy current values - std::strncpy(room_name, properties.name.c_str(), sizeof(room_name) - 1); - room_name[sizeof(room_name) - 1] = '\0'; + // Safe string copy with bounds checking + size_t name_len = std::min(properties.name.length(), sizeof(room_name) - 1); + std::memcpy(room_name, properties.name.c_str(), name_len); + room_name[name_len] = '\0'; dungeon_id = properties.dungeon_id; floor_level = properties.floor_level; is_boss_room = properties.is_boss_room; diff --git a/src/app/editor/editor_manager.cc b/src/app/editor/editor_manager.cc index 7621b501..4bc75a95 100644 --- a/src/app/editor/editor_manager.cc +++ b/src/app/editor/editor_manager.cc @@ -1,5 +1,6 @@ #include "editor_manager.h" +#include #include #include @@ -2254,8 +2255,11 @@ void EditorManager::DrawSessionSwitcher() { ImGui::SameLine(); if (ImGui::Button("Rename")) { session_to_rename_ = i; - std::strncpy(session_rename_buffer_, session.GetDisplayName().c_str(), sizeof(session_rename_buffer_) - 1); - session_rename_buffer_[sizeof(session_rename_buffer_) - 1] = '\0'; + // Safe string copy with bounds checking + const std::string& name = session.GetDisplayName(); + size_t copy_len = std::min(name.length(), sizeof(session_rename_buffer_) - 1); + std::memcpy(session_rename_buffer_, name.c_str(), copy_len); + session_rename_buffer_[copy_len] = '\0'; show_session_rename_dialog_ = true; } @@ -2431,8 +2435,11 @@ void EditorManager::DrawSessionManager() { ImGui::SameLine(); if (ImGui::Button("Rename")) { session_to_rename_ = i; - std::strncpy(session_rename_buffer_, session.GetDisplayName().c_str(), sizeof(session_rename_buffer_) - 1); - session_rename_buffer_[sizeof(session_rename_buffer_) - 1] = '\0'; + // Safe string copy with bounds checking + const std::string& name = session.GetDisplayName(); + size_t copy_len = std::min(name.length(), sizeof(session_rename_buffer_) - 1); + std::memcpy(session_rename_buffer_, name.c_str(), copy_len); + session_rename_buffer_[copy_len] = '\0'; show_session_rename_dialog_ = true; } diff --git a/src/app/gui/theme_manager.cc b/src/app/gui/theme_manager.cc index 257b6699..3b9b2fcd 100644 --- a/src/app/gui/theme_manager.cc +++ b/src/app/gui/theme_manager.cc @@ -1,5 +1,6 @@ #include "theme_manager.h" +#include #include #include #include @@ -1778,12 +1779,18 @@ void ThemeManager::ShowSimpleThemeEditor(bool* p_open) { ImGui::SameLine(); if (ImGui::Button("Reset to Current")) { edit_theme = current_theme_; - std::strncpy(theme_name, current_theme_.name.c_str(), sizeof(theme_name) - 1); - theme_name[sizeof(theme_name) - 1] = '\0'; - std::strncpy(theme_description, current_theme_.description.c_str(), sizeof(theme_description) - 1); - theme_description[sizeof(theme_description) - 1] = '\0'; - std::strncpy(theme_author, current_theme_.author.c_str(), sizeof(theme_author) - 1); - theme_author[sizeof(theme_author) - 1] = '\0'; + // Safe string copy with bounds checking + size_t name_len = std::min(current_theme_.name.length(), sizeof(theme_name) - 1); + std::memcpy(theme_name, current_theme_.name.c_str(), name_len); + theme_name[name_len] = '\0'; + + size_t desc_len = std::min(current_theme_.description.length(), sizeof(theme_description) - 1); + std::memcpy(theme_description, current_theme_.description.c_str(), desc_len); + theme_description[desc_len] = '\0'; + + size_t author_len = std::min(current_theme_.author.length(), sizeof(theme_author) - 1); + std::memcpy(theme_author, current_theme_.author.c_str(), author_len); + theme_author[author_len] = '\0'; // Reset backup state since we're back to current theme if (theme_backup_made) { diff --git a/src/yaze.cc b/src/yaze.cc index f64636ba..710c9b6b 100644 --- a/src/yaze.cc +++ b/src/yaze.cc @@ -1,5 +1,6 @@ #include "yaze.h" +#include #include #include #include @@ -292,8 +293,8 @@ yaze_status yaze_load_messages(const zelda3_rom* rom, zelda3_message** messages, std::memcpy((*messages)[i].raw_data, msg.Data.data(), msg.Data.size()); (*messages)[i].parsed_text = new char[msg.ContentsParsed.length() + 1]; - std::strncpy((*messages)[i].parsed_text, msg.ContentsParsed.c_str(), - msg.ContentsParsed.length()); + // Safe string copy with bounds checking + std::memcpy((*messages)[i].parsed_text, msg.ContentsParsed.c_str(), msg.ContentsParsed.length()); (*messages)[i].parsed_text[msg.ContentsParsed.length()] = '\0'; (*messages)[i].is_compressed = false; // TODO: Detect compression