diff options
| author | Christophe Lebras <christophe.lebras@gmail.com> | 2017-07-04 03:56:42 +0000 |
|---|---|---|
| committer | Christophe Lebras <christophe.lebras@gmail.com> | 2017-07-04 03:56:42 +0000 |
| commit | 70a8ff03de32c3f87f130436d645a382c5595628 (patch) | |
| tree | ee37a1506b32828ea63a0fe7cc30b81b13d4bea1 /src | |
| parent | Fix and cleanup icons. (diff) | |
| download | inkscape-70a8ff03de32c3f87f130436d645a382c5595628.tar.gz inkscape-70a8ff03de32c3f87f130436d645a382c5595628.zip | |
Fix crash in "New from template" dialog
Selecting template in "New from template" dialog, causes Inkscape to crash because the method SPCanvas::paintSingleBuffer is called before _backing_store is initialized.
Checking _backing_store value and returning if null, prebent crash.
Diffstat (limited to 'src')
| -rw-r--r-- | src/display/sp-canvas.cpp | 45 |
1 files changed, 26 insertions, 19 deletions
diff --git a/src/display/sp-canvas.cpp b/src/display/sp-canvas.cpp index 8857b8c68..17c4cc0d5 100644 --- a/src/display/sp-canvas.cpp +++ b/src/display/sp-canvas.cpp @@ -217,7 +217,7 @@ sp_canvas_item_class_init(SPCanvasItemClass *klass) gobject_class->dispose = sp_canvas_item_dispose; gobject_class->finalize = sp_canvas_item_finalize; klass->destroy = sp_canvas_item_real_destroy; - + object_signals[DESTROY] = g_signal_new ("destroy", G_TYPE_FROM_CLASS (gobject_class), @@ -300,7 +300,7 @@ static void redraw_if_visible(SPCanvasItem *item) void sp_canvas_item_destroy(SPCanvasItem *item) { g_return_if_fail(SP_IS_CANVAS_ITEM(item)); - + if (!item->in_destruction) g_object_run_dispose(G_OBJECT(item)); } @@ -327,12 +327,12 @@ void sp_canvas_item_dispose(GObject *object) redraw_if_visible (item); } item->visible = FALSE; - + if (item == item->canvas->_current_item) { item->canvas->_current_item = NULL; item->canvas->_need_repick = TRUE; } - + if (item == item->canvas->_new_current_item) { item->canvas->_new_current_item = NULL; item->canvas->_need_repick = TRUE; @@ -346,11 +346,11 @@ void sp_canvas_item_dispose(GObject *object) if (item == item->canvas->_focused_item) { item->canvas->_focused_item = NULL; } - + if (item->parent) { SP_CANVAS_GROUP(item->parent)->remove(item); } - + g_signal_emit (object, object_signals[DESTROY], 0); item->in_destruction = false; } @@ -362,7 +362,7 @@ void sp_canvas_item_real_destroy(SPCanvasItem *object) { g_signal_handlers_destroy(object); } - + void sp_canvas_item_finalize(GObject *gobject) { SPCanvasItem *object = SP_CANVAS_ITEM(gobject); @@ -374,7 +374,7 @@ void sp_canvas_item_finalize(GObject *gobject) "reference; the initial floating reference is not owned by anyone\n" "and must be removed with g_object_ref_sink()."); } - + G_OBJECT_CLASS (sp_canvas_item_parent_class)->finalize (gobject); } } // namespace @@ -482,7 +482,7 @@ void sp_canvas_item_raise(SPCanvasItem *item, int positions) item->canvas->_need_repick = TRUE; } -void sp_canvas_item_raise_to_top(SPCanvasItem *item) +void sp_canvas_item_raise_to_top(SPCanvasItem *item) { g_return_if_fail (item != NULL); g_return_if_fail (SP_IS_CANVAS_ITEM (item)); @@ -521,9 +521,9 @@ void sp_canvas_item_lower(SPCanvasItem *item, int positions) std::list<SPCanvasItem *>::iterator l = std::find(parent->items.begin(), parent->items.end(), item); g_assert (l != parent->items.end()); - for (int i=0; i<positions && l != parent->items.begin(); ++i) + for (int i=0; i<positions && l != parent->items.begin(); ++i) --l; - + parent->items.remove(item); parent->items.insert(l, item); @@ -540,7 +540,7 @@ void sp_canvas_item_lower_to_bottom(SPCanvasItem *item) SPCanvasGroup *parent = SP_CANVAS_GROUP (item->parent); parent->items.remove(item); parent->items.push_front(item); - redraw_if_visible (item); + redraw_if_visible (item); item->canvas->_need_repick = TRUE; } @@ -644,7 +644,7 @@ int sp_canvas_item_grab(SPCanvasItem *item, guint event_mask, GdkCursor *cursor, auto dm = gdk_display_get_device_manager(display); auto device = gdk_device_manager_get_client_pointer(dm); - gdk_device_grab(device, + gdk_device_grab(device, getWindow(item->canvas), GDK_OWNERSHIP_NONE, FALSE, @@ -882,7 +882,7 @@ void SPCanvasGroup::render(SPCanvasItem *item, SPCanvasBuf *buf) void SPCanvasGroup::viewboxChanged(SPCanvasItem *item, Geom::IntRect const &new_area) { SPCanvasGroup *group = SP_CANVAS_GROUP(item); - + for (std::list<SPCanvasItem *>::const_iterator it = group->items.begin(); it != group->items.end(); ++it) { SPCanvasItem *child = *it; if (child->visible) { @@ -905,7 +905,7 @@ void SPCanvasGroup::add(SPCanvasItem *item) void SPCanvasGroup::remove(SPCanvasItem *item) { - + g_return_if_fail(item != NULL); items.remove(item); @@ -962,7 +962,7 @@ static void sp_canvas_init(SPCanvas *canvas) // See comment at in sp-canvas.h. canvas->_gen_all_enter_events = false; - + canvas->_drawing_disabled = false; canvas->_backing_store = NULL; @@ -1124,7 +1124,7 @@ void SPCanvas::handle_size_allocate(GtkWidget *widget, GtkAllocation *allocation { SPCanvas *canvas = SP_CANVAS (widget); GtkAllocation old_allocation; - + gtk_widget_get_allocation(widget, &old_allocation); // Geom::IntRect old_area = Geom::IntRect::from_xywh(canvas->_x0, canvas->_y0, @@ -1518,6 +1518,13 @@ int SPCanvas::handle_motion(GtkWidget *widget, GdkEventMotion *event) void SPCanvas::paintSingleBuffer(Geom::IntRect const &paint_rect, Geom::IntRect const &canvas_rect, int /*sw*/) { + + // Prevent crash if paintSingleBuffer is called before _backing_store is + // initialized. + + if (_backing_store == NULL) + return; + SPCanvasBuf buf; buf.buf = NULL; buf.buf_rowstride = 0; @@ -1568,7 +1575,7 @@ void SPCanvas::paintSingleBuffer(Geom::IntRect const &paint_rect, Geom::IntRect } else { transf = Inkscape::CMSSystem::getDisplayTransform(); } - + if (transf) { cairo_surface_flush(imgs); unsigned char *px = cairo_image_surface_get_data(imgs); @@ -2152,7 +2159,7 @@ Geom::Point sp_canvas_world_to_window(SPCanvas const *canvas, Geom::Point const bool sp_canvas_world_pt_inside_window(SPCanvas const *canvas, Geom::Point const &world) { GtkAllocation allocation; - + g_assert( canvas != NULL ); g_assert(SP_IS_CANVAS(canvas)); |
