From 5873a7a1571de3a6f33711802d9ac8430fb2d9d5 Mon Sep 17 00:00:00 2001 From: Chris Thrasher Date: Mon, 8 Jul 2024 10:12:20 -0600 Subject: [PATCH] Fix null pointer dereference when creating fullscreen window Regression introduced in 7556d1b --- include/SFML/Window/WindowBase.hpp | 13 ------- src/SFML/Window/Window.cpp | 6 ---- src/SFML/Window/WindowBase.cpp | 54 ------------------------------ src/SFML/Window/WindowImpl.cpp | 52 +++++++++++++++++++--------- src/SFML/Window/WindowImpl.hpp | 14 -------- 5 files changed, 37 insertions(+), 102 deletions(-) diff --git a/include/SFML/Window/WindowBase.hpp b/include/SFML/Window/WindowBase.hpp index 5ebbba8f3..0b6ec38ab 100644 --- a/include/SFML/Window/WindowBase.hpp +++ b/include/SFML/Window/WindowBase.hpp @@ -491,19 +491,6 @@ protected: private: friend class Window; - //////////////////////////////////////////////////////////// - /// \brief Create (or recreate) the window - /// - /// Implementation detail for sharing underlying implementation - /// with sf::Window - /// - /// \param mode Video mode to use (defines the width, height and depth of the rendering area of the window) - /// \param style %Window style, a bitwise OR combination of sf::Style enumerators - /// \param state %Window state - /// - //////////////////////////////////////////////////////////// - void create(VideoMode mode, std::uint32_t& style, State& state); - //////////////////////////////////////////////////////////// /// \brief Processes an event before it is sent to the user /// diff --git a/src/SFML/Window/Window.cpp b/src/SFML/Window/Window.cpp index ad18d1a77..6d7abe6b1 100644 --- a/src/SFML/Window/Window.cpp +++ b/src/SFML/Window/Window.cpp @@ -84,9 +84,6 @@ void Window::create(VideoMode mode, const String& title, std::uint32_t style, St //////////////////////////////////////////////////////////// void Window::create(VideoMode mode, const String& title, std::uint32_t style, State state, const ContextSettings& settings) { - // Delegate to base class for creation logic - WindowBase::create(mode, style, state); - // Recreate the window implementation m_impl = priv::WindowImpl::create(mode, title, style, state, settings); @@ -108,9 +105,6 @@ void Window::create(WindowHandle handle) //////////////////////////////////////////////////////////// void Window::create(WindowHandle handle, const ContextSettings& settings) { - // Destroy the previous window implementation - close(); - // Recreate the window implementation WindowBase::create(handle); diff --git a/src/SFML/Window/WindowBase.cpp b/src/SFML/Window/WindowBase.cpp index 313fd87e2..3f84478d8 100644 --- a/src/SFML/Window/WindowBase.cpp +++ b/src/SFML/Window/WindowBase.cpp @@ -35,12 +35,8 @@ #include #include -#include - #include #include -#include -#include #include #include @@ -88,8 +84,6 @@ WindowBase& WindowBase::operator=(WindowBase&&) noexcept = default; //////////////////////////////////////////////////////////// void WindowBase::create(VideoMode mode, const String& title, std::uint32_t style, State state) { - WindowBase::create(mode, style, state); - // Recreate the window implementation m_impl = priv::WindowImpl::create(mode, title, @@ -111,9 +105,6 @@ void WindowBase::create(VideoMode mode, const String& title, std::uint32_t style //////////////////////////////////////////////////////////// void WindowBase::create(WindowHandle handle) { - // Destroy the previous window implementation - close(); - // Recreate the window implementation m_impl = priv::WindowImpl::create(handle); @@ -366,51 +357,6 @@ void WindowBase::onResize() } -//////////////////////////////////////////////////////////// -void WindowBase::create(VideoMode mode, std::uint32_t& style, State& state) -{ - // Destroy the previous window implementation - close(); - - // Fullscreen style requires some tests - if (state == State::Fullscreen) - { - // Make sure there's not already a fullscreen window (only one is allowed) - if (m_impl->getFullscreenWindow()) - { - err() << "Creating two fullscreen windows is not allowed, switching to windowed mode" << std::endl; - state = State::Windowed; - } - else - { - // Make sure that the chosen video mode is compatible - if (!mode.isValid()) - { - err() << "The requested video mode is not available, switching to a valid mode" << std::endl; - assert(!VideoMode::getFullscreenModes().empty() && "No video modes available"); - mode = VideoMode::getFullscreenModes()[0]; - err() << " VideoMode: { size: { " << mode.size.x << ", " << mode.size.y - << " }, bitsPerPixel: " << mode.bitsPerPixel << " }" << std::endl; - } - - // Update the fullscreen window - m_impl->setFullscreenWindow(); - } - } - -// Check validity of style according to the underlying platform -#if defined(SFML_SYSTEM_IOS) || defined(SFML_SYSTEM_ANDROID) - if (state == State::Fullscreen) - style &= ~static_cast(Style::Titlebar); - else - style |= Style::Titlebar; -#else - if ((style & Style::Close) || (style & Style::Resize)) - style |= Style::Titlebar; -#endif -} - - //////////////////////////////////////////////////////////// void WindowBase::filterEvent(const Event& event) { diff --git a/src/SFML/Window/WindowImpl.cpp b/src/SFML/Window/WindowImpl.cpp index 208e71343..67317a4c6 100644 --- a/src/SFML/Window/WindowImpl.cpp +++ b/src/SFML/Window/WindowImpl.cpp @@ -31,12 +31,14 @@ #include #include +#include #include #include #include #include #include +#include #include @@ -118,7 +120,41 @@ std::unique_ptr WindowImpl::create( State state, const ContextSettings& settings) { - return std::make_unique(mode, title, style, state, settings); + // Fullscreen style requires some tests + if (state == State::Fullscreen) + { + // Make sure there's not already a fullscreen window (only one is allowed) + if (WindowImplImpl::fullscreenWindow != nullptr) + { + err() << "Creating two fullscreen windows is not allowed, switching to windowed mode" << std::endl; + state = State::Windowed; + } + // Make sure that the chosen video mode is compatible + else if (!mode.isValid()) + { + err() << "The requested video mode is not available, switching to a valid mode" << std::endl; + assert(!VideoMode::getFullscreenModes().empty() && "No video modes available"); + mode = VideoMode::getFullscreenModes()[0]; + err() << " VideoMode: { size: { " << mode.size.x << ", " << mode.size.y + << " }, bitsPerPixel: " << mode.bitsPerPixel << " }" << std::endl; + } + } + + // Check validity of style according to the underlying platform +#if defined(SFML_SYSTEM_IOS) || defined(SFML_SYSTEM_ANDROID) + if (state == State::Fullscreen) + style &= ~static_cast(Style::Titlebar); + else + style |= Style::Titlebar; +#else + if ((style & Style::Close) || (style & Style::Resize)) + style |= Style::Titlebar; +#endif + + auto windowImpl = std::make_unique(mode, title, style, state, settings); + if (state == State::Fullscreen) + WindowImplImpl::fullscreenWindow = windowImpl.get(); + return windowImpl; } @@ -362,18 +398,4 @@ bool WindowImpl::createVulkanSurface([[maybe_unused]] const VkInstance& #endif } - -//////////////////////////////////////////////////////////// -const WindowImpl* WindowImpl::getFullscreenWindow() const -{ - return WindowImplImpl::fullscreenWindow; -} - - -//////////////////////////////////////////////////////////// -void WindowImpl::setFullscreenWindow() const -{ - WindowImplImpl::fullscreenWindow = this; -} - } // namespace sf::priv diff --git a/src/SFML/Window/WindowImpl.hpp b/src/SFML/Window/WindowImpl.hpp index 0b53c290c..fe2341f6f 100644 --- a/src/SFML/Window/WindowImpl.hpp +++ b/src/SFML/Window/WindowImpl.hpp @@ -305,20 +305,6 @@ public: //////////////////////////////////////////////////////////// bool createVulkanSurface(const VkInstance& instance, VkSurfaceKHR& surface, const VkAllocationCallbacks* allocator) const; - //////////////////////////////////////////////////////////// - /// \brief Get the fullscreen window - /// - /// \return The fullscreen window or a null pointer if there is none - /// - //////////////////////////////////////////////////////////// - [[nodiscard]] const WindowImpl* getFullscreenWindow() const; - - //////////////////////////////////////////////////////////// - /// \brief Set a window as the fullscreen window - /// - //////////////////////////////////////////////////////////// - void setFullscreenWindow() const; - protected: //////////////////////////////////////////////////////////// /// \brief Default constructor