[colobot] 259/377: Fix crash related to TTF and PHYSFS

Didier Raboud odyx at moszumanska.debian.org
Wed Mar 30 13:34:24 UTC 2016


This is an automated email from the git hooks/post-receive script.

odyx pushed a commit to branch debian/master
in repository colobot.

commit c780148b77bd047b2291e2c2af7bec64163ec4ca
Author: Krzysztof Dermont <erihel at gmail.com>
Date:   Thu Feb 11 16:12:16 2016 +0100

    Fix crash related to TTF and PHYSFS
    
    TTF fonts will be loaded to memory instead of file pointers
    
    Added new class CSDLMemoryWrapper that loads data from PHYSFS into memory block
    and closes file after. This closes issues #519, #708 and #619
---
 src/CMakeLists.txt                          |  1 +
 src/common/resources/resourcemanager.cpp    |  5 ++
 src/common/resources/resourcemanager.h      |  2 +
 src/common/resources/sdl_file_wrapper.cpp   |  8 +--
 src/common/resources/sdl_memory_wrapper.cpp | 77 +++++++++++++++++++++++++++++
 src/common/resources/sdl_memory_wrapper.h   | 42 ++++++++++++++++
 src/graphics/engine/text.cpp                |  6 +--
 7 files changed, 132 insertions(+), 9 deletions(-)

diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index 35809a4..f0012b1 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -98,6 +98,7 @@ set(BASE_SOURCES
     common/resources/outputstreambuffer.cpp
     common/resources/resourcemanager.cpp
     common/resources/sdl_file_wrapper.cpp
+    common/resources/sdl_memory_wrapper.cpp
     common/resources/sndfile_wrapper.cpp
     common/restext.cpp
     common/settings.cpp
diff --git a/src/common/resources/resourcemanager.cpp b/src/common/resources/resourcemanager.cpp
index a81ac5d..dcf9ccb 100644
--- a/src/common/resources/resourcemanager.cpp
+++ b/src/common/resources/resourcemanager.cpp
@@ -114,6 +114,11 @@ std::unique_ptr<CSDLFileWrapper> CResourceManager::GetSDLFileHandler(const std::
     return MakeUnique<CSDLFileWrapper>(CleanPath(filename));
 }
 
+std::unique_ptr<CSDLMemoryWrapper> CResourceManager::GetSDLMemoryHandler(const std::string &filename)
+{
+    return MakeUnique<CSDLMemoryWrapper>(CleanPath(filename));
+}
+
 std::unique_ptr<CSNDFileWrapper> CResourceManager::GetSNDFileHandler(const std::string &filename)
 {
     return MakeUnique<CSNDFileWrapper>(CleanPath(filename));
diff --git a/src/common/resources/resourcemanager.h b/src/common/resources/resourcemanager.h
index 07870ec..692ea95 100644
--- a/src/common/resources/resourcemanager.h
+++ b/src/common/resources/resourcemanager.h
@@ -20,6 +20,7 @@
 #pragma once
 
 #include "common/resources/sdl_file_wrapper.h"
+#include "common/resources/sdl_memory_wrapper.h"
 #include "common/resources/sndfile_wrapper.h"
 
 #include <memory>
@@ -41,6 +42,7 @@ public:
     static std::string GetSaveLocation();
 
     static std::unique_ptr<CSDLFileWrapper> GetSDLFileHandler(const std::string &filename);
+    static std::unique_ptr<CSDLMemoryWrapper> GetSDLMemoryHandler(const std::string &filename);
     static std::unique_ptr<CSNDFileWrapper> GetSNDFileHandler(const std::string &filename);
 
     //! Check if file exists
diff --git a/src/common/resources/sdl_file_wrapper.cpp b/src/common/resources/sdl_file_wrapper.cpp
index 97cd2ee..c4f782f 100644
--- a/src/common/resources/sdl_file_wrapper.cpp
+++ b/src/common/resources/sdl_file_wrapper.cpp
@@ -24,10 +24,6 @@
 
 #include <physfs.h>
 
-namespace
-{
-    const Uint32 PHYSFS_RWOPS_TYPE = 0xc010b04f;
-}
 
 CSDLFileWrapper::CSDLFileWrapper(const std::string& filename)
     : m_rwops(nullptr)
@@ -52,7 +48,7 @@ CSDLFileWrapper::CSDLFileWrapper(const std::string& filename)
         return;
     }
 
-    m_rwops->type = PHYSFS_RWOPS_TYPE; //TODO: Documentation recommends to leave SDL_RWOPS_UNKNOWN here for application-defined RWops. Did that change in SDL2?
+    m_rwops->type = SDL_RWOPS_UNKNOWN;
     m_rwops->hidden.unknown.data1 = file;
     m_rwops->seek = SDLSeek;
     m_rwops->read = SDLRead;
@@ -109,7 +105,7 @@ int CSDLFileWrapper::SDLCloseWithFreeRW(SDL_RWops *context)
 
 bool CSDLFileWrapper::CheckSDLContext(SDL_RWops *context)
 {
-    if (context->type != PHYSFS_RWOPS_TYPE)
+    if (context->type != SDL_RWOPS_UNKNOWN)
     {
         SDL_SetError("Wrong kind of RWops");
         return false;
diff --git a/src/common/resources/sdl_memory_wrapper.cpp b/src/common/resources/sdl_memory_wrapper.cpp
new file mode 100644
index 0000000..d265d84
--- /dev/null
+++ b/src/common/resources/sdl_memory_wrapper.cpp
@@ -0,0 +1,77 @@
+/*
+ * This file is part of the Colobot: Gold Edition source code
+ * Copyright (C) 2001-2015, Daniel Roux, EPSITEC SA & TerranovaTeam
+ * http://epsitec.ch; http://colobot.info; http://github.com/colobot
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see http://gnu.org/licenses
+ */
+
+
+#include "common/resources/sdl_memory_wrapper.h"
+
+#include "common/logger.h"
+
+#include <physfs.h>
+
+
+CSDLMemoryWrapper::CSDLMemoryWrapper(const std::string& filename)
+    : m_rwops(nullptr)
+{
+    if (!PHYSFS_isInit())
+    {
+        GetLogger()->Error("PHYSFS not initialized!\n");
+        return;
+    }
+
+    PHYSFS_File *file = PHYSFS_openRead(filename.c_str());
+    if (file == nullptr)
+    {
+        GetLogger()->Error("Error opening file with PHYSFS: \"%s\"\n", filename.c_str());
+        return;
+    }
+
+    PHYSFS_sint64 length = PHYSFS_fileLength(file);
+    m_buffer = new char[length];
+    if (PHYSFS_read(file, m_buffer, 1, length) != length)
+    {
+        GetLogger()->Error("Unable to read data for \"%s\"\n", filename.c_str());
+        PHYSFS_close(file);
+        return;
+    }
+    PHYSFS_close(file);
+    m_rwops = SDL_RWFromMem(m_buffer, length);
+
+    if (m_rwops == nullptr)
+    {
+        GetLogger()->Error("Unable to allocate SDL_RWops for \"%s\"\n", filename.c_str());
+        return;
+    }
+}
+
+CSDLMemoryWrapper::~CSDLMemoryWrapper()
+{
+    SDL_FreeRW(m_rwops);
+    delete []m_buffer;
+}
+
+SDL_RWops* CSDLMemoryWrapper::GetHandler()
+{
+    return m_rwops;
+}
+
+bool CSDLMemoryWrapper::IsOpen() const
+{
+    return m_rwops != nullptr;
+}
+
diff --git a/src/common/resources/sdl_memory_wrapper.h b/src/common/resources/sdl_memory_wrapper.h
new file mode 100644
index 0000000..f446efd
--- /dev/null
+++ b/src/common/resources/sdl_memory_wrapper.h
@@ -0,0 +1,42 @@
+/*
+ * This file is part of the Colobot: Gold Edition source code
+ * Copyright (C) 2001-2015, Daniel Roux, EPSITEC SA & TerranovaTeam
+ * http://epsitec.ch; http://colobot.info; http://github.com/colobot
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see http://gnu.org/licenses
+ */
+
+
+#pragma once
+
+#include <string>
+
+#include <SDL.h>
+
+class CSDLMemoryWrapper
+{
+public:
+    CSDLMemoryWrapper(const std::string& filename);
+    ~CSDLMemoryWrapper();
+
+    CSDLMemoryWrapper(const CSDLMemoryWrapper&) = delete;
+    CSDLMemoryWrapper& operator=(const CSDLMemoryWrapper&) = delete;
+
+    bool IsOpen() const;
+    SDL_RWops* GetHandler();
+
+private:
+    SDL_RWops* m_rwops;
+    char *m_buffer;
+};
diff --git a/src/graphics/engine/text.cpp b/src/graphics/engine/text.cpp
index f5028d1..84f5f91 100644
--- a/src/graphics/engine/text.cpp
+++ b/src/graphics/engine/text.cpp
@@ -60,11 +60,11 @@ struct MultisizeFont
  */
 struct CachedFont
 {
-    std::unique_ptr<CSDLFileWrapper> fontFile;
+    std::unique_ptr<CSDLMemoryWrapper> fontFile;
     TTF_Font* font = nullptr;
     std::map<UTF8Char, CharTexture> cache;
 
-    CachedFont(std::unique_ptr<CSDLFileWrapper> fontFile, int pointSize)
+    CachedFont(std::unique_ptr<CSDLMemoryWrapper> fontFile, int pointSize)
         : fontFile(std::move(fontFile))
     {
         font = TTF_OpenFontRW(this->fontFile->GetHandler(), 0, pointSize);
@@ -980,7 +980,7 @@ CachedFont* CText::GetOrOpenFont(FontType font, float size)
         return m_lastCachedFont;
     }
 
-    auto file = CResourceManager::GetSDLFileHandler(mf->fileName);
+    auto file = CResourceManager::GetSDLMemoryHandler(mf->fileName);
     if (!file->IsOpen())
     {
         m_error = std::string("Unable to open file");

-- 
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-games/colobot.git



More information about the Pkg-games-commits mailing list