Skip to content

Crashes in GeoJsonDocumentRasterOverlayTileProvider::loadTileImage #1313

@baruchInsert-tech

Description

@baruchInsert-tech

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 ownership

Bug 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

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions