Merge lp:~osomon/oxide/geolocation-doesnt-like-nans into lp:~oxide-developers/oxide/oxide.trunk

Proposed by Olivier Tilloy
Status: Merged
Merged at revision: 770
Proposed branch: lp:~osomon/oxide/geolocation-doesnt-like-nans
Merge into: lp:~oxide-developers/oxide/oxide.trunk
Diff against target: 113 lines (+32/-5)
4 files modified
qt/core/browser/oxide_qt_location_provider.cc (+21/-5)
qt/tests/mock/position/source.cc (+9/-0)
qt/tests/mock/position/source.h (+1/-0)
qt/tests/qmltests/core/tst_geolocation.qml (+1/-0)
To merge this branch: bzr merge lp:~osomon/oxide/geolocation-doesnt-like-nans
Reviewer Review Type Date Requested Status
Chris Coulson Approve
Review via email: mp+235667@code.launchpad.net

Commit message

Shield ourselves against location sources that return invalid values for attributes (horizontal accuracy, vertical accuracy, speed).
Chromium silently fails to deliver a position update if the horizontal accuracy is NaN.

To post a comment you must log in.
Revision history for this message
David Barth (dbarth) wrote :

Well done for debugging the problem this far !

On Tue, Sep 23, 2014 at 5:59 PM, Olivier Tilloy <
<email address hidden>> wrote:

> Olivier Tilloy has proposed merging
> lp:~osomon/oxide/geolocation-doesnt-like-nans into lp:oxide.
>
> Commit message:
> Shield ourselves against location sources that return invalid values for
> attributes (horizontal accuracy, vertical accuracy, speed).
> Chromium silently fails to deliver a position update if the horizontal
> accuracy is NaN.
>
> Requested reviews:
> Chris Coulson (chrisccoulson)
> Related bugs:
> Bug #1371166 in Oxide: "HERE location does not work in browser, but
> works in osmtouch"
> https://bugs.launchpad.net/oxide/+bug/1371166
>
> For more details, see:
>
> https://code.launchpad.net/~osomon/oxide/geolocation-doesnt-like-nans/+merge/235667
> --
>
> https://code.launchpad.net/~osomon/oxide/geolocation-doesnt-like-nans/+merge/235667
> Your team Oxide Developers is subscribed to branch lp:oxide.
>
> === modified file 'qt/core/browser/oxide_qt_location_provider.cc'
> --- qt/core/browser/oxide_qt_location_provider.cc 2014-05-06
> 21:14:38 +0000
> +++ qt/core/browser/oxide_qt_location_provider.cc 2014-09-23
> 15:58:36 +0000
> @@ -19,6 +19,7 @@
> #include "oxide_qt_location_provider_p.h"
>
> #include <cfloat>
> +#include <math.h>
>
> #include <QGeoCoordinate>
> #include <QGeoPositionInfo>
> @@ -43,16 +44,27 @@
> position.altitude = coord.altitude();
> if (info.hasAttribute(QGeoPositionInfo::HorizontalAccuracy)) {
> position.accuracy =
> info.attribute(QGeoPositionInfo::HorizontalAccuracy);
> + if (isnan(position.accuracy)) {
> + // shield ourselves against invalid data
> + position.accuracy = DBL_MAX;
> + }
> } else {
> // accuracy is mandatory
> position.accuracy = DBL_MAX;
> }
> if (info.hasAttribute(QGeoPositionInfo::VerticalAccuracy)) {
> - position.altitude_accuracy =
> - info.attribute(QGeoPositionInfo::VerticalAccuracy);
> + qreal accuracy = info.attribute(QGeoPositionInfo::VerticalAccuracy);
> + if (!isnan(accuracy)) {
> + // shield ourselves against invalid data
> + position.altitude_accuracy = accuracy;
> + }
> }
> if (info.hasAttribute(QGeoPositionInfo::GroundSpeed)) {
> - position.speed = info.attribute(QGeoPositionInfo::GroundSpeed);
> + qreal speed = info.attribute(QGeoPositionInfo::GroundSpeed);
> + if (!isnan(speed)) {
> + // shield ourselves against invalid data
> + position.speed = speed;
> + }
> }
> position.timestamp =
> base::Time::FromJsTime(info.timestamp().toMSecsSinceEpoch());
>
>
>

766. By Olivier Tilloy

Use portable qIsNaN() function.

767. By Olivier Tilloy

Shield against invalid values for altitude.

Revision history for this message
Chris Coulson (chrisccoulson) wrote :

Thanks. I've added a couple of comments inline. Also, would it be possible for the mock plugin to emulate this behaviour so that we could have a test for it?

768. By Olivier Tilloy

Fix typo.

769. By Olivier Tilloy

Use std::numeric_limits instead of macros from <cfloat>.

770. By Olivier Tilloy

Use base::IsNaN() from chromium instead of qIsNaN().

771. By Olivier Tilloy

Add a test case to check that invalid data in position updates is guarded against.

Revision history for this message
Chris Coulson (chrisccoulson) :
review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'qt/core/browser/oxide_qt_location_provider.cc'
2--- qt/core/browser/oxide_qt_location_provider.cc 2014-05-06 21:14:38 +0000
3+++ qt/core/browser/oxide_qt_location_provider.cc 2014-09-24 11:57:16 +0000
4@@ -18,7 +18,7 @@
5 #include "oxide_qt_location_provider.h"
6 #include "oxide_qt_location_provider_p.h"
7
8-#include <cfloat>
9+#include <limits>
10
11 #include <QGeoCoordinate>
12 #include <QGeoPositionInfo>
13@@ -26,6 +26,7 @@
14 #include <QThread>
15
16 #include "base/bind.h"
17+#include "base/float_util.h"
18 #include "base/location.h"
19 #include "base/logging.h"
20 #include "base/message_loop/message_loop_proxy.h"
21@@ -41,18 +42,33 @@
22 position.latitude = coord.latitude();
23 position.longitude = coord.longitude();
24 position.altitude = coord.altitude();
25+ if (base::IsNaN(position.altitude)) {
26+ // shield ourselves against invalid data
27+ position.altitude = 0;
28+ }
29 if (info.hasAttribute(QGeoPositionInfo::HorizontalAccuracy)) {
30 position.accuracy = info.attribute(QGeoPositionInfo::HorizontalAccuracy);
31+ if (base::IsNaN(position.accuracy)) {
32+ // shield ourselves against invalid data
33+ position.accuracy = std::numeric_limits<double>::max();
34+ }
35 } else {
36 // accuracy is mandatory
37- position.accuracy = DBL_MAX;
38+ position.accuracy = std::numeric_limits<double>::max();
39 }
40 if (info.hasAttribute(QGeoPositionInfo::VerticalAccuracy)) {
41- position.altitude_accuracy =
42- info.attribute(QGeoPositionInfo::VerticalAccuracy);
43+ qreal accuracy = info.attribute(QGeoPositionInfo::VerticalAccuracy);
44+ if (!base::IsNaN(accuracy)) {
45+ // shield ourselves against invalid data
46+ position.altitude_accuracy = accuracy;
47+ }
48 }
49 if (info.hasAttribute(QGeoPositionInfo::GroundSpeed)) {
50- position.speed = info.attribute(QGeoPositionInfo::GroundSpeed);
51+ qreal speed = info.attribute(QGeoPositionInfo::GroundSpeed);
52+ if (!base::IsNaN(speed)) {
53+ // shield ourselves against invalid data
54+ position.speed = speed;
55+ }
56 }
57 position.timestamp =
58 base::Time::FromJsTime(info.timestamp().toMSecsSinceEpoch());
59
60=== modified file 'qt/tests/mock/position/source.cc'
61--- qt/tests/mock/position/source.cc 2014-06-30 11:42:54 +0000
62+++ qt/tests/mock/position/source.cc 2014-09-24 11:57:16 +0000
63@@ -21,6 +21,7 @@
64 #include <QGeoCoordinate>
65 #include <QGuiApplication>
66 #include <QtGlobal>
67+#include <QtNumeric>
68
69 namespace {
70
71@@ -83,6 +84,8 @@
72 } else if (testcase == "error-unavailable") {
73 Q_EMIT QGeoPositionInfoSource::error(
74 QGeoPositionInfoSource::UnknownSourceError);
75+ } else if (testcase == "invaliddata") {
76+ QTimer::singleShot((int) rand(1., 1000.), this, SLOT(sendInvalidUpdate()));
77 } else {
78 QTimer::singleShot((int) rand(1., 1000.), this, SLOT(sendUpdate()));
79 }
80@@ -92,3 +95,9 @@
81 QGeoPositionInfo update = randomPosition();
82 Q_EMIT positionUpdated(update);
83 }
84+
85+void SourceMock::sendInvalidUpdate() {
86+ QGeoPositionInfo update = randomPosition();
87+ update.setAttribute(QGeoPositionInfo::HorizontalAccuracy, qQNaN());
88+ Q_EMIT positionUpdated(update);
89+}
90
91=== modified file 'qt/tests/mock/position/source.h'
92--- qt/tests/mock/position/source.h 2014-04-23 22:40:48 +0000
93+++ qt/tests/mock/position/source.h 2014-09-24 11:57:16 +0000
94@@ -41,6 +41,7 @@
95
96 private Q_SLOTS:
97 void sendUpdate();
98+ void sendInvalidUpdate();
99
100 private:
101 QTimer timer_;
102
103=== modified file 'qt/tests/qmltests/core/tst_geolocation.qml'
104--- qt/tests/qmltests/core/tst_geolocation.qml 2014-09-11 20:15:31 +0000
105+++ qt/tests/qmltests/core/tst_geolocation.qml 2014-09-24 11:57:16 +0000
106@@ -26,6 +26,7 @@
107 function test_geolocation_get_data() {
108 return [
109 { testcase: "", result: "OK" },
110+ { testcase: "invaliddata", result: "OK" },
111 { testcase: "timeout", result: "TIMEOUT" },
112 { testcase: "error-permission", result: "PERMISSION DENIED" },
113 { testcase: "error-unavailable", result: "POSITION UNAVAILABLE" }

Subscribers

People subscribed via source and target branches