Closed yaobinwen-mvs closed 4 years ago
I tried several other writers:
writers.bpf "Binary Point Format" (BPF) writer support. BPF is a simple DoD and research format that is used by some sensor and processing chains.
writers.gdal Write a point cloud as a GDAL raster.
writers.gltf Gltf Writer
writers.las ASPRS LAS 1.0 - 1.4 writer. LASzip support is also available if enabled at compile-time. Note that LAZ does not provide LAS 1.4 support at this time.
They don't have this problem. I haven't tried all the other available writers.
Describe the bug
When
PlyWriter::prepared
is called more than once, them_dims
will have more members thanm_dimNames
which later causes an exception to be thrown when dereferencing am_dimNames
iteratorni
here.Reproduce the bug
Step 1: Check out the PDAL and its Python extension code. See the section below for the versions I'm using.
Step 2: Build and install PDAL according to the documentation.
Step 3: Build and install PDAL's Python extension according to the documentation. Note that
python3
should be used.Step 4: Run the following Python code, saved in a file called
bug.py
, to see the exception. I'm not sure if there is a way to reproduce it with the C++ API.Actual result
The following exception and call stack was printed:
Note: I'm not sure why, but some other times the exception was a
bad_alloc
:My analysis
In the Python code,
pipeline.validate()
callsPipelineExecutor::validate()
which further callsm_manager.prepare();
. This finally callsStage::prepared()
. This is the first timePlyWriter::prepared
is called, som_dimNames.size()
is zero and theelse
branch is called. After the call, bothm_dims
andm_dimNames
have 3 elements (X, Y, and Z).Later, when
pipeline.execute()
is called,Stage::prepared
is finally called again. This time,m_dimNames.size()
is 3 so thetrue
branch of theif
is called, resultingm_dims
to be pushed back three dimensions again. After the call,m_dims
has 6 elements butm_dimNames
still 3 elements.Later,
PlyWriter::writeHeader
is called from withinPlyWriter::ready
.m_dimNames
's iteratorni
is assgined to its beginning, but it'sm_dims
that gets iterated through, andni
is dereferenced inside thefor
loop:Because
m_dims
has 6 elements butm_dimNames
has only 3, as I have analyzed above,ni
is incorrectly dereferenced when it already points at the end ofm_dimNames
, which results in the exception.Expected behavior
The Python demo code calls both
validate()
andexecute()
, so I assume calling both should be allowed, andPlyWriter::prepared
should make surem_dims
andm_dimNames
have the same length no matter how many times this method is called.I've read through the PDAL documentation, especially the Making a Stage (Reader, Filter or Writer). The document there doesn't require
Stage::prepared
have no side effects when called multiple times, nor did I read anywhere else that requires this.System/installation information:
PDAL: I'm using the latest
master
on Oct. 7th, 2019, at this commit: 2033fdd8dcbd54551a8e1646939155590d277888PDAL Python: I'm using the latest
master
on Sep 19, 2019, at this commit: PDAL/python@0da1fb7dcba0e006cda4700048dac8dfba556548I'm using Ubuntu 18.04.
I didn't install it via Conda. I built it by myself with
cmake
andmake
.