[gnome-maps] overpass, placeBubble: Avoid use-after-free
- From: Marcus Lundblad <mlundblad src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-maps] overpass, placeBubble: Avoid use-after-free
- Date: Sat, 20 Oct 2018 11:24:52 +0000 (UTC)
commit af4994cf82d4201e88d0a71841dbb52169e49ad4
Author: Marcus Lundblad <ml update uu se>
Date: Fri Oct 19 12:28:54 2018 +0200
overpass, placeBubble: Avoid use-after-free
Use bound properties to avoid JS accessing finalized GObject.
Fixes #134
src/overpass.js | 28 ++++++++++++++++++++--------
src/placeBubble.js | 40 +++++++++++++++++++++++++++++-----------
2 files changed, 49 insertions(+), 19 deletions(-)
---
diff --git a/src/overpass.js b/src/overpass.js
index b8307ca..cf5cba3 100644
--- a/src/overpass.js
+++ b/src/overpass.js
@@ -19,6 +19,7 @@
const Format = imports.format;
const Geocode = imports.gi.GeocodeGlib;
+const GObject = imports.gi.GObject;
const Soup = imports.gi.Soup;
const Place = imports.place;
@@ -33,11 +34,22 @@ const _DEFAULT_OUTPUT_SORT_ORDER = 'qt';
const BASE_URL = 'https://overpass-api.de/api/interpreter';
-var Overpass = class Overpass {
+var Overpass = GObject.registerClass({
+ Properties: {
+ 'place': GObject.ParamSpec.object('place',
+ 'Place',
+ 'Place with added information',
+ GObject.ParamFlags.READABLE |
+ GObject.ParamFlags.WRITABLE,
+ Geocode.Place)
+ }
+}, class Overpass extends GObject.Object {
- constructor(params) {
+ _init(params) {
params = params || { };
+ super._init();
+
// maximum allowed runtime for the query in seconds
this.timeout = params.timeout || _DEFAULT_TIMEOUT;
@@ -60,7 +72,7 @@ var Overpass = class Overpass {
this._session = new Soup.Session();
}
- addInfo(place, callback) {
+ addInfo(place) {
let url = this._getQueryUrl(place);
let uri = new Soup.URI(url);
let request = new Soup.Message({ method: 'GET',
@@ -68,16 +80,16 @@ var Overpass = class Overpass {
this._session.queue_message(request, (obj, message) => {
if (message.status_code !== Soup.KnownStatusCode.OK) {
- callback(false, message.status_code, null);
+ Utils.debug('Failed to fetch Overpass result: ' + message.status_code);
return;
}
try {
let jsonObj = JSON.parse(message.response_body.data);
this._populatePlace(place, jsonObj);
- callback(true,
- message.status_code);
+ this.place = place;
+ this.notify('place');
} catch(e) {
- callback(false, message.status_code);
+ Utils.debug('Failed to parse Overpass result');
}
});
}
@@ -143,4 +155,4 @@ var Overpass = class Overpass {
this.outputSortOrder,
this.outputCount ]);
}
-};
+});
diff --git a/src/placeBubble.js b/src/placeBubble.js
index 1bdf47d..720fbbb 100644
--- a/src/placeBubble.js
+++ b/src/placeBubble.js
@@ -20,6 +20,7 @@
*/
const GdkPixbuf = imports.gi.GdkPixbuf;
+const Geocode = imports.gi.GeocodeGlib;
const GLib = imports.gi.GLib;
const GObject = imports.gi.GObject;
const Gtk = imports.gi.Gtk;
@@ -43,8 +44,16 @@ const THUMBNAIL_FETCH_SIZE = 128;
// final scaled size of cropped thumnail
const THUMBNAIL_FINAL_SIZE = 70;
-var PlaceBubble = GObject.registerClass(
-class PlaceBubble extends MapBubble.MapBubble {
+var PlaceBubble = GObject.registerClass({
+ Properties: {
+ 'overpass-place': GObject.ParamSpec.object('overpass-place',
+ 'Overpass Place',
+ 'The place as filled in by Overpass',
+ GObject.ParamFlags.READABLE |
+ GObject.ParamFlags.WRITABLE,
+ Geocode.Place)
+ }
+}, class PlaceBubble extends MapBubble.MapBubble {
_init(params) {
let ui = Utils.getUIObject('place-bubble', [ 'stack',
@@ -75,24 +84,25 @@ class PlaceBubble extends MapBubble.MapBubble {
this._revealer = ui.contentRevealer;
let overpass = new Overpass.Overpass();
+
+ /* use a property binding from the Overpass instance to avoid
+ * accessing accessing this object after the underlying GObject has
+ * been finalized */
+ overpass.bind_property('place', this, 'overpass-place',
+ GObject.BindingFlags.DEFAULT);
+ this.connect('notify::overpass-place', () => this._onInfoAdded());
+
if (Application.placeStore.exists(this.place, null)) {
// If the place is stale, update from Overpass.
if (Application.placeStore.isStale(this.place)) {
- overpass.addInfo(this.place, (status, code) => {
- this._populate(this.place);
- Application.placeStore.updatePlace(this.place);
- });
+ overpass.addInfo(this.place);
} else {
let place = Application.placeStore.get(this.place);
this._populate(place);
}
} else if (this.place.store) {
- overpass.addInfo(this.place, (status, code) => {
- this._populate(this.place);
- Application.placeStore.addPlace(this.place,
- PlaceStore.PlaceType.RECENT);
- });
+ overpass.addInfo(this.place);
} else {
this._populate(this.place);
}
@@ -107,6 +117,14 @@ class PlaceBubble extends MapBubble.MapBubble {
this._initExpandButton();
}
+ _onInfoAdded() {
+ this._populate(this.place);
+ if (Application.placeStore.exists(this.place, null))
+ Application.placeStore.updatePlace(this.place);
+ else
+ Application.placeStore.addPlace(this.place, PlaceStore.PlaceType.RECENT);
+ }
+
_formatWikiLink(wiki) {
let lang = Wikipedia.getLanguage(wiki);
let article = Wikipedia.getArticle(wiki);
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]