-
Notifications
You must be signed in to change notification settings - Fork 261
Description
Summary
There are three bugs in GeoJsonDocumentRasterOverlayTileProvider::loadTileImage that cause crashes when using GeoJsonDocumentRasterOverlay. All three were discovered through cesium-unity integration on Windows 10 with cesium-native 0.57.0.
Bug 1: Use-after-free — _tree captured by reference in worker thread lambda
The loadTileImage lambda captures _tree by reference:
return this->getAsyncSystem().runInWorkerThread(
[&tree = this->_tree, // <-- captured by reference
pDocument = this->_pDocument,
...When tiles unload and the tile provider's reference count reaches zero, the object (including _tree) gets destroyed while queued worker threads still hold a dangling reference.
Fix: Convert _tree to std::shared_ptr<Quadtree> and capture it by value in the lambda:
[pTree = this->_pTree, // captured by value — shared ownershipBug 2: Use-after-free — QuadtreeGeometryData::pStyle is a raw pointer to tile provider's _defaultStyle
QuadtreeGeometryData stored a raw pointer to the tile provider's _defaultStyle:
struct QuadtreeGeometryData {
const VectorStyle* pStyle; // raw pointer — dangles when tile provider is destroyed
};When the tile provider is destroyed, _defaultStyle is freed, but worker threads still access it through the raw pointer.
Fix: Store VectorStyle by value instead of a raw pointer:
struct QuadtreeGeometryData {
VectorStyle style; // stored by value — safe
};Bug 3: Crash from zero-dimension texture size
The texture size computation can produce a zero width or height:
glm::ivec2 textureSize = glm::min(
glm::ivec2(
overlayTile.getTargetScreenPixels() /
options.maximumScreenSpaceError),
glm::ivec2(options.maximumTextureSize));When getTargetScreenPixels() returns a small value in one dimension, dividing by maximumScreenSpaceError (e.g. 2.0) and truncating to int can produce 0. This causes Blend2D to crash when creating a BLImage with zero height or width.
Fix: Clamp the texture size to a minimum of 1×1:
glm::ivec2 textureSize = glm::max(
glm::min(
glm::ivec2(
overlayTile.getTargetScreenPixels() /
options.maximumScreenSpaceError),
glm::ivec2(options.maximumTextureSize)),
glm::ivec2(1));Environment
- cesium-native version: 0.57.0
- OS: Windows 10
- Discovered through: cesium-unity integration