Skip to content

anari: fix crash on curves without primitive.index or vertex.radius - #87

Merged
iwald-nvidia merged 1 commit into
NVIDIA:mainfrom
MaxFreedomPollard:fix/curve-optional-params
Oct 26, 2026
Merged

iwald-nvidia merged 1 commit into
NVIDIA:mainfrom
MaxFreedomPollard:fix/curve-optional-params

Conversation

@MaxFreedomPollard

Copy link
Copy Markdown
Contributor

primitive.index and vertex.radius are optional on curve geometry (only vertex.position is required in KHR_GEOMETRY_CURVE, which barney advertises), but barney/anari/Geometry.cpp dereferences both without a null check:

  • Curve::setBarneyParameters() reads m_index->totalSize() (line 636). A curve without an index segfaults on the first render, or on the first world bounds query, since that builds the model too.
  • Curve::bounds() reads m_vertexRadius->beginAs<float>() (line 669). A curve that relies on the global radius segfaults when the world bounds are queried.

The ANARI SDK's test/random_curves scene, which has an unindexed curve with a global radius, crashes on both lines. So does this minimal pynari case:

geom = device.newGeometry('curve')
geom.setParameter('vertex.position', anari.ARRAY1D,
                  device.newArray1D(anari.FLOAT32_VEC3, positions))
geom.setParameter('radius', anari.FLOAT32, .2)  # no primitive.index, no vertex.radius
geom.commitParameters()
# ... surface, world
world.getBounds()  # or frame.render(): SIGSEGV

Fix

  • Without primitive.index, every vertex except the last one starts a segment, as in helide. Indexed curves are unchanged.
  • Without per-vertex radii, Curve::bounds() uses the global radius, under the same condition setBarneyParameters() already uses.

unitTests/curve-optional-params.py renders such a curve and checks the world bounds and the covered pixels. It calls World.getBounds(), which is in pynari master but not in the 1.4.0 release.

Testing

I built barney_cpu (Embree backend) on macOS arm64 with Apple clang 21, against ANARI-SDK main (0.17.0). I built pynari master against the same SDK and loaded barney_cpu through ANARI_LIBRARY. I ran each case on main, with only one of the two hunks, and with the full fix:

main index hunk only bounds hunk only this PR
unindexed curve, render SIGSEGV ok SIGSEGV ok
indexed curve with global radius, world bounds SIGSEGV SIGSEGV ok bounds (-1.2,-0.2,-0.2)-(1.2,0.2,0.2)
SDK test/random_curves: bounds, default camera, render SIGSEGV SIGSEGV SIGSEGV renders (2044 of 128x128 pixels hit)
unitTests/curve-optional-params.py SIGSEGV SIGSEGV SIGSEGV passes

The existing tests/*.sh still pass. I did not build or run the CUDA, OptiX or HIP backends because this machine has no GPU. The change is in the backend-independent ANARI layer.

🤖 Generated with Claude Code

Both parameters are optional on 'curve' geometry (KHR_GEOMETRY_CURVE),
but Curve::setBarneyParameters() dereferenced m_index unconditionally
and Curve::bounds() dereferenced m_vertexRadius. A curve without an
index crashed on the first render, and one without per-vertex radii
crashed when the world bounds were queried. The ANARI SDK's
test/random_curves scene, which has an unindexed curve with a global
radius, segfaulted in both places.

Without an index, every vertex except the last one now starts a
segment, as in helide. Without per-vertex radii, the bounds use the
global radius, as setBarneyParameters() already did.

Add a pynari unit test that renders such a curve and checks the world
bounds.

Signed-off-by: Max Freedom Pollard <[email protected]>
Co-Authored-By: Claude Opus 5.5 <[email protected]>
@iwald-nvidia
iwald-nvidia merged commit 94af9d7 into NVIDIA:main Oct 26, 2026
14 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants