Skip to content

Commit 9c9ee01

Browse files
authored
Merge pull request #1314 from baruchInsert-tech/fix/use-after-free-geojson-loadtileimage
Fix crashes in GeoJsonDocumentRasterOverlayTileProvider::loadTileImage
2 parents a42b513 + 5152a3d commit 9c9ee01

File tree

2 files changed

+25
-25
lines changed

2 files changed

+25
-25
lines changed

CHANGES.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
- `Cesium3DTilesetSelection::Tileset::getRootTileAvailableEvent` will now resolve even when a `Tileset` is constructed with invalid source parameters, instead of hanging indefinitely.
1818
- Fixed compilation error with MSVC when using custom `CesiumITwinClient::PagedList` types.
1919
- Fixed a "maybe uninitialized" error in `GeoJsonDocumentRasterOverlay` signaled by gcc 15.2.
20+
- Fixed crashes in `GeoJsonDocumentRasterOverlay` caused by the `GeoJsonDocumentRasterOverlayTileProvider` being freed before actions on the worker thread completed.
2021

2122
### v0.58.0 - 2026-03-02
2223

CesiumRasterOverlays/src/GeoJsonDocumentRasterOverlay.cpp

Lines changed: 24 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -214,6 +214,7 @@ struct QuadtreeNode {
214214
struct Quadtree {
215215
GlobeRectangle rectangle = GlobeRectangle::EMPTY;
216216
uint32_t rootId = 0;
217+
VectorStyle defaultStyle;
217218
std::vector<QuadtreeNode> nodes;
218219
std::vector<QuadtreeGeometryData> data;
219220
/**
@@ -555,28 +556,24 @@ uint32_t buildQuadtreeNode(
555556
return resultId;
556557
}
557558

558-
Quadtree buildQuadtree(
559+
void buildQuadtree(
560+
Quadtree& tree,
559561
const std::shared_ptr<GeoJsonDocument>& document,
560562
const VectorStyle& defaultStyle,
561563
const Ellipsoid& ellipsoid) {
564+
tree.defaultStyle = defaultStyle;
565+
562566
BoundingRegionBuilder builder;
563-
std::vector<QuadtreeGeometryData> data;
564567
const std::optional<VectorStyle>& rootObjectStyle =
565568
document->rootObject.getStyle();
566569
addPrimitivesToData(
567570
&document->rootObject,
568-
data,
571+
tree.data,
569572
builder,
570-
rootObjectStyle ? *rootObjectStyle : defaultStyle,
573+
rootObjectStyle ? *rootObjectStyle : tree.defaultStyle,
571574
ellipsoid);
572575

573-
Quadtree tree{
574-
builder.toGlobeRectangle(),
575-
0,
576-
std::vector<QuadtreeNode>(),
577-
std::move(data),
578-
std::vector<uint32_t>(),
579-
std::vector<uint32_t>()};
576+
tree.rectangle = builder.toGlobeRectangle();
580577

581578
std::vector<uint32_t> dataIndices;
582579
dataIndices.reserve(tree.data.size());
@@ -598,8 +595,6 @@ Quadtree buildQuadtree(
598595
QuadtreeTileID(0, 0, 0));
599596
// Add last entry so [i + 1] is always valid
600597
tree.dataNodeIndicesBegin.emplace_back((uint32_t)tree.dataIndices.size());
601-
602-
return tree;
603598
}
604599

605600
void rasterizeQuadtreeNode(
@@ -684,8 +679,7 @@ class CESIUMRASTEROVERLAYS_API GeoJsonDocumentRasterOverlayTileProvider final
684679

685680
private:
686681
std::shared_ptr<GeoJsonDocument> _pDocument;
687-
VectorStyle _defaultStyle;
688-
Quadtree _tree;
682+
std::shared_ptr<Quadtree> _pTree;
689683
Ellipsoid _ellipsoid;
690684
uint32_t _mipLevels;
691685

@@ -703,14 +697,15 @@ class CESIUMRASTEROVERLAYS_API GeoJsonDocumentRasterOverlayTileProvider final
703697
GeographicProjection(geoJsonOptions.ellipsoid),
704698
GlobeRectangle::MAXIMUM)),
705699
_pDocument(std::move(pDocument)),
706-
_defaultStyle(geoJsonOptions.defaultStyle),
707-
_tree(),
700+
_pTree(),
708701
_ellipsoid(geoJsonOptions.ellipsoid),
709702
_mipLevels(geoJsonOptions.mipLevels) {
710703
CESIUM_ASSERT(this->_pDocument);
711-
this->_tree = buildQuadtree(
704+
this->_pTree = std::make_shared<Quadtree>();
705+
buildQuadtree(
706+
*this->_pTree,
712707
this->_pDocument,
713-
this->_defaultStyle,
708+
geoJsonOptions.defaultStyle,
714709
geoJsonOptions.ellipsoid);
715710
}
716711

@@ -719,19 +714,23 @@ class CESIUMRASTEROVERLAYS_API GeoJsonDocumentRasterOverlayTileProvider final
719714
// Choose the texture size according to the geometry screen size and raster
720715
// SSE, but no larger than the maximum texture size.
721716
const RasterOverlayOptions& options = this->getOwner().getOptions();
722-
glm::ivec2 textureSize = glm::min(
723-
glm::ivec2(
724-
overlayTile.getTargetScreenPixels() /
725-
options.maximumScreenSpaceError),
726-
glm::ivec2(options.maximumTextureSize));
717+
glm::ivec2 textureSize = glm::max(
718+
glm::min(
719+
glm::ivec2(
720+
overlayTile.getTargetScreenPixels() /
721+
options.maximumScreenSpaceError),
722+
glm::ivec2(options.maximumTextureSize)),
723+
glm::ivec2(1));
727724

728725
return this->getAsyncSystem().runInWorkerThread(
729-
[&tree = this->_tree,
726+
[pTree = this->_pTree,
727+
pDocument = this->_pDocument,
730728
ellipsoid = this->_ellipsoid,
731729
projection = this->getProjection(),
732730
rectangle = overlayTile.getRectangle(),
733731
textureSize,
734732
mipLevels = this->_mipLevels]() -> LoadedRasterOverlayImage {
733+
const Quadtree& tree = *pTree;
735734
const CesiumGeospatial::GlobeRectangle tileRectangle =
736735
CesiumGeospatial::unprojectRectangleSimple(projection, rectangle);
737736

0 commit comments

Comments
 (0)