summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKonstantin Käfer <mail@kkaefer.com>2018-06-11 14:02:15 +0200
committerKonstantin Käfer <mail@kkaefer.com>2018-06-12 10:55:46 +0200
commit9af5172f98a4319ba4d8d9d4cb7a24ac8bd9ea12 (patch)
tree21e315d8aea8439947b142c4ef6dcd4c5d34fbbb
parented7623092515f264ab4dc8e8dc7f493ecfd67a6c (diff)
downloadqtlocation-mapboxgl-9af5172f98a4319ba4d8d9d4cb7a24ac8bd9ea12.tar.gz
[core] fix undefined behavior in LineAtlas::addDash
-rw-r--r--cmake/test-files.cmake1
-rw-r--r--src/mbgl/geometry/line_atlas.cpp7
-rw-r--r--test/geometry/line_atlas.test.cpp31
3 files changed, 39 insertions, 0 deletions
diff --git a/cmake/test-files.cmake b/cmake/test-files.cmake
index 8105cbf5ce..a93f199d2a 100644
--- a/cmake/test-files.cmake
+++ b/cmake/test-files.cmake
@@ -23,6 +23,7 @@ set(MBGL_TEST_FILES
# geometry
test/geometry/dem_data.test.cpp
+ test/geometry/line_atlas.test.cpp
# gl
test/gl/bucket.test.cpp
diff --git a/src/mbgl/geometry/line_atlas.cpp b/src/mbgl/geometry/line_atlas.cpp
index 71a855b943..1129bd0b20 100644
--- a/src/mbgl/geometry/line_atlas.cpp
+++ b/src/mbgl/geometry/line_atlas.cpp
@@ -41,6 +41,10 @@ LinePatternPos LineAtlas::addDash(const std::vector<float>& dasharray, LinePatte
const uint8_t dashheight = 2 * n + 1;
const uint8_t offset = 128;
+ if (dasharray.size() < 2) {
+ return LinePatternPos();
+ }
+
if (nextRow + dashheight > image.size.height) {
Log::Warning(Event::OpenGL, "line atlas bitmap overflow");
return LinePatternPos();
@@ -73,6 +77,9 @@ LinePatternPos LineAtlas::addDash(const std::vector<float>& dasharray, LinePatte
while (right < x / stretch) {
left = right;
+ if (partIndex >= dasharray.size()) {
+ return LinePatternPos();
+ }
right = right + dasharray[partIndex];
if (oddLength && partIndex == dasharray.size() - 1) {
diff --git a/test/geometry/line_atlas.test.cpp b/test/geometry/line_atlas.test.cpp
new file mode 100644
index 0000000000..960e4ad7ad
--- /dev/null
+++ b/test/geometry/line_atlas.test.cpp
@@ -0,0 +1,31 @@
+#include <mbgl/test/util.hpp>
+
+#include <mbgl/geometry/line_atlas.hpp>
+
+#include <random>
+
+using namespace mbgl;
+
+TEST(LineAtlas, Random) {
+ std::mt19937 generator(42); // Use the same seed for reproducible tests.
+ std::uniform_int_distribution<size_t> countDistribution(0, 12);
+ std::uniform_int_distribution<size_t> capStyleDistribution(0, 1);
+ std::normal_distribution<float> lengthDistribution(3, 5);
+
+ for (size_t it = 0; it < 100; it++) {
+ LineAtlas atlas{ Size{ 128, 1024 } };
+ std::vector<float> dasharray;
+ dasharray.reserve(8);
+ for (size_t j = 0; j < 100; j++) {
+ dasharray.resize(0);
+ const size_t count = countDistribution(generator);
+ for (size_t i = 0; i < count; i++) {
+ dasharray.push_back(lengthDistribution(generator));
+ }
+ const LinePatternCap patternCap =
+ capStyleDistribution(generator) > 0 ? LinePatternCap::Round : LinePatternCap::Square;
+
+ atlas.addDash(dasharray, patternCap);
+ }
+ }
+}