summaryrefslogtreecommitdiff
path: root/src/text
diff options
context:
space:
mode:
authorDane Springmeyer <dane@mapbox.com>2014-05-30 12:35:49 -0700
committerDane Springmeyer <dane@mapbox.com>2014-05-30 12:35:49 -0700
commit552b9a0f1bc86b617fd6d8163c5164eceeb01641 (patch)
tree7481fcc0514d4e55d72fe59d3d045b0e4d9e7f9e /src/text
parentc5fd7a0cddbf6825e3947bfbff418730b288b7bb (diff)
downloadqtlocation-mapboxgl-552b9a0f1bc86b617fd6d8163c5164eceeb01641.tar.gz
fix potential crash in line wrapping:
- shaping.size() == 0 would result in unsigned overflow because uint32_t(0) - 1 == huge number
Diffstat (limited to 'src/text')
-rw-r--r--src/text/glyph_store.cpp25
1 files changed, 14 insertions, 11 deletions
diff --git a/src/text/glyph_store.cpp b/src/text/glyph_store.cpp
index e93d9e9958..5e94a35f49 100644
--- a/src/text/glyph_store.cpp
+++ b/src/text/glyph_store.cpp
@@ -38,8 +38,7 @@ const Shaping FontStack::getShaping(const std::u32string &string, const float &m
Shaping shaping;
// Loop through all characters of this label and shape.
for (uint32_t chr : string) {
- GlyphPlacement glyph = GlyphPlacement(0, chr, x, 0);
- shaping.push_back(glyph);
+ shaping.emplace_back(0, chr, x, 0);
i++;
x += metrics.find(chr)->second.advance + letterSpacing;
}
@@ -58,18 +57,24 @@ void alignVertically(Shaping &shaping, const uint32_t &lines, const float &lineH
void alignHorizontally(Shaping &shaping, const std::map<uint32_t, GlyphMetrics> &metrics,
const uint32_t &start, const uint32_t &end, const float &alignment) {
-
- uint32_t lastAdvance = metrics.find(shaping[end].glyph)->second.advance;
- int32_t lineIndent = (shaping[end].x + lastAdvance) * alignment;
-
- for (uint32_t j = start; j <= end; j++) {
- shaping[j].x -= lineIndent;
+ auto & shape = shaping.at(end);
+ auto metric = metrics.find(shape.glyph);
+ if (metric != metrics.end()) {
+ uint32_t lastAdvance = metric->second.advance;
+ int32_t lineIndent = (shape.x + lastAdvance) * alignment;
+ for (uint32_t j = start; j <= end; j++) {
+ shaping[j].x -= lineIndent;
+ }
}
}
void FontStack::lineWrap(Shaping &shaping, const float &lineHeight, const float &maxWidth,
const float &alignment, const float &verticalAlignment) const {
+ std::size_t num_shapes = shaping.size();
+ if (!num_shapes) {
+ return;
+ }
uint32_t lastSafeBreak = 0;
uint32_t lengthBeforeCurrentLine = 0;
uint32_t lineStartIndex = 0;
@@ -77,11 +82,10 @@ void FontStack::lineWrap(Shaping &shaping, const float &lineHeight, const float
for (uint32_t i = 0; i < shaping.size(); i++) {
GlyphPlacement &shape = shaping[i];
-
shape.x -= lengthBeforeCurrentLine;
shape.y += lineHeight * line;
- if (shape.x > maxWidth && lastSafeBreak != 0) {
+ if (shape.x > maxWidth && lastSafeBreak > 0) {
uint32_t lineLength = shaping[lastSafeBreak + 1].x;
@@ -103,7 +107,6 @@ void FontStack::lineWrap(Shaping &shaping, const float &lineHeight, const float
lastSafeBreak = i;
}
}
-
alignHorizontally(shaping, metrics, lineStartIndex, shaping.size() - 1, alignment);
alignVertically(shaping, line + 1, lineHeight, verticalAlignment);
}