[pavucontrol] Add a patch fixing various crashes due to referencing freed memory (#1133339)

Hans de Goede jwrdegoede at fedoraproject.org
Thu Aug 28 11:07:58 UTC 2014


commit 4271c11b4d44799fd3f539bd81498cc95906ec9d
Author: Hans de Goede <hdegoede at redhat.com>
Date:   Thu Aug 28 13:07:59 2014 +0200

    Add a patch fixing various crashes due to referencing freed memory (#1133339)
    
    - Cherry-pick some other fixes from upstream git

 ...l-ellipsize-labels-to-fix-window-resizing.patch |   75 ++++++++
 0003-Add-horizontal-scrollbars-automatically.patch |   72 +++++++
 ...he-widget-before-returning-it-from-create.patch |  201 ++++++++++++++++++++
 pavucontrol.spec                                   |   12 +-
 4 files changed, 359 insertions(+), 1 deletions(-)
---
diff --git a/0002-pavucontrol-ellipsize-labels-to-fix-window-resizing.patch b/0002-pavucontrol-ellipsize-labels-to-fix-window-resizing.patch
new file mode 100644
index 0000000..1fcb80e
--- /dev/null
+++ b/0002-pavucontrol-ellipsize-labels-to-fix-window-resizing.patch
@@ -0,0 +1,75 @@
+From 82d7c5f03c493244b1f0f7472afbc7282a940b9d Mon Sep 17 00:00:00 2001
+From: "Alexander E. Patrakov" <patrakov at gmail.com>
+Date: Fri, 13 Dec 2013 17:47:38 +0600
+Subject: [PATCH 2/4] pavucontrol: ellipsize labels to fix window resizing
+
+ellipsize labels to make the window resizable even with long label text
+and add tooltips to provide a way to read the full text
+
+Originally from Sebastian Wick <sebastian at sebastianwick.net>
+---
+ src/mainwindow.cc     | 6 ++++++
+ src/pavucontrol.glade | 2 ++
+ 2 files changed, 8 insertions(+)
+
+diff --git a/src/mainwindow.cc b/src/mainwindow.cc
+index 8fa3949..5a42318 100644
+--- a/src/mainwindow.cc
++++ b/src/mainwindow.cc
+@@ -433,6 +433,7 @@ bool MainWindow::updateSink(const pa_sink_info &info) {
+     w->boldNameLabel->set_text("");
+     gchar *txt;
+     w->nameLabel->set_markup(txt = g_markup_printf_escaped("%s", info.description));
++    w->nameLabel->set_tooltip_text(info.description);
+     g_free(txt);
+ 
+     icon = pa_proplist_gets(info.proplist, PA_PROP_DEVICE_ICON_NAME);
+@@ -588,6 +589,7 @@ void MainWindow::updateSource(const pa_source_info &info) {
+     w->boldNameLabel->set_text("");
+     gchar *txt;
+     w->nameLabel->set_markup(txt = g_markup_printf_escaped("%s", info.description));
++    w->nameLabel->set_tooltip_text(info.description);
+     g_free(txt);
+ 
+     icon = pa_proplist_gets(info.proplist, PA_PROP_DEVICE_ICON_NAME);
+@@ -709,6 +711,8 @@ void MainWindow::updateSinkInput(const pa_sink_input_info &info) {
+         w->nameLabel->set_label(info.name);
+     }
+ 
++    w->nameLabel->set_tooltip_text(info.name);
++
+     setIconFromProplist(w->iconImage, info.proplist, "audio-card");
+ 
+     w->setVolume(info.volume);
+@@ -761,6 +765,8 @@ void MainWindow::updateSourceOutput(const pa_source_output_info &info) {
+         w->nameLabel->set_label(info.name);
+     }
+ 
++    w->nameLabel->set_tooltip_text(info.name);
++
+     setIconFromProplist(w->iconImage, info.proplist, "audio-input-microphone");
+ 
+ #if HAVE_SOURCE_OUTPUT_VOLUMES
+diff --git a/src/pavucontrol.glade b/src/pavucontrol.glade
+index 4b3dd01..b0aa2a5 100644
+--- a/src/pavucontrol.glade
++++ b/src/pavucontrol.glade
+@@ -256,6 +256,7 @@
+                             <property name="xalign">0</property>
+                             <property name="label" translatable="yes">Device Title</property>
+                             <property name="use_markup">True</property>
++                            <property name="ellipsize">end</property>
+                           </object>
+                           <packing>
+                             <property name="expand">False</property>
+@@ -1384,6 +1385,7 @@
+                             <property name="xalign">0</property>
+                             <property name="label" translatable="yes">Stream Title</property>
+                             <property name="use_markup">True</property>
++                            <property name="ellipsize">end</property>
+                           </object>
+                           <packing>
+                             <property name="expand">False</property>
+-- 
+2.1.0
+
diff --git a/0003-Add-horizontal-scrollbars-automatically.patch b/0003-Add-horizontal-scrollbars-automatically.patch
new file mode 100644
index 0000000..558198b
--- /dev/null
+++ b/0003-Add-horizontal-scrollbars-automatically.patch
@@ -0,0 +1,72 @@
+From 710037ea1687ab2737298c7e3e897554253b44db Mon Sep 17 00:00:00 2001
+From: Simon Johansson <amp at ampleyfly.se>
+Date: Tue, 24 Jun 2014 01:06:58 +0200
+Subject: [PATCH 3/4] Add horizontal scrollbars automatically
+
+Add a horizontal scrollbar inside each tab automatically when the window
+is not wide enough. Add arrows for scrolling the tab bar when the tabs
+don't fit inside the window.
+---
+ src/pavucontrol.glade | 11 ++++++-----
+ 1 file changed, 6 insertions(+), 5 deletions(-)
+
+diff --git a/src/pavucontrol.glade b/src/pavucontrol.glade
+index b0aa2a5..5116632 100644
+--- a/src/pavucontrol.glade
++++ b/src/pavucontrol.glade
+@@ -705,6 +705,7 @@
+             <property name="visible">True</property>
+             <property name="can_focus">True</property>
+             <property name="show_border">False</property>
++            <property name="scrollable">True</property>
+             <child>
+               <object class="GtkVBox" id="vbox32">
+                 <property name="visible">True</property>
+@@ -714,7 +715,7 @@
+                     <property name="visible">True</property>
+                     <property name="can_focus">True</property>
+                     <property name="border_width">12</property>
+-                    <property name="hscrollbar_policy">never</property>
++                    <property name="hscrollbar_policy">automatic</property>
+                     <property name="vscrollbar_policy">automatic</property>
+                     <child>
+                       <object class="GtkViewport" id="viewport1">
+@@ -828,7 +829,7 @@
+                     <property name="visible">True</property>
+                     <property name="can_focus">True</property>
+                     <property name="border_width">12</property>
+-                    <property name="hscrollbar_policy">never</property>
++                    <property name="hscrollbar_policy">automatic</property>
+                     <property name="vscrollbar_policy">automatic</property>
+                     <child>
+                       <object class="GtkViewport" id="viewport5">
+@@ -946,7 +947,7 @@
+                     <property name="visible">True</property>
+                     <property name="can_focus">True</property>
+                     <property name="border_width">12</property>
+-                    <property name="hscrollbar_policy">never</property>
++                    <property name="hscrollbar_policy">automatic</property>
+                     <property name="vscrollbar_policy">automatic</property>
+                     <child>
+                       <object class="GtkViewport" id="viewport4">
+@@ -1065,7 +1066,7 @@
+                     <property name="visible">True</property>
+                     <property name="can_focus">True</property>
+                     <property name="border_width">12</property>
+-                    <property name="hscrollbar_policy">never</property>
++                    <property name="hscrollbar_policy">automatic</property>
+                     <property name="vscrollbar_policy">automatic</property>
+                     <child>
+                       <object class="GtkViewport" id="viewport3">
+@@ -1185,7 +1186,7 @@
+                     <property name="visible">True</property>
+                     <property name="can_focus">True</property>
+                     <property name="border_width">12</property>
+-                    <property name="hscrollbar_policy">never</property>
++                    <property name="hscrollbar_policy">automatic</property>
+                     <property name="vscrollbar_policy">automatic</property>
+                     <child>
+                       <object class="GtkViewport" id="viewport2">
+-- 
+2.1.0
+
diff --git a/0004-Reference-the-widget-before-returning-it-from-create.patch b/0004-Reference-the-widget-before-returning-it-from-create.patch
new file mode 100644
index 0000000..9c6a844
--- /dev/null
+++ b/0004-Reference-the-widget-before-returning-it-from-create.patch
@@ -0,0 +1,201 @@
+From 5df85cc00332a652e0bb5678e656c5bb107971a5 Mon Sep 17 00:00:00 2001
+From: Hans de Goede <hdegoede at redhat.com>
+Date: Thu, 28 Aug 2014 12:58:05 +0200
+Subject: [PATCH 4/4] Reference the widget before returning it from ::create
+ methods
+
+Widgets (unlike Windows and Dialogs) returned by Gtk::Builder::get_widget*
+start owned by the GtkBuilder object, the idea being that they will get
+added to a container before the scope of the GtkBuilder object ends, and it
+thus automatically gets destroyed.
+
+But in the various ::create methods in pavucontrol, a pointer to the widget
+gets returned, so that it can be added to a cointainer by the caller.
+However as soon as the ::create method exits the GtkBuilder object owning
+the widget, and thus also the widget gets destroyed, and we end up returning
+free-ed memory.
+
+This commit fixes this by making all ::create methods take a reference on
+the widget before returning it, and having all the callers unreference the
+widget after adding it to a container.
+
+https://bugs.freedesktop.org/show_bug.cgi?id=83144
+https://bugzilla.redhat.com/show_bug.cgi?id=1133339
+
+Signed-off-by: Hans de Goede <hdegoede at redhat.com>
+---
+ src/cardwidget.cc         | 1 +
+ src/channelwidget.cc      | 1 +
+ src/devicewidget.cc       | 1 +
+ src/mainwindow.cc         | 6 ++++++
+ src/rolewidget.cc         | 1 +
+ src/sinkinputwidget.cc    | 1 +
+ src/sinkwidget.cc         | 1 +
+ src/sourceoutputwidget.cc | 1 +
+ src/sourcewidget.cc       | 1 +
+ src/streamwidget.cc       | 1 +
+ 10 files changed, 15 insertions(+)
+
+diff --git a/src/cardwidget.cc b/src/cardwidget.cc
+index c79ac6c..28c558d 100644
+--- a/src/cardwidget.cc
++++ b/src/cardwidget.cc
+@@ -45,6 +45,7 @@ CardWidget* CardWidget::create() {
+     CardWidget* w;
+     Glib::RefPtr<Gtk::Builder> x = Gtk::Builder::create_from_file(GLADE_FILE, "cardWidget");
+     x->get_widget_derived("cardWidget", w);
++    w->reference();
+     return w;
+ }
+ 
+diff --git a/src/channelwidget.cc b/src/channelwidget.cc
+index 6f59de2..fe94c11 100644
+--- a/src/channelwidget.cc
++++ b/src/channelwidget.cc
+@@ -53,6 +53,7 @@ ChannelWidget* ChannelWidget::create() {
+     x->add_from_file(GLADE_FILE, "adjustment1");
+     x->add_from_file(GLADE_FILE, "channelWidget");
+     x->get_widget_derived("channelWidget", w);
++    w->reference();
+     return w;
+ }
+ 
+diff --git a/src/devicewidget.cc b/src/devicewidget.cc
+index 1a148ee..813780f 100644
+--- a/src/devicewidget.cc
++++ b/src/devicewidget.cc
+@@ -89,6 +89,7 @@ void DeviceWidget::setChannelMap(const pa_channel_map &m, bool can_decibel) {
+         snprintf(text, sizeof(text), "<b>%s</b>", pa_channel_position_to_pretty_string(m.map[i]));
+         cw->channelLabel->set_markup(text);
+         channelsVBox->pack_start(*cw, false, false, 0);
++        cw->unreference();
+     }
+     channelWidgets[m.channels-1]->last = true;
+ 
+diff --git a/src/mainwindow.cc b/src/mainwindow.cc
+index 5a42318..5d205fb 100644
+--- a/src/mainwindow.cc
++++ b/src/mainwindow.cc
+@@ -300,6 +300,7 @@ void MainWindow::updateCard(const pa_card_info &info) {
+     else {
+         cardWidgets[info.index] = w = CardWidget::create();
+         cardsVBox->pack_start(*w, false, false, 0);
++        w->unreference();
+         w->index = info.index;
+         is_new = true;
+     }
+@@ -416,6 +417,7 @@ bool MainWindow::updateSink(const pa_sink_info &info) {
+         sinkWidgets[info.index] = w = SinkWidget::create(this);
+         w->setChannelMap(info.channel_map, !!(info.flags & PA_SINK_DECIBEL_VOLUME));
+         sinksVBox->pack_start(*w, false, false, 0);
++        w->unreference();
+         w->index = info.index;
+         w->monitor_index = info.monitor_source;
+         is_new = true;
+@@ -570,6 +572,7 @@ void MainWindow::updateSource(const pa_source_info &info) {
+         sourceWidgets[info.index] = w = SourceWidget::create(this);
+         w->setChannelMap(info.channel_map, !!(info.flags & PA_SOURCE_DECIBEL_VOLUME));
+         sourcesVBox->pack_start(*w, false, false, 0);
++        w->unreference();
+         w->index = info.index;
+         is_new = true;
+ 
+@@ -686,6 +689,7 @@ void MainWindow::updateSinkInput(const pa_sink_input_info &info) {
+         sinkInputWidgets[info.index] = w = SinkInputWidget::create(this);
+         w->setChannelMap(info.channel_map, true);
+         streamsVBox->pack_start(*w, false, false, 0);
++        w->unreference();
+         w->index = info.index;
+         w->clientIndex = info.client;
+         is_new = true;
+@@ -743,6 +747,7 @@ void MainWindow::updateSourceOutput(const pa_source_output_info &info) {
+         w->setChannelMap(info.channel_map, true);
+ #endif
+         recsVBox->pack_start(*w, false, false, 0);
++        w->unreference();
+         w->index = info.index;
+         w->clientIndex = info.client;
+         is_new = true;
+@@ -838,6 +843,7 @@ bool MainWindow::createEventRoleWidget() {
+ 
+     eventRoleWidget = RoleWidget::create();
+     streamsVBox->pack_start(*eventRoleWidget, false, false, 0);
++    eventRoleWidget->unreference();
+     eventRoleWidget->role = "sink-input-by-media-role:event";
+     eventRoleWidget->setChannelMap(cm, true);
+ 
+diff --git a/src/rolewidget.cc b/src/rolewidget.cc
+index fd3196c..db07f92 100644
+--- a/src/rolewidget.cc
++++ b/src/rolewidget.cc
+@@ -40,6 +40,7 @@ RoleWidget* RoleWidget::create() {
+     RoleWidget* w;
+     Glib::RefPtr<Gtk::Builder> x = Gtk::Builder::create_from_file(GLADE_FILE, "streamWidget");
+     x->get_widget_derived("streamWidget", w);
++    w->reference();
+     return w;
+ }
+ 
+diff --git a/src/sinkinputwidget.cc b/src/sinkinputwidget.cc
+index b88b718..5a0ba39 100644
+--- a/src/sinkinputwidget.cc
++++ b/src/sinkinputwidget.cc
+@@ -43,6 +43,7 @@ SinkInputWidget* SinkInputWidget::create(MainWindow* mainWindow) {
+     Glib::RefPtr<Gtk::Builder> x = Gtk::Builder::create_from_file(GLADE_FILE, "streamWidget");
+     x->get_widget_derived("streamWidget", w);
+     w->init(mainWindow);
++    w->reference();
+     return w;
+ }
+ 
+diff --git a/src/sinkwidget.cc b/src/sinkwidget.cc
+index 7f4902c..f682cf2 100644
+--- a/src/sinkwidget.cc
++++ b/src/sinkwidget.cc
+@@ -82,6 +82,7 @@ SinkWidget* SinkWidget::create(MainWindow* mainWindow) {
+     Glib::RefPtr<Gtk::Builder> x = Gtk::Builder::create_from_file(GLADE_FILE, "deviceWidget");
+     x->get_widget_derived("deviceWidget", w);
+     w->init(mainWindow, "sink");
++    w->reference();
+     return w;
+ }
+ 
+diff --git a/src/sourceoutputwidget.cc b/src/sourceoutputwidget.cc
+index 827c5a8..4d915b0 100644
+--- a/src/sourceoutputwidget.cc
++++ b/src/sourceoutputwidget.cc
+@@ -49,6 +49,7 @@ SourceOutputWidget* SourceOutputWidget::create(MainWindow* mainWindow) {
+     Glib::RefPtr<Gtk::Builder> x = Gtk::Builder::create_from_file(GLADE_FILE, "streamWidget");
+     x->get_widget_derived("streamWidget", w);
+     w->init(mainWindow);
++    w->reference();
+     return w;
+ }
+ 
+diff --git a/src/sourcewidget.cc b/src/sourcewidget.cc
+index 5e4ecf0..fde5333 100644
+--- a/src/sourcewidget.cc
++++ b/src/sourcewidget.cc
+@@ -35,6 +35,7 @@ SourceWidget* SourceWidget::create(MainWindow* mainWindow) {
+     Glib::RefPtr<Gtk::Builder> x = Gtk::Builder::create_from_file(GLADE_FILE, "deviceWidget");
+     x->get_widget_derived("deviceWidget", w);
+     w->init(mainWindow, "source");
++    w->reference();
+     return w;
+ }
+ 
+diff --git a/src/streamwidget.cc b/src/streamwidget.cc
+index 94363ec..e602cce 100644
+--- a/src/streamwidget.cc
++++ b/src/streamwidget.cc
+@@ -77,6 +77,7 @@ void StreamWidget::setChannelMap(const pa_channel_map &m, bool can_decibel) {
+         snprintf(text, sizeof(text), "<b>%s</b>", pa_channel_position_to_pretty_string(m.map[i]));
+         cw->channelLabel->set_markup(text);
+         channelsVBox->pack_start(*cw, false, false, 0);
++        cw->unreference();
+     }
+     channelWidgets[m.channels-1]->last = true;
+     channelWidgets[m.channels-1]->setBaseVolume(PA_VOLUME_NORM);
+-- 
+2.1.0
+
diff --git a/pavucontrol.spec b/pavucontrol.spec
index fa934dc..4d060f4 100644
--- a/pavucontrol.spec
+++ b/pavucontrol.spec
@@ -1,6 +1,6 @@
 Name:           pavucontrol
 Version:        2.0
-Release:        7%{?dist}
+Release:        8%{?dist}
 Summary:        Volume control for PulseAudio
 
 Group:          Applications/Multimedia
@@ -8,6 +8,9 @@ License:        GPLv2+
 URL:            http://freedesktop.org/software/pulseaudio/%{name}
 Source0:        http://freedesktop.org/software/pulseaudio/%{name}/%{name}-%{version}.tar.xz
 Patch0:         0001-sinkwidget-add-support-for-AAC-pass-through.patch
+Patch1:         0002-pavucontrol-ellipsize-labels-to-fix-window-resizing.patch
+Patch2:         0003-Add-horizontal-scrollbars-automatically.patch
+Patch3:         0004-Reference-the-widget-before-returning-it-from-create.patch
 
 BuildRequires:  pulseaudio-libs-devel >= 3.0
 BuildRequires:  gtkmm30-devel
@@ -25,6 +28,9 @@ of each playback stream separately.
 %prep
 %setup -q
 %patch0 -p1
+%patch1 -p1
+%patch2 -p1
+%patch3 -p1
 
 %build
 %configure
@@ -52,6 +58,10 @@ desktop-file-install \
 %{_datadir}/applications/pavucontrol.desktop
 
 %changelog
+* Thu Aug 28 2014 Hans de Goede <hdegoede at redhat.com> - 2.0-8
+- Add a patch fixing various crashes due to referencing freed memory (#1133339)
+- Cherry-pick some other fixes from upstream git
+
 * Sun Aug 17 2014 Fedora Release Engineering <rel-eng at lists.fedoraproject.org> - 2.0-7
 - Rebuilt for https://fedoraproject.org/wiki/Fedora_21_22_Mass_Rebuild
 


More information about the scm-commits mailing list