[aseprite] 190/308: Fix crash pasting a document range from a closed document

Tobias Hansen thansen at moszumanska.debian.org
Tue Mar 8 02:45:09 UTC 2016


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

thansen pushed a commit to branch master
in repository aseprite.

commit 4dedc1e8d276367667f28dc148a1553557805def
Author: David Capello <davidcapello at gmail.com>
Date:   Sat Jan 30 09:13:46 2016 -0300

    Fix crash pasting a document range from a closed document
    
    Steps to reproduce the crash without this patch:
    1. Create a new sprite
    2. Copy the first cel from the Timeline
    3. Create a new sprite
    4. Close the first sprite
    5. Paste the copied cel to the second sprite
    
    The program crashed because the original sprite is invalid now. With this
    patch we observe the main DocumentsObserver to check when the document is
    closed/destroyed. In this way we can invalidate the clipboard content.
---
 src/app/app.cpp            |  4 ++-
 src/app/util/clipboard.cpp | 86 +++++++++++++++++++++++++++++++++-------------
 src/app/util/clipboard.h   | 10 +++++-
 3 files changed, 74 insertions(+), 26 deletions(-)

diff --git a/src/app/app.cpp b/src/app/app.cpp
index 014f823..5b23e6c 100644
--- a/src/app/app.cpp
+++ b/src/app/app.cpp
@@ -1,5 +1,5 @@
 // Aseprite
-// Copyright (C) 2001-2015  David Capello
+// Copyright (C) 2001-2016  David Capello
 //
 // This program is free software; you can redistribute it and/or modify
 // it under the terms of the GNU General Public License version 2 as
@@ -51,6 +51,7 @@
 #include "app/ui/toolbar.h"
 #include "app/ui/workspace.h"
 #include "app/ui_context.h"
+#include "app/util/clipboard.h"
 #include "app/webserver.h"
 #include "base/exception.h"
 #include "base/fs.h"
@@ -100,6 +101,7 @@ public:
   UIContext m_ui_context;
   RecentFiles m_recent_files;
   InputChain m_inputChain;
+  clipboard::ClipboardManager m_clipboardManager;
   // This is a raw pointer because we want to delete this explicitly.
   app::crash::DataRecovery* m_recovery;
 
diff --git a/src/app/util/clipboard.cpp b/src/app/util/clipboard.cpp
index 879edc4..e82b5a1 100644
--- a/src/app/util/clipboard.cpp
+++ b/src/app/util/clipboard.cpp
@@ -1,5 +1,5 @@
 // Aseprite
-// Copyright (C) 2001-2015  David Capello
+// Copyright (C) 2001-2016  David Capello
 //
 // This program is free software; you can redistribute it and/or modify
 // it under the terms of the GNU General Public License version 2 as
@@ -50,17 +50,29 @@ namespace app {
 
 namespace {
 
-  class ClipboardRange {
+  class ClipboardRange : public doc::DocumentsObserver {
   public:
-    ClipboardRange() : m_doc(NULL) {
+    ClipboardRange() : m_doc(nullptr) {
+    }
+
+    ~ClipboardRange() {
+      ASSERT(!m_doc);
+    }
+
+    void observeUIContext() {
+      UIContext::instance()->documents().addObserver(this);
+    }
+
+    void unobserveUIContext() {
+      UIContext::instance()->documents().removeObserver(this);
     }
 
     bool valid() {
-      return m_doc != NULL;
+      return (m_doc != nullptr);
     }
 
     void invalidate() {
-      m_doc = NULL;
+      m_doc = nullptr;
     }
 
     void setRange(Document* doc, const DocumentRange& range) {
@@ -71,6 +83,12 @@ namespace {
     Document* document() const { return m_doc; }
     DocumentRange range() const { return m_range; }
 
+    // DocumentsObserver impl
+    void onRemoveDocument(doc::Document* doc) override {
+      if (doc == m_doc)
+        invalidate();
+    }
+
   private:
     Document* m_doc;
     DocumentRange m_range;
@@ -78,29 +96,47 @@ namespace {
 
 }
 
+namespace clipboard {
+
 using namespace doc;
 
-static bool first_time = true;
 static base::SharedPtr<Palette> clipboard_palette;
 static PalettePicks clipboard_picks;
 static ImageRef clipboard_image;
 static base::SharedPtr<Mask> clipboard_mask;
 static ClipboardRange clipboard_range;
 
-static void on_exit_delete_clipboard()
+static ClipboardManager* g_instance = nullptr;
+
+ClipboardManager::ClipboardManager()
 {
+  ASSERT(!g_instance);
+  g_instance = this;
+
+  clipboard_range.observeUIContext();
+}
+
+ClipboardManager::~ClipboardManager()
+{
+  clipboard_range.invalidate();
+  clipboard_range.unobserveUIContext();
+
+  // Clean the whole clipboard
   clipboard_palette.reset();
   clipboard_image.reset();
   clipboard_mask.reset();
+
+  ASSERT(g_instance = this);
+  g_instance = nullptr;
 }
 
-static void set_clipboard_image(Image* image, Mask* mask, Palette* palette, bool set_system_clipboard)
+ClipboardManager* ClipboardManager::instance()
 {
-  if (first_time) {
-    first_time = false;
-    App::instance()->Exit.connect(&on_exit_delete_clipboard);
-  }
+  return g_instance;
+}
 
+static void set_clipboard_image(Image* image, Mask* mask, Palette* palette, bool set_system_clipboard)
+{
   clipboard_palette.reset(palette);
   clipboard_picks.clear();
   clipboard_image.reset(image);
@@ -135,7 +171,7 @@ static bool copy_from_document(const Site& site)
   return true;
 }
 
-clipboard::ClipboardFormat clipboard::get_current_format()
+ClipboardFormat get_current_format()
 {
 #ifdef USE_NATIVE_WIN32_CLIPBOARD
   if (win32_clipboard_contains_bitmap())
@@ -152,7 +188,7 @@ clipboard::ClipboardFormat clipboard::get_current_format()
     return ClipboardNone;
 }
 
-void clipboard::get_document_range_info(Document** document, DocumentRange* range)
+void get_document_range_info(Document** document, DocumentRange* range)
 {
   if (clipboard_range.valid()) {
     *document = clipboard_range.document();
@@ -163,12 +199,12 @@ void clipboard::get_document_range_info(Document** document, DocumentRange* rang
   }
 }
 
-void clipboard::clear_content()
+void clear_content()
 {
   set_clipboard_image(nullptr, nullptr, nullptr, true);
 }
 
-void clipboard::cut(ContextWriter& writer)
+void cut(ContextWriter& writer)
 {
   ASSERT(writer.document() != NULL);
   ASSERT(writer.sprite() != NULL);
@@ -190,7 +226,7 @@ void clipboard::cut(ContextWriter& writer)
   }
 }
 
-void clipboard::copy(const ContextReader& reader)
+void copy(const ContextReader& reader)
 {
   ASSERT(reader.document() != NULL);
 
@@ -201,7 +237,7 @@ void clipboard::copy(const ContextReader& reader)
   }
 }
 
-void clipboard::copy_range(const ContextReader& reader, const DocumentRange& range)
+void copy_range(const ContextReader& reader, const DocumentRange& range)
 {
   ASSERT(reader.document() != NULL);
 
@@ -216,7 +252,7 @@ void clipboard::copy_range(const ContextReader& reader, const DocumentRange& ran
     ->getTimeline()->activateClipboardRange();
 }
 
-void clipboard::copy_image(const Image* image, const Mask* mask, const Palette* pal)
+void copy_image(const Image* image, const Mask* mask, const Palette* pal)
 {
   set_clipboard_image(
     Image::createCopy(image),
@@ -224,7 +260,7 @@ void clipboard::copy_image(const Image* image, const Mask* mask, const Palette*
     (pal ? new Palette(*pal): nullptr), true);
 }
 
-void clipboard::copy_palette(const Palette* palette, const doc::PalettePicks& picks)
+void copy_palette(const Palette* palette, const doc::PalettePicks& picks)
 {
   if (!picks.picks())
     return;                     // Do nothing case
@@ -235,7 +271,7 @@ void clipboard::copy_palette(const Palette* palette, const doc::PalettePicks& pi
   clipboard_picks = picks;
 }
 
-void clipboard::paste()
+void paste()
 {
   Editor* editor = current_editor;
   if (editor == NULL)
@@ -472,7 +508,7 @@ void clipboard::paste()
   }
 }
 
-bool clipboard::get_image_size(gfx::Size& size)
+bool get_image_size(gfx::Size& size)
 {
 #ifdef USE_NATIVE_WIN32_CLIPBOARD
   // Get the image from the clipboard.
@@ -488,7 +524,7 @@ bool clipboard::get_image_size(gfx::Size& size)
 #endif
 }
 
-Palette* clipboard::get_palette()
+Palette* get_palette()
 {
   if (clipboard::get_current_format() == ClipboardPaletteEntries) {
     ASSERT(clipboard_palette);
@@ -498,9 +534,11 @@ Palette* clipboard::get_palette()
     return nullptr;
 }
 
-const PalettePicks& clipboard::get_palette_picks()
+const PalettePicks& get_palette_picks()
 {
   return clipboard_picks;
 }
 
+}  // namespace clipboard
+
 } // namespace app
diff --git a/src/app/util/clipboard.h b/src/app/util/clipboard.h
index 08ecef8..755a1e6 100644
--- a/src/app/util/clipboard.h
+++ b/src/app/util/clipboard.h
@@ -1,5 +1,5 @@
 // Aseprite
-// Copyright (C) 2001-2015  David Capello
+// Copyright (C) 2001-2016  David Capello
 //
 // This program is free software; you can redistribute it and/or modify
 // it under the terms of the GNU General Public License version 2 as
@@ -37,6 +37,14 @@ namespace app {
 
     // TODO Horrible API: refactor it (maybe a merge with she::clipboard).
 
+    class ClipboardManager {
+    public:
+      ClipboardManager();
+      ~ClipboardManager();
+
+      static ClipboardManager* instance();
+    };
+
     ClipboardFormat get_current_format();
     void get_document_range_info(Document** document, DocumentRange* range);
 

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



More information about the Pkg-games-commits mailing list