Skip to content

renderdem segfault when using --decimation > 1 (out-of-bounds write in point_io.cpp) #2

Description

@JinyuJia-bot

Description

renderdem consistently crashes with a Segmentation fault (core dumped) when using --decimation > 1 with LAZ point cloud inputs. The crash does NOT occur when --decimation=1.

Reproduction

  1. Run renderdem with --decimation > 1 on a large LAZ file (164M points):
    ./renderdem "/datasets/PhaseOne_cut/odm_georeferencing/odm_georeferenced_model.laz" \
      --outdir "/datasets/PhaseOne_cut/odm_dem" \
      --output-type max \
      --radiuses 0.11,0.15556349186104046,0.22 \
      --resolution 20 \
      --decimation 50 \
      --classification -1 \
      --force
  2. Observe immediate segfault;
  3. Run the same command with --decimation=1 → no crash, DEM generates successfully.

Terminal Output (Fault Case)

Decimation set to 50
Reading points from /datasets/PhaseOne_cut/odm_georeferencing/odm_georeferenced_model.laz
Number of points: 164352797
Classification dimension: Classification
Segmentation fault (core dumped)

Terminal Output (Working Case, --decimation=1)

Reading points from /datasets/PhaseOne_cut/odm_georeferencing/odm_georeferenced_model.laz
Number of points: 164352797
Classification dimension: Classification
Point cloud bounds are [minx: 600123.28, maxx: 603468.245, miny: 3601441.208, maxy: 3604695.694]
DEM resolution is (168, 163), max tile size is 4096, will split DEM generation into 1 tiles
r0.11_x0_y0.tif
r0.155563_x0_y0.tif
r0.22_x0_y0.tif
...

Root Cause

The decimation logic is inverted in point_io.cpp, leading to an out-of-bounds memory write:

  1. Memory is pre-allocated for count / decimation points (expected to keep 1/N points):
    r->resize(count / decimation); // Allocates space for 1/50 of points 
  2. The loop skips points incorrectly (keeps 49/50 points instead of 1/50):
    if (decimate && idx % decimation == 0) continue; // Skips Nth point (wrong)
  3. This mismatch causes the program to write past the allocated memory buffer → segfault.

Proposed Fix

Correct the decimation condition to keep every Nth point (consistent with the CLI help text: "Read every Nth point"):

// Replace this (wrong):
...
r->resize(count / decimation); 
...
if (decimate && idx % decimation == 0) continue;

// With this (correct):
...
r->resize((count + decimation - 1) / decimation); // ceil(count/decimation)
...
if (decimate && (idx % decimation) != 0) continue;

Apply this fix to both:

  • pdalReadPointSet()
  • fastPlyReadPointSet() (ASCII and binary)

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions