TDF_Label.FindAttribute segfaults when the attribute is absent

Open
#225 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Assessment

Difficulty
3/5
Estimated time
1-2 days
Newbie friendliness
58/100
Issue type
Bug
Clarity
Mostly clear
Activity status
Active
Tech stack
cpp, python
Domain
api, backend

Research direction

The issue names the Python binding entry point TDF_Label.FindAttribute but no source file or test. Start by locating that binding and run the minimal absent-attribute reproducer, then verify the present-attribute control case. Done means an absent attribute returns safely without SIGSEGV while the existing present-attribute behavior remains intact.

Written by the indexing model from the issue text.

Description

Summary

TDF_Label.FindAttribute segfaults when the requested attribute is not present on the label.
When the attribute is present it returns normally. There is no exception to catch — the process
dies with SIGSEGV.

This is related to #153 (open) and #55 (closed), but both of those report the attribute-present
path returning an unpopulated handle. The absent path crashing does not appear to be reported.

Minimal reproducer

No STEP file or external data needed:

from OCP.TCollection import TCollection_ExtendedString
from OCP.TDocStd import TDocStd_Document
from OCP.TDataStd import TDataStd_Name

doc = TDocStd_Document(TCollection_ExtendedString("XCAF"))
label = doc.Main()                                   # a label with no TDataStd_Name

print("IsAttribute:", label.IsAttribute(TDataStd_Name.GetID_s()))   # -> False, safe
n = TDataStd_Name()
label.FindAttribute(TDataStd_Name.GetID_s(), n)                     # -> SIGSEGV
IsAttribute: False
[1]    segmentation fault

Exit status 139.

Control: attribute present works

from OCP.TCollection import TCollection_ExtendedString
from OCP.TDocStd import TDocStd_Document
from OCP.TDataStd import TDataStd_Name

doc = TDocStd_Document(TCollection_ExtendedString("XCAF"))
label = doc.Main()
TDataStd_Name.Set_s(label, TCollection_ExtendedString("hello"))

n = TDataStd_Name()
print("returned:", label.FindAttribute(TDataStd_Name.GetID_s(), n))  # True
print("name:", n.Get().ToExtString())                                # hello

Runs clean, exit 0.

Not specific to TDataStd_Name

Same crash with the same shape of call:

attribute type exit status
TDataStd_Name 139 (SIGSEGV)
TDataStd_Integer 139 (SIGSEGV)
TDataStd_Real 139 (SIGSEGV)

Environment

  • cadquery-ocp-novtk 7.9.3.1 (OCCT 7.9.3)
  • Python 3.14.7
  • macOS 15 (Darwin 25.6.0), arm64

Safe alternatives

Both of these work on the exact label that crashes FindAttribute:

  • label.IsAttribute(guid) returns False without crashing.
  • TDF_AttributeIterator(label) enumerates the label's attributes normally. This is the
    reimplementation suggested in #153 and it appears to be the reliable path today.

Real-world impact

This is reachable from ordinary library code. build123d's import_step calls FindAttribute
unguarded on every assembly component label to read its name, so any STEP file containing an
assembly component without a name attribute kills the interpreter. I hit it on the public NIST
MBE PMI conformance model nist_ctc_02_asme1_ap242-e2.stp, whose component label carries
TNaming_NamedShape, TDataStd_UAttribute, TDF_TagSource and TDataStd_TreeNode but no
TDataStd_Name. Because it is a segfault rather than an exception, a service cannot defend itself
against it with try/except.

Note on cause

I have verified the behavioural boundary (absent → crash, present → fine, IsAttribute and
TDF_AttributeIterator safe) but not the underlying mechanism. Given #55 and #153 it looks like the
binding's handling of the Handle(TDF_Attribute)& out-parameter is wrong in a way that is merely
lossy when the attribute is found and memory-unsafe when it is not — but that is inference, not
something I have confirmed in the binding code.

Dominant language
C++
Stars
200
Forks
48
Avg merge
2d 2h
Merged PRs (30d)
6

Contributor guide

No contributing guide indexed for this repository

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

More from CadQuery/OCP

All issues in CadQuery/OCP

Similar issues

More C++ issues

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.