[gtkmm/gtkmm-2-16] Correct misuse of container handle (bgo #586626)
- From: Daniel Elstner <daniel src gnome org>
- To: svn-commits-list gnome org
- Cc:
- Subject: [gtkmm/gtkmm-2-16] Correct misuse of container handle (bgo #586626)
- Date: Wed, 16 Sep 2009 15:20:57 +0000 (UTC)
commit 9171bfc30d06e81c8bc8daef0636a783af8cf8d3
Author: Daniel Elstner <danielk openismus com>
Date: Tue Sep 15 16:49:51 2009 +0200
Correct misuse of container handle (bgo #586626)
* gtk/src/clipboard.{ccg,hg} (Clipboard::wait_for_targets): Create
an intermediate array of allocated C strings and transfer ownership
on return, instead of trying to returned a handle to a container
with local scope. (Based on patch by Peter Clifton.)
(SignalProxy_TargetsReceived_gtk_callback): Correct another misuse
of the container handles similar to the above, except for the crash.
(SignalProxy_RichTextReceived_gtk_callback): Simplify the code and
plug a memory leak in the event of an exception.
ChangeLog | 13 ++++++
gtk/src/clipboard.ccg | 109 +++++++++++++++++++-----------------------------
2 files changed, 56 insertions(+), 66 deletions(-)
---
diff --git a/ChangeLog b/ChangeLog
index 54b4889..268f232 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,16 @@
+2009-09-15 Daniel Elstner <danielk openismus com>
+
+ Correct misuse of container handle (bgo #586626)
+
+ * gtk/src/clipboard.{ccg,hg} (Clipboard::wait_for_targets): Create
+ an intermediate array of allocated C strings and transfer ownership
+ on return, instead of trying to returned a handle to a container
+ with local scope. (Based on patch by Peter Clifton.)
+ (SignalProxy_TargetsReceived_gtk_callback): Correct another misuse
+ of the container handles similar to the above, except for the crash.
+ (SignalProxy_RichTextReceived_gtk_callback): Simplify the code and
+ plug a memory leak in the event of an exception.
+
2009-09-07 Murray Cumming <murrayc murrayc com>
* gtk/src/enums.hg: Include gtkmmconfig.h because we use
diff --git a/gtk/src/clipboard.ccg b/gtk/src/clipboard.ccg
index eff18bf..04ac5a9 100644
--- a/gtk/src/clipboard.ccg
+++ b/gtk/src/clipboard.ccg
@@ -1,6 +1,3 @@
-// -*- c++ -*-
-/* $Id: clipboard.ccg,v 1.11 2006/06/13 17:16:26 murrayc Exp $ */
-
/*
*
* Copyright 2002 The gtkmm Development Team
@@ -118,47 +115,33 @@ static void SignalProxy_Received_gtk_callback(GtkClipboard*, GtkSelectionData* s
delete the_slot;
}
-//This is not public API:
-typedef std::list<Glib::ustring> listStrings;
-static listStrings util_convert_atoms_to_strings(GdkAtom* targets, int n_targets)
+static void SignalProxy_TargetsReceived_gtk_callback(GtkClipboard*, GdkAtom* atoms,
+ gint n_atoms, gpointer data)
{
- listStrings listTargets;
+ Gtk::Clipboard::SlotTargetsReceived *const
+ slot = static_cast<Gtk::Clipboard::SlotTargetsReceived*>(data);
- //Add the targets to the C++ container:
- for(int i = 0; i < n_targets; i++)
+#ifdef GLIBMM_EXCEPTIONS_ENABLED
+ try
+#endif
{
- //Convert the atom to a string:
- char* atom_name = gdk_atom_name(targets[i]);
- if(atom_name)
- {
- listTargets.push_back( Glib::ustring(atom_name) );
- g_free(atom_name);
- }
- }
+ // TODO: This conversion should normally be performed in a custom
+ // Traits implementation. Alternatively, a real container could
+ // have been used as the argument instead of handle.
+ const unsigned int n_names = (n_atoms > 0) ? n_atoms : 0;
+ char** names = g_new(char*, n_names);
- return listTargets;
-}
+ std::transform(&atoms[0], &atoms[n_names], &names[0], &gdk_atom_name);
-static void SignalProxy_TargetsReceived_gtk_callback(GtkClipboard*, GdkAtom* atoms, gint n_atoms, gpointer data)
-{
- Gtk::Clipboard::SlotTargetsReceived* the_slot = static_cast<Gtk::Clipboard::SlotTargetsReceived*>(data);
-
- #ifdef GLIBMM_EXCEPTIONS_ENABLED
- try
- {
- #endif //GLIBMM_EXCEPTIONS_ENABLED
- listStrings listTargets = util_convert_atoms_to_strings(atoms, n_atoms);
- (*the_slot)(listTargets);
- //I guess that GTK+ does a g_free of the GdkAtoms* array itself, so we do not need to. murrayc.
- #ifdef GLIBMM_EXCEPTIONS_ENABLED
+ (*slot)(Glib::StringArrayHandle(names, n_names, Glib::OWNERSHIP_DEEP));
}
- catch(...)
+#ifdef GLIBMM_EXCEPTIONS_ENABLED
+ catch (...)
{
Glib::exception_handlers_invoke();
}
- #endif //GLIBMM_EXCEPTIONS_ENABLED
-
- delete the_slot; // the callback is only used once
+#endif
+ delete slot; // the callback is only used once
}
@@ -182,26 +165,26 @@ static void SignalProxy_TextReceived_gtk_callback(GtkClipboard*, const char* tex
delete the_slot; // the callback is only used once
}
-static void SignalProxy_RichTextReceived_gtk_callback(GtkClipboard*, GdkAtom format, const guint8* text, gsize length, void* data)
+static void SignalProxy_RichTextReceived_gtk_callback(GtkClipboard*, GdkAtom format,
+ const guint8* text, gsize length, void* data)
{
- Gtk::Clipboard::SlotRichTextReceived* the_slot = static_cast<Gtk::Clipboard::SlotRichTextReceived*>(data);
+ Gtk::Clipboard::SlotRichTextReceived *const
+ slot = static_cast<Gtk::Clipboard::SlotRichTextReceived*>(data);
- #ifdef GLIBMM_EXCEPTIONS_ENABLED
+#ifdef GLIBMM_EXCEPTIONS_ENABLED
try
+#endif
{
- #endif //GLIBMM_EXCEPTIONS_ENABLED
- gchar* format_atom_name = gdk_atom_name(format);
- (*the_slot)( (format_atom_name ? Glib::ustring(format_atom_name) : Glib::ustring()), (text ? std::string((char*)text, length) : std::string()) );
- g_free(format_atom_name);
- #ifdef GLIBMM_EXCEPTIONS_ENABLED
+ (*slot)(Glib::convert_return_gchar_ptr_to_ustring(gdk_atom_name(format)),
+ (text) ? std::string(reinterpret_cast<const char*>(text), length) : std::string());
}
+#ifdef GLIBMM_EXCEPTIONS_ENABLED
catch(...)
{
Glib::exception_handlers_invoke();
}
- #endif //GLIBMM_EXCEPTIONS_ENABLED
-
- delete the_slot; // the callback is only used once
+#endif
+ delete slot; // the callback is only used once
}
static void SignalProxy_UrisReceived_gtk_callback(GtkClipboard*, gchar** uris, void* data)
@@ -329,29 +312,23 @@ SelectionData Clipboard::wait_for_contents(const Glib::ustring& target) const
Glib::StringArrayHandle Clipboard::wait_for_targets() const
{
- std::list<Glib::ustring> listTargets;
-
- //Get a newly-allocated array of atoms:
- GdkAtom* targets = 0;
- gint n_targets = 0;
- gboolean test = gtk_clipboard_wait_for_targets( const_cast<GtkClipboard*>(gobj()), &targets, &n_targets );
- if(!test)
- n_targets = 0; //otherwise it will be -1.
-
- //Add the targets to the C++ container:
- for(int i = 0; i < n_targets; i++)
+ char** names = 0;
+ GdkAtom* atoms = 0;
+ int n_targets = 0;
+
+ // TODO: This works, but is not the intended way to use the array handles.
+ // Normally one would define custom Traits for the conversion, but that is
+ // not possible here because it would break binary compatibility.
+ if (gtk_clipboard_wait_for_targets(const_cast<GtkClipboard*>(gobj()), &atoms, &n_targets))
{
- //Convert the atom to a string:
- gchar* const atom_name = gdk_atom_name(targets[i]);
-
- Glib::ustring target;
- if(atom_name)
- target = Glib::ScopedPtr<char>(atom_name).get(); //This frees the gchar*.
-
- listTargets.push_back(target);
+ names = g_new(char*, n_targets);
+ std::transform(&atoms[0], &atoms[n_targets], &names[0], &gdk_atom_name);
+ g_free(atoms);
}
+ else
+ n_targets = 0;
- return listTargets;
+ return Glib::StringArrayHandle(names, n_targets, Glib::OWNERSHIP_DEEP);
}
void Clipboard::set_can_store(const ArrayHandle_TargetEntry& targets)
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]