fix: use callback() for missing raster-dem tiles to prevent segfault#2139
fix: use callback() for missing raster-dem tiles to prevent segfault#2139JeremyBYU wants to merge 1 commit into
Conversation
fc6b4c9 to
8f28ce4
Compare
There was a problem hiding this comment.
Pull request overview
Prevents MapLibre GL Native crashes when rendering styles that include local raster-dem (terrain) sources with missing tiles by ensuring missing DEM tiles go through MapLibre’s “no content” callback path rather than generating a 1×1 placeholder image.
Changes:
- Treat missing
raster-demtiles as “no content” (callback()) even whensparseis explicitlyfalse. - Add an inline comment documenting the segfault scenario and linking to the issue.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| // raster-dem: 1x1 placeholder causes backfillBorder segfault (#2065) | ||
| if (sparse || sourceInfo.type === 'raster-dem') { |
There was a problem hiding this comment.
This change prevents 1×1 placeholders for missing raster-dem tiles in the mbtiles/pmtiles path, but the http/https request path still calls createEmptyResponse() (1×1 PNG) for non-OK responses whenever options.sparse is false. If those remote requests are raster-dem tiles, the same DEM dimension mismatch/crash risk can still exist. Consider extending the raster-dem safeguard to the remote code path (or clarifying in code/docs that the fix applies only to local sources).
| // raster-dem: 1x1 placeholder causes backfillBorder segfault (#2065) | ||
| if (sparse || sourceInfo.type === 'raster-dem') { | ||
| callback(); | ||
| return; |
There was a problem hiding this comment.
There’s no regression test covering the crash scenario this guard is meant to prevent (raster-dem source with sparse explicitly false and at least one missing tile next to a real neighbor). Adding an integration test that renders a tile/static image using a raster-dem MBTiles/PMTiles source with a deliberately missing tile would help ensure this doesn’t regress and that the server doesn’t crash under that configuration.
There was a problem hiding this comment.
@copilot apply changes based on this feedback
You could download gebco terrarium raster-dem tiles from my server at https://tiles.wifidb.net/data/ocean-rgb/{z}/{x}/{y}.webp (https://tiles.wifidb.net/data/ocean-rgb.json) for the test, what has z0 - Z8 tiles. the gebco terrain tiles are public domain licensed, so they are good for tests
…#2065 Agent-Logs-Url: https://github.com/maptiler/tileserver-gl/sessions/c9862e9c-6307-4265-abc5-a83922f5519e Co-authored-by: acalcutt <3792408+acalcutt@users.noreply.github.com>
…#2065 Agent-Logs-Url: https://github.com/maptiler/tileserver-gl/sessions/c9862e9c-6307-4265-abc5-a83922f5519e Co-authored-by: acalcutt <3792408+acalcutt@users.noreply.github.com>
Missing raster-dem tiles were routed through createEmptyResponse() when sparse=false, generating a 1x1 PNG. This caused a dimension mismatch segfault in maplibre-native's DEMData::backfillBorder(). Fixes maptiler#2065 Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
8f28ce4 to
d852b87
Compare
Summary
When the internal renderer (
serve_rendered.js) requests a tile from a local mbtiles/pmtiles source and the tile doesn't exist,createEmptyResponse()generates a 1×1 pixel PNG. Forraster-demsources, this 1×1 PNG is passed to maplibre-native as valid DEM tile data. WhenDEMData::backfillBorder()later runs between this tile and a real 256×256 neighbor, the dimension mismatch causes an out-of-bounds memory read — segfault.This PR adds
sourceInfo.type === 'raster-dem'to the existingsparsecheck so that missing DEM tiles always take thecallback()(no-content) path, regardless of thesparseflag.What changed
One condition added in
src/serve_rendered.js:callback()with zero arguments is maplibre-native's designed "no content" path:TileLoader→setData(nullptr)raster_dem_tile_worker.cpp→ skips image decodingraster_dem_tile.cpp→renderable = falserender_raster_dem_source.cpp→isRenderable()returns false → backfill loop skippedWhy only raster-dem?
createEmptyResponserespectssourceInfo.color— a source can specify what color empty tiles should be. Changing this for non-DEM sources would be a breaking change. Forraster-demsources,sourceInfo.coloris meaningless (DEM tiles are elevation data, not visual), socallback()is strictly correct.Risk
Minimal. Since v5.4.0,
sparsedefaults totrue, so the vast majority of raster-dem sources already hit thecallback()path. This change only affects the edge case wheresparseis explicitly set tofalseon a raster-dem source — which can cause a crash depending on memory layout and neighbor tile timing.Fixes #2065
Related: maplibre/maplibre-native#4160