Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
30 changes: 18 additions & 12 deletions okf/references/carried-occt-patches.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ title: Carried OCCT source patches
resource: https://github.com/SecondMouseAU/OCCTSwift/tree/main/Scripts/patches
tags: [occt, patches, upstream, thread-safety, kernel]
description: Upstream-bound OCCT fixes OCCTSwift carries in its xcframework build until they ship in an OCCT release.
timestamp: 2026-07-30
timestamp: 2026-07-31
---

# Carried OCCT source patches
Expand All @@ -20,27 +20,33 @@ Each patch is also meant to be **offered upstream** as an OCCT PR. When you do,
[Upstream OCCT PRs — style and submission workflow](../policies/upstream-occt-style.md): clang-format
with OCCT's own `.clang-format`, OCCT's terse comment style — not OCCTSwift's — and, as of
2026-07-30, go straight to the PR rather than filing a separate repro issue first when the fix is
already in hand (an OCCT maintainer asked for exactly that). The table below still shows the older
repro-issue-then-fix-PR pattern for patches filed before that — left as the accurate historical
record, not something to retitle after the fact.
already in hand (an OCCT maintainer asked for exactly that). Rows `0001` to `0017` still show the
older repro-issue-then-fix-PR pattern, left as the accurate historical record rather than retitled
after the fact; `0018` is the first filed as a PR alone.

| Patch | Fixes | Upstream | Retire when |
|-------|-------|----------|-------------|
| `0001-ShapeFix_Face-…-263` | ShapeFix_Face compound-context crash ([#263](https://github.com/SecondMouseAU/OCCTSwift/issues/263)) | [OCCT#1322](https://github.com/Open-Cascade-SAS/OCCT/issues/1322) reports it; fix offered as **[OCCT#1323](https://github.com/Open-Cascade-SAS/OCCT/pull/1323)** (our PR, CI green, ready for review) | bundled OCCT includes the guard |
| `0001-ShapeFix_Face-…-263` | ShapeFix_Face compound-context crash ([#263](https://github.com/SecondMouseAU/OCCTSwift/issues/263)) | [OCCT#1322](https://github.com/Open-Cascade-SAS/OCCT/issues/1322) reports it; fix offered as **[OCCT#1323](https://github.com/Open-Cascade-SAS/OCCT/pull/1323)** (our PR, merged) | bundled OCCT includes the guard |
| `0002-STEPControl_Writer-…-1334` | XDE STEP read corrupts later STEP writes ([#280](https://github.com/SecondMouseAU/OCCTSwift/issues/280)) | [OCCT#1334](https://github.com/Open-Cascade-SAS/OCCT/pull/1334) (their fix, merged upstream; we backport) | bundled OCCT moves past that commit |
| `0003-TopOpeBRep-non-reentrant-globals-fillet-298` | Concurrent fillet/chamfer corrupts geometry (non-reentrant `STATIC_SOLIDINDEX` in the TopOpeBRepBuild solid reconstruction, [#298](https://github.com/SecondMouseAU/OCCTSwift/issues/298)) | **[OCCT#1374](https://github.com/Open-Cascade-SAS/OCCT/pull/1374)** (our PR, open, not yet released) | **an upstream OCCT release includes the `thread_local` conversion** |
| `0004-ShapeAnalysis_FreeBounds-…-310` | `ShapeAnalysis_FreeBounds` SIGSEGV on a compound of 2+ disjoint free-boundary components ([#310](https://github.com/SecondMouseAU/OCCTSwift/issues/310)) | [OCCT#1376](https://github.com/Open-Cascade-SAS/OCCT/issues/1376) (repro) → **[OCCT#1377](https://github.com/Open-Cascade-SAS/OCCT/pull/1377)** (our fix PR, open) | bundled OCCT includes the fix |
| `0005-ShapeFix_Face-…-317` | `ShapeFix_Face::FixPeriodicDegenerated` SIGSEGV on a single closed wire belting a cone's full period, no `SetContext()` set ([#317](https://github.com/SecondMouseAU/OCCTSwift/issues/317)) | [OCCT#1378](https://github.com/Open-Cascade-SAS/OCCT/issues/1378) (repro) → **[OCCT#1380](https://github.com/Open-Cascade-SAS/OCCT/pull/1380)** (our fix PR, open) | bundled OCCT includes the fix |
| `0006-BRepGProp_EdgeTool-…-318` | `BRepGProp_EdgeTool::IntegrationOrder` SIGSEGV on a degenerate edge whose sole geometry is a Bezier/BSpline curve-on-surface pcurve, no 3D curve ([#318](https://github.com/SecondMouseAU/OCCTSwift/issues/318)) | [OCCT#1381](https://github.com/Open-Cascade-SAS/OCCT/issues/1381) (repro) → **[OCCT#1382](https://github.com/Open-Cascade-SAS/OCCT/pull/1382)** (our fix PR, open) | bundled OCCT includes the fix |
| `0007-ShapeAnalysis_FreeBounds-…-323` | `connectWiresToWiresImpl` invalid-memory read: stale `lwire` when a skipped-loop candidate wire has zero edges ([#323](https://github.com/SecondMouseAU/OCCTSwift/issues/323) audit) | [OCCT#1330](https://github.com/Open-Cascade-SAS/OCCT/issues/1330) (repro) → [OCCT#1331](https://github.com/Open-Cascade-SAS/OCCT/pull/1331) (third-party fix PR, open — pinned to a commit) | bundled OCCT includes the fix |
| `0003-TopOpeBRep-non-reentrant-globals-fillet-298` | Concurrent fillet/chamfer corrupts geometry (non-reentrant `STATIC_SOLIDINDEX` in the TopOpeBRepBuild solid reconstruction, [#298](https://github.com/SecondMouseAU/OCCTSwift/issues/298)) | **[OCCT#1374](https://github.com/Open-Cascade-SAS/OCCT/pull/1374)** (our PR, merged, not yet in a release) | **an upstream OCCT release includes the `thread_local` conversion** |
| `0004-ShapeAnalysis_FreeBounds-…-310` | `ShapeAnalysis_FreeBounds` SIGSEGV on a compound of 2+ disjoint free-boundary components ([#310](https://github.com/SecondMouseAU/OCCTSwift/issues/310)) | [OCCT#1376](https://github.com/Open-Cascade-SAS/OCCT/issues/1376) (repro) → **[OCCT#1377](https://github.com/Open-Cascade-SAS/OCCT/pull/1377)** (our fix PR, merged) | bundled OCCT includes the fix |
| `0005-ShapeFix_Face-…-317` | `ShapeFix_Face::FixPeriodicDegenerated` SIGSEGV on a single closed wire belting a cone's full period, no `SetContext()` set ([#317](https://github.com/SecondMouseAU/OCCTSwift/issues/317)) | [OCCT#1378](https://github.com/Open-Cascade-SAS/OCCT/issues/1378) (repro) → **[OCCT#1380](https://github.com/Open-Cascade-SAS/OCCT/pull/1380)** (our fix PR, merged) | bundled OCCT includes the fix |
| `0006-BRepGProp_EdgeTool-…-318` | `BRepGProp_EdgeTool::IntegrationOrder` SIGSEGV on a degenerate edge whose sole geometry is a Bezier/BSpline curve-on-surface pcurve, no 3D curve ([#318](https://github.com/SecondMouseAU/OCCTSwift/issues/318)) | [OCCT#1381](https://github.com/Open-Cascade-SAS/OCCT/issues/1381) (repro) → **[OCCT#1382](https://github.com/Open-Cascade-SAS/OCCT/pull/1382)** (our fix PR, merged) | bundled OCCT includes the fix |
| `0007-ShapeAnalysis_FreeBounds-…-323` | `connectWiresToWiresImpl` invalid-memory read: stale `lwire` when a skipped-loop candidate wire has zero edges ([#323](https://github.com/SecondMouseAU/OCCTSwift/issues/323) audit) | [OCCT#1330](https://github.com/Open-Cascade-SAS/OCCT/issues/1330) (repro) → [OCCT#1331](https://github.com/Open-Cascade-SAS/OCCT/pull/1331) (third-party fix PR, merged) | bundled OCCT includes the fix |
| `0008-Geom_BSplineCurve-…-323` | `PeriodicNormalization` infinite loop / O(N) hang on far-out-of-range parameters ([#323](https://github.com/SecondMouseAU/OCCTSwift/issues/323) audit) | [OCCT#1288](https://github.com/Open-Cascade-SAS/OCCT/issues/1288) (repro) → [OCCT#1329](https://github.com/Open-Cascade-SAS/OCCT/pull/1329) (merged, stable) | bundled OCCT moves past that commit |
| `0009-StepData_StepWriter-…-323` | `AddString` infinite loop writing a single unbroken raw string longer than the 72-char line buffer ([#323](https://github.com/SecondMouseAU/OCCTSwift/issues/323) audit) | [OCCT#1318](https://github.com/Open-Cascade-SAS/OCCT/pull/1318) (open, by an OCCT maintainer — pinned to a commit) | bundled OCCT includes the fix |
| `0009-StepData_StepWriter-…-323` | `AddString` infinite loop writing a single unbroken raw string longer than the 72-char line buffer ([#323](https://github.com/SecondMouseAU/OCCTSwift/issues/323) audit) | [OCCT#1318](https://github.com/Open-Cascade-SAS/OCCT/pull/1318) (by an OCCT maintainer, merged) | bundled OCCT includes the fix |
| `0010-Intf_Interference-…-319` | `isSelfIntersecting(hardTimeout:)` couldn't interrupt an unbounded self-interference search — O(n)-per-call tangent-zone point access plus no checkpoint below `CheckFaceSelfIntersection` ([#319](https://github.com/SecondMouseAU/OCCTSwift/issues/319)) | [OCCT#1385](https://github.com/Open-Cascade-SAS/OCCT/issues/1385) (repro) → **[OCCT#1386](https://github.com/Open-Cascade-SAS/OCCT/pull/1386)** (our fix PR, CI green, ready for review) | bundled OCCT includes the fix |
| `0011-XCAFDoc_ShapeTool-AutoNamingScope-341` | `XCAFDoc_ShapeTool::theAutoNaming` process-global race across concurrent OBJ/glTF import and PLY/OBJ/glTF export ([#341](https://github.com/SecondMouseAU/OCCTSwift/issues/341)); revised per upstream review to a per-instance `OwnAutoNamingScope` instead of a mutex-guarded global flag ([#363](https://github.com/SecondMouseAU/OCCTSwift/issues/363)) | [OCCT#1387](https://github.com/Open-Cascade-SAS/OCCT/issues/1387) (repro) → **[OCCT#1388](https://github.com/Open-Cascade-SAS/OCCT/pull/1388)** (our fix PR, updated, CI green, ready for review) | bundled OCCT includes the fix |
| `0012-CDF_Directory-XCAFApp_Application-thread-safety-344` | `XCAFApp_Application::GetApplication()`/`TDocStd_Application::Resources()` lazy-singleton races + unsynchronized `CDF_Directory`/`Resource_Manager`/`CDF_Application` reader-writer maps — SIGSEGV surviving the #341 fix ([#344](https://github.com/SecondMouseAU/OCCTSwift/issues/344); a related but architecturally different driver-reentrancy crash found in the same validation is tracked separately as [#349](https://github.com/SecondMouseAU/OCCTSwift/issues/349)) | [OCCT#1389](https://github.com/Open-Cascade-SAS/OCCT/issues/1389) (repro) → **[OCCT#1390](https://github.com/Open-Cascade-SAS/OCCT/pull/1390)** (our fix PR, 2 commits, CI pending) | bundled OCCT includes the fix |
| `0013-ShapeUpgrade_UnifySameDomain-guard-null-pcurve-348` | `IntUnifyFaces`/`SplitWire` dereference a null pcurve when disambiguating candidate edges at a branching vertex, SIGSEGV on a mesh-sewn solid ([#348](https://github.com/SecondMouseAU/OCCTSwift/issues/348)) | [OCCT#1391](https://github.com/Open-Cascade-SAS/OCCT/issues/1391) (repro) → **[OCCT#1392](https://github.com/Open-Cascade-SAS/OCCT/pull/1392)** (our fix PR, merged) | bundled OCCT includes the fix |
| `0014-CDF-driver-reentrancy-mutex-349` | `CDF_Application` hands one cached storage/retrieval driver instance to every thread, but the drivers keep per-call scratch state, so concurrent `Save`/`Open` of one format corrupt each other ([#349](https://github.com/SecondMouseAU/OCCTSwift/issues/349)) | [OCCT#1393](https://github.com/Open-Cascade-SAS/OCCT/issues/1393) (repro) → **[OCCT#1394](https://github.com/Open-Cascade-SAS/OCCT/pull/1394)** (our fix PR, open) | bundled OCCT includes the fix |
| `0015-CDM_Application-metadata-lookup-table-mutex-353` | `CDM_Application::myMetaDataLookUpTable` and each `CDM_MetaData`'s own fields are shared process-wide with no guard, so a document destructor races another thread's save ([#353](https://github.com/SecondMouseAU/OCCTSwift/issues/353)) | [OCCT#1396](https://github.com/Open-Cascade-SAS/OCCT/issues/1396) (repro) → **[OCCT#1397](https://github.com/Open-Cascade-SAS/OCCT/pull/1397)** (our fix PR, open) | bundled OCCT includes the fix |
| `0016-Resource_Manager-atomic-Debug-Storage_Schema-per-instance-374` | `Resource_Manager::Debug` written unsynchronized on every construction, and `Storage_Schema::ICurrentData()`'s process-wide handle nulled by an unrelated document's `Open()` mid-save ([#374](https://github.com/SecondMouseAU/OCCTSwift/issues/374)); the `Storage_Schema` half redesigned per upstream review from a mutex to a per-instance field ([#518](https://github.com/SecondMouseAU/OCCTSwift/issues/518)) | [OCCT#1398](https://github.com/Open-Cascade-SAS/OCCT/issues/1398) (repro, filed before the PR-only rule) → **[OCCT#1399](https://github.com/Open-Cascade-SAS/OCCT/pull/1399)** (our fix PR, updated to the per-instance design, CI green) | bundled OCCT includes the fix |
| `0017-null-reshape-context-ComposeShell-WireDivide-484` | `ShapeFix_ComposeShell::Perform`/`SplitEdges` and `ShapeUpgrade_WireDivide::Perform` dereference an unset `ShapeBuild_ReShape` context, SIGSEGV on a plain 4-edge planar face ([#484](https://github.com/SecondMouseAU/OCCTSwift/issues/484)) | [OCCT#1409](https://github.com/Open-Cascade-SAS/OCCT/issues/1409) (repro; the maintainer reply on it is what set the PR-only rule) → **[OCCT#1410](https://github.com/Open-Cascade-SAS/OCCT/pull/1410)** (our fix PR, open) | bundled OCCT includes the fix |
| `0018-GCPnts-degenerate-count-and-duplicate-end-point-555` | `GCPnts_UniformAbscissa::NbPoints()` unbounded by the requested count (a `Resolution()` tolerance mismatch appends a duplicate end point), and a count below 2 stores out of bounds in `GCPnts_QuasiUniformAbscissa` ([#555](https://github.com/SecondMouseAU/OCCTSwift/issues/555)) | **[OCCT#1417](https://github.com/Open-Cascade-SAS/OCCT/pull/1417)** (our fix PR, open); first one filed under the PR-only rule, no companion issue | bundled OCCT includes the fix |

**#298 status:** we ship the fix now via patch `0003` (xcframework rebuilt in v1.12.3);
we keep carrying it — and building our own xcframework — **until an upstream OCCT
release contains OCCT#1374**. When that lands and we re-pin to that OCCT version, drop
release contains OCCT#1374** (merged, not yet in a release). When that lands and we re-pin, drop
`0003`. (The in-wrapper `occtFilletMutex` serialization that v1.12.1 shipped was already
removed in v1.12.3 once the kernel patch made fillet reentrant.)
Loading