Fix crash when feature contains invalid UTF-8 data (#2693)

This commit is contained in:
Bart Louwers
2024-08-06 20:32:27 +02:00
committed by GitHub
parent a417e700d1
commit 5ededddf8b
14 changed files with 75 additions and 24 deletions

View File

@@ -11,7 +11,7 @@ protected:
const style::conversion::Convertible& value) noexcept final;
std::unique_ptr<Layout> createLayout(const LayoutParameters& parameters,
std::unique_ptr<GeometryTileLayer> tileLayer,
const std::vector<Immutable<style::LayerProperties>>& group) noexcept final;
const std::vector<Immutable<style::LayerProperties>>& group) final;
std::unique_ptr<RenderLayer> createRenderLayer(Immutable<style::Layer::Impl>) noexcept final;
};

View File

@@ -11,7 +11,7 @@ protected:
const style::conversion::Convertible& value) noexcept final;
std::unique_ptr<Layout> createLayout(const LayoutParameters&,
std::unique_ptr<GeometryTileLayer>,
const std::vector<Immutable<style::LayerProperties>>&) noexcept final;
const std::vector<Immutable<style::LayerProperties>>&) final;
std::unique_ptr<RenderLayer> createRenderLayer(Immutable<style::Layer::Impl>) noexcept final;
};

View File

@@ -11,7 +11,7 @@ protected:
const style::conversion::Convertible& value) noexcept final;
std::unique_ptr<Layout> createLayout(const LayoutParameters&,
std::unique_ptr<GeometryTileLayer>,
const std::vector<Immutable<style::LayerProperties>>&) noexcept final;
const std::vector<Immutable<style::LayerProperties>>&) final;
std::unique_ptr<RenderLayer> createRenderLayer(Immutable<style::Layer::Impl>) noexcept final;
};

View File

@@ -38,7 +38,7 @@ public:
/// Returns a new Layout instance on success call; returns `nullptr` otherwise.
virtual std::unique_ptr<Layout> createLayout(const LayoutParameters&,
std::unique_ptr<GeometryTileLayer>,
const std::vector<Immutable<style::LayerProperties>>&) noexcept;
const std::vector<Immutable<style::LayerProperties>>&);
protected:
std::optional<std::string> getSource(const style::conversion::Convertible& value) const noexcept;

View File

@@ -11,7 +11,7 @@ protected:
const style::conversion::Convertible& value) noexcept final;
std::unique_ptr<Layout> createLayout(const LayoutParameters& parameters,
std::unique_ptr<GeometryTileLayer> tileLayer,
const std::vector<Immutable<style::LayerProperties>>& group) noexcept final;
const std::vector<Immutable<style::LayerProperties>>& group) final;
std::unique_ptr<RenderLayer> createRenderLayer(Immutable<style::Layer::Impl>) noexcept final;
};

View File

@@ -4,6 +4,8 @@ MapLibre welcomes participation and contributions from everyone. Please read [`C
## main
- Fix reported [crash](https://github.com/maplibre/maplibre-native/issues/2678) when feature contains invalid UTF-8 data.
## 6.5.3
- Disabled iOS 14 metal options ([#2620](https://github.com/maplibre/maplibre-native/pull/2620)).

View File

@@ -18,10 +18,9 @@ std::unique_ptr<style::Layer> CircleLayerFactory::createLayer(const std::string&
return std::unique_ptr<style::Layer>(source ? new (std::nothrow) style::CircleLayer(id, *source) : nullptr);
}
std::unique_ptr<Layout> CircleLayerFactory::createLayout(
const LayoutParameters& parameters,
std::unique_ptr<GeometryTileLayer> layer,
const std::vector<Immutable<style::LayerProperties>>& group) noexcept {
std::unique_ptr<Layout> CircleLayerFactory::createLayout(const LayoutParameters& parameters,
std::unique_ptr<GeometryTileLayer> layer,
const std::vector<Immutable<style::LayerProperties>>& group) {
return std::unique_ptr<Layout>(new (std::nothrow)
CircleLayout(parameters.bucketParameters, group, std::move(layer)));
}

View File

@@ -20,7 +20,7 @@ std::unique_ptr<style::Layer> FillExtrusionLayerFactory::createLayer(
std::unique_ptr<Layout> FillExtrusionLayerFactory::createLayout(
const LayoutParameters& parameters,
std::unique_ptr<GeometryTileLayer> layer,
const std::vector<Immutable<style::LayerProperties>>& group) noexcept {
const std::vector<Immutable<style::LayerProperties>>& group) {
using namespace style;
using LayoutType = PatternLayout<FillExtrusionBucket, FillExtrusionLayerProperties, FillExtrusionPattern>;
return std::unique_ptr<Layout>(new (std::nothrow)

View File

@@ -17,10 +17,9 @@ std::unique_ptr<style::Layer> FillLayerFactory::createLayer(const std::string& i
return std::unique_ptr<style::Layer>(source ? new (std::nothrow) style::FillLayer(id, *source) : nullptr);
}
std::unique_ptr<Layout> FillLayerFactory::createLayout(
const LayoutParameters& parameters,
std::unique_ptr<GeometryTileLayer> layer,
const std::vector<Immutable<style::LayerProperties>>& group) noexcept {
std::unique_ptr<Layout> FillLayerFactory::createLayout(const LayoutParameters& parameters,
std::unique_ptr<GeometryTileLayer> layer,
const std::vector<Immutable<style::LayerProperties>>& group) {
using namespace style;
using LayoutTypeUnsorted = PatternLayout<FillBucket, FillLayerProperties, FillPattern, FillLayoutProperties>;
using LayoutTypeSorted =

View File

@@ -33,7 +33,7 @@ std::unique_ptr<Bucket> LayerFactory::createBucket(const BucketParameters&,
std::unique_ptr<Layout> LayerFactory::createLayout(const LayoutParameters&,
std::unique_ptr<GeometryTileLayer>,
const std::vector<Immutable<style::LayerProperties>>&) noexcept {
const std::vector<Immutable<style::LayerProperties>>&) {
assert(false);
return nullptr;
}

View File

@@ -17,10 +17,9 @@ std::unique_ptr<style::Layer> SymbolLayerFactory::createLayer(const std::string&
return std::unique_ptr<style::Layer>(source ? new (std::nothrow) style::SymbolLayer(id, *source) : nullptr);
}
std::unique_ptr<Layout> SymbolLayerFactory::createLayout(
const LayoutParameters& parameters,
std::unique_ptr<GeometryTileLayer> tileLayer,
const std::vector<Immutable<style::LayerProperties>>& group) noexcept {
std::unique_ptr<Layout> SymbolLayerFactory::createLayout(const LayoutParameters& parameters,
std::unique_ptr<GeometryTileLayer> tileLayer,
const std::vector<Immutable<style::LayerProperties>>& group) {
return std::unique_ptr<Layout>(
new (std::nothrow) SymbolLayout(parameters.bucketParameters, group, std::move(tileLayer), parameters));
}

View File

@@ -156,11 +156,19 @@ SymbolLayout::SymbolLayout(const BucketParameters& parameters,
} else if (textTransform == TextTransformType::Lowercase) {
u8string = platform::lowercase(u8string);
}
ft.formattedText->addTextSection(applyArabicShaping(util::convertUTF8ToUTF16(u8string)),
section.fontScale ? *section.fontScale : 1.0,
section.fontStack ? *section.fontStack : baseFontStack,
section.textColor);
try {
ft.formattedText->addTextSection(applyArabicShaping(util::convertUTF8ToUTF16(u8string)),
section.fontScale ? *section.fontScale : 1.0,
section.fontStack ? *section.fontStack : baseFontStack,
section.textColor);
} catch (...) {
mbgl::Log::Error(
mbgl::Event::ParseTile,
"Encountered section with invalid UTF-8 in tile, source: " + sourceLayer->getName() +
" z: " + std::to_string(canonicalID.z) + " x: " + std::to_string(canonicalID.x) +
" y: " + std::to_string(canonicalID.y));
continue; // skip section
}
} else {
layoutParameters.imageDependencies.emplace(section.image->id(), ImageType::Icon);
ft.formattedText->addImageSection(section.image->id());

Binary file not shown.

View File

@@ -1640,3 +1640,47 @@ TEST(Map, StencilOverflow) {
// TODO: confirm that the stencil masking actually worked
}
TEST(Map, InvalidUTF8InTile) {
FixtureLog log;
MapTest<> test{1, MapMode::Continuous};
test.fileSource->tileResponse = [&](const Resource&) {
Response result;
result.data = std::make_shared<std::string>(
util::read_file("test/fixtures/map/invalid_utf8/invalidutf8feature.mvt"));
return result;
};
test.fileSource->glyphsResponse = makeResponse("glyphs.pbf", true);
test.map.jumpTo(CameraOptions().withZoom(11.0));
test.map.getStyle().loadJSON(R"STYLE({
"version": 8,
"sources": {
"invalidutf8": {
"type": "vector",
"tiles": ["http://example.com/{z}-{x}-{y}.vector.pbf"]
}
},
"layers": [{
"id": "mountain_peak",
"type": "symbol",
"source": "invalidutf8",
"source-layer": "points",
"layout": {
"text-field": "{name}"
}
}]
})STYLE");
test.observer.didFinishLoadingMapCallback = [&]() {
test.observer.didFinishRenderingFrameCallback = [&](MapObserver::RenderFrameStatus status) {
if (!status.needsRepaint) {
test.runLoop.stop();
}
};
};
test.runLoop.run();
}