From f18d89b36d6762324af8ff420230b409efd95d81 Mon Sep 17 00:00:00 2001 From: Andreas Kling Date: Sat, 16 Jan 2021 11:12:59 +0100 Subject: [PATCH] LibGfx: Make sure Bitmap::create_with_anon_fd() always closes if needed If this is called with ShouldCloseAnonymousFile::Yes, it's entrusted with closing the anon_fd and nobody else will take care of it. --- Userland/Libraries/LibGfx/Bitmap.cpp | 33 +++++++++++++++++----------- 1 file changed, 20 insertions(+), 13 deletions(-) diff --git a/Userland/Libraries/LibGfx/Bitmap.cpp b/Userland/Libraries/LibGfx/Bitmap.cpp index d04f9801bb..5de2da2062 100644 --- a/Userland/Libraries/LibGfx/Bitmap.cpp +++ b/Userland/Libraries/LibGfx/Bitmap.cpp @@ -28,6 +28,7 @@ #include #include #include +#include #include #include #include @@ -188,22 +189,28 @@ static bool check_size(const IntSize& size, BitmapFormat format, unsigned actual RefPtr Bitmap::create_with_anon_fd(BitmapFormat format, int anon_fd, const IntSize& size, ShouldCloseAnonymousFile should_close_anon_fd) { - if (size_would_overflow(format, size)) - return nullptr; + void* data = nullptr; + { + // If ShouldCloseAnonymousFile::Yes, it's our responsibility to close 'anon_fd' no matter what. + ScopeGuard close_guard = [&] { + if (should_close_anon_fd == ShouldCloseAnonymousFile::Yes) { + int rc = close(anon_fd); + ASSERT(rc == 0); + anon_fd = -1; + } + }; - const auto pitch = minimum_pitch(size.width(), format); - const auto data_size_in_bytes = size_in_bytes(pitch, size.height()); + if (size_would_overflow(format, size)) + return nullptr; - auto* data = mmap(nullptr, round_up_to_power_of_two(data_size_in_bytes, PAGE_SIZE), PROT_READ | PROT_WRITE, MAP_FILE | MAP_SHARED, anon_fd, 0); - if (data == MAP_FAILED) { - perror("mmap"); - return nullptr; - } + const auto pitch = minimum_pitch(size.width(), format); + const auto data_size_in_bytes = size_in_bytes(pitch, size.height()); - if (should_close_anon_fd == ShouldCloseAnonymousFile::Yes) { - int rc = close(anon_fd); - ASSERT(rc == 0); - anon_fd = -1; + data = mmap(nullptr, round_up_to_power_of_two(data_size_in_bytes, PAGE_SIZE), PROT_READ | PROT_WRITE, MAP_FILE | MAP_SHARED, anon_fd, 0); + if (data == MAP_FAILED) { + perror("mmap"); + return nullptr; + } } return adopt(*new Bitmap(format, anon_fd, size, data));