[pygobject] gtk-demo: Avoid crash in CSS demos
- From: Simon Feltman <sfeltman src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [pygobject] gtk-demo: Avoid crash in CSS demos
- Date: Tue, 31 Dec 2013 21:45:59 +0000 (UTC)
commit 2ef59b89311529e34366d4d7aa8f8ae9a8ea6371
Author: Simon Feltman <sfeltman src gnome org>
Date: Tue Dec 31 13:41:20 2013 -0800
gtk-demo: Avoid crash in CSS demos
Avoid a potential crash in the CSS demos where the text editing buffer is
out of sync with the last good CSS parsing buffer. In the case of CSS
warnings, we get a parsing-error callback but no exception is raised.
This would cause the buffers to become out of sync and accessing position
information from the parsing-error section would crash the text editor due
to an out of range iterator being created.
demos/gtk-demo/demos/Css/css_basics.py | 31 ++++++++++++++++++++-------
demos/gtk-demo/demos/Css/css_multiplebgs.py | 31 ++++++++++++++++++++-------
2 files changed, 46 insertions(+), 16 deletions(-)
---
diff --git a/demos/gtk-demo/demos/Css/css_basics.py b/demos/gtk-demo/demos/Css/css_basics.py
index bd3f873..18c3d12 100644
--- a/demos/gtk-demo/demos/Css/css_basics.py
+++ b/demos/gtk-demo/demos/Css/css_basics.py
@@ -32,7 +32,13 @@ from gi.repository import Gtk, Gdk, Pango, Gio, GLib
class CSSBasicsApp:
def __init__(self, demoapp):
self.demoapp = demoapp
+ #: Store the last successful parsing of the css so we can revert
+ #: this in case of an error.
self.last_good_text = ''
+ #: Set when we receive a parsing-error callback. This is needed
+ #: to handle logic after a parsing-error callback which does not raise
+ #: an exception with provider.load_from_data()
+ self.last_error_code = 0
self.window = Gtk.Window()
self.window.set_title('CSS Basics')
@@ -86,12 +92,14 @@ class CSSBasicsApp:
end = buffer.get_iter_at_line_index(section.get_end_line(),
section.get_end_position())
- if error:
- tag_name = "error"
- self.infolabel.set_text(error.message)
- self.infobar.show_all()
- else:
+ if error.code == Gtk.CssProviderError.DEPRECATED:
tag_name = "warning"
+ else:
+ tag_name = "error"
+ self.last_error_code = error.code
+
+ self.infolabel.set_text(error.message)
+ self.infobar.show_all()
buffer.apply_tag_by_name(tag_name, start, end)
@@ -106,10 +114,17 @@ class CSSBasicsApp:
try:
provider.load_from_data(text)
except GLib.GError as e:
- if e.domain == 'gtk-css-provider-error-quark':
- provider.load_from_data(self.last_good_text)
- else:
+ if e.domain != 'gtk-css-provider-error-quark':
raise e
+
+ # If the parsing-error callback is ever run (even in the case of warnings)
+ # load the last good css text that ran without any warnings. Otherwise
+ # we may have a discrepancy in "last_good_text" vs the current buffer
+ # causing section.get_start_position() to give back an invalid position
+ # for the editor buffer.
+ if self.last_error_code:
+ provider.load_from_data(self.last_good_text)
+ self.last_error_code = 0
else:
self.last_good_text = text
self.infobar.hide()
diff --git a/demos/gtk-demo/demos/Css/css_multiplebgs.py b/demos/gtk-demo/demos/Css/css_multiplebgs.py
index 803c853..9e1b011 100644
--- a/demos/gtk-demo/demos/Css/css_multiplebgs.py
+++ b/demos/gtk-demo/demos/Css/css_multiplebgs.py
@@ -31,7 +31,13 @@ from gi.repository import Gtk, Gdk, Pango, Gio, GLib
class CSSMultiplebgsApp:
def __init__(self, demoapp):
self.demoapp = demoapp
+ #: Store the last successful parsing of the css so we can revert
+ #: this in case of an error.
self.last_good_text = ''
+ #: Set when we receive a parsing-error callback. This is needed
+ #: to handle logic after a parsing-error callback which does not raise
+ #: an exception with provider.load_from_data()
+ self.last_error_code = 0
self.window = Gtk.Window()
self.window.set_title('CSS Multiplebgs')
@@ -124,12 +130,14 @@ class CSSMultiplebgsApp:
end = buffer.get_iter_at_line_index(section.get_end_line(),
section.get_end_position())
- if error:
- tag_name = "error"
- self.infolabel.set_text(error.message)
- self.infobar.show_all()
- else:
+ if error.code == Gtk.CssProviderError.DEPRECATED:
tag_name = "warning"
+ else:
+ tag_name = "error"
+ self.last_error_code = error.code
+
+ self.infolabel.set_text(error.message)
+ self.infobar.show_all()
buffer.apply_tag_by_name(tag_name, start, end)
@@ -144,10 +152,17 @@ class CSSMultiplebgsApp:
try:
provider.load_from_data(text)
except GLib.GError as e:
- if e.domain == 'gtk-css-provider-error-quark':
- provider.load_from_data(self.last_good_text)
- else:
+ if e.domain != 'gtk-css-provider-error-quark':
raise e
+
+ # If the parsing-error callback is ever run (even in the case of warnings)
+ # load the last good css text that ran without any warnings. Otherwise
+ # we may have a discrepancy in "last_good_text" vs the current buffer
+ # causing section.get_start_position() to give back an invalid position
+ # for the editor buffer.
+ if self.last_error_code:
+ provider.load_from_data(self.last_good_text)
+ self.last_error_code = 0
else:
self.last_good_text = text
self.infobar.hide()
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]