Commit Graph

21 Commits

Author SHA1 Message Date
Dion Moult 7aa967b01a ifcparse: recover two fixes lost in the datamodel-rewrite merge
Both fixes were made on v0.8.0's IfcParse.cpp AFTER the datamodel branch
had already renamed it to parse.cpp. When main was later merged into the
branch, the modify/delete was resolved toward the deletion (merge
8c9c3cde2), so the changes never reached the live parse.cpp. They are
invisible to `git log v0.8.0...HEAD` because the originating commits sit
in the merged-in shared ancestry; only a content sweep of the renamed
files surfaces them.

- format_double now uses the shortest decimal representation that
  round-trips exactly (Mac-safe manual implementation, no std::to_chars),
  instead of setprecision(digits10) which padded clean REALs with noise
  digits (0.0174532925199433 -> 0.017453292519943299) and rewrote every
  REAL on re-save. Recovers ee2b357d7 + fa597536e + 821cf7b67, #7696.
- The [SYN004] non-entity-type parse-error branch now resets current_id
  to 0 before advancing, matching its sibling error branches, so a
  malformed non-entity instance no longer erroneously terminates parsing.
  Recovers 7c9df9f98.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-26 16:32:47 +10:00
Bruno Postle 57d9c47c6c Fix null-pointer derefs in reference resolution
Two related bugs in read_from_stream's reference-resolution
loop, both reachable from malformed input:

- has_attribute_value<IfcBaseClass*> only checks the stored
  slot's type, not that it's non-null (e.g. an explicit $
  value), so the following get_attribute_value() call could
  return null and inst->declaration() crashed on it.
- byid_[ref] default-inserts (and returns) a null pointer
  when the owning instance id isn't present, which was then
  dereferenced unconditionally via ->data().

Added regression tests using the two minimized crash inputs
that found these.

Generated with the assistance of an AI coding tool.

(cherry picked from commit 56121ca061)
2026-07-25 23:16:38 +10:00
Andrej730 2b7f55c1a0 stub: fixes after data model changes 2026-07-24 21:50:49 +05:00
Petru Conduraru f23db9440f ifcparse: widen all integer attribute types to int64_t for consistency
Follow-up to the scalar-only fix in #8754, per aothms's direct request on
that PR ("Please do make all int types consistent") and his own original
2023 design intent on issue #3058 ("make all integers (incl. schema
namespaces) an int64_t"). Widens the remaining inconsistent spots now that
compatibility isn't a constraint on this v0.9 branch:

- Integer aggregates (IfcTriangulatedFaceSet.CoordIndex and similar
  List<int> attributes), including the SWIG to_vec_int/to_vec_vec_int
  helpers, which previously silently truncated via static_cast<int> on the
  Python-set path - the same bug class as the original scalar issue.
- The schema code generator (express/mapping.py's integer type mapping),
  and all 12 generated schema header/source pairs regenerated to match, so
  every schema-typed getter/setter (e.g. IfcOwnerHistory::CreationDate) is
  int64_t end to end, not just the dynamic attribute-value path.

Instance/reference identifiers (STEP #123 ids) are deliberately left at
32-bit: they're a file-local index into internal maps, not an EXPRESS
domain value an application chooses, and no realistic STEP file has
billions of entities. The lexer's Token_IDENTIFIER parsing still funnels
through a 32-bit int for this reason - flagged as a known, low-risk gap
rather than fixed, since fixing it would mean touching indexing/hashing
code for no realistic benefit.

Verified: original PR's round-trip tests extended with aggregate cases
(IfcTriangulatedFaceSet.CoordIndex, InnerCoordIndices) at 64-bit boundary
values, in memory and through STEP text, IFC2X3 and IFC4. A standalone C++
program exercising the generated schema API directly (Ifc4::IfcOwnerHistory
::setCreationDate/CreationDate, IfcTriangulatedFaceSet::setCoordIndex/
CoordIndex) confirms int64_t end to end, bypassing SWIG. Full build
(BUILD_IFCGEOM, WITH_OPENCASCADE, BUILD_IFCPYTHON, IFC2X3+IFC4) clean.
test/util/test_attribute.py and test_file.py pass unchanged.

This contribution was produced with the assistance of an AI coding tool.
2026-07-19 13:54:16 +02:00
Petru Conduraru d5076bded3 ifcparse: store integer attribute values as int64_t to allow out-of-range timestamps
Setting an IfcInteger/IfcTimeStamp typed attribute (e.g. IfcOwnerHistory.CreationDate)
outside the signed 32-bit range corrupted the value instead of raising, since the
Python wrapper's set_attribute_value_py() truncated it with a plain static_cast<int>
before handing it to the C++ storage. Unix timestamps before 1901-12-13 or after
2038-01-19 silently wrapped around (e.g. 3000000000 became -1294967296) rather than
being rejected or stored correctly. Fixes #3058, equivalent to PR #8683 but ported to
this branch's rewritten ifcparse (snake_case files, variant_array/instance_data
storage, SWIG PyObject-based attribute setter) instead of the old IfcEntityInstanceData
sources, which no longer exist here.

The scalar slot of the attribute variant (Argument_INT) becomes int64_t. Integer
aggregates (Argument_AGGREGATE_OF_INT, e.g. CoordIndex) and instance/reference
identifiers stay 32-bit, since neither is the value that overflows here; this narrow
scope is kept on its own technical merits (aggregates and identifiers were never the
source of the bug, and widening them would be a much larger, riskier change for no
benefit) even though aothms said compatibility isn't a concern on this v0.9-track
branch. express::Base::set_attribute_value promotes the schema-generated int to
int64_t at a single choke point, so the generated setters keep compiling unchanged.
The STEP lexer, writer, and SWIG wrapper (set_attribute_value_py, pythonize) are all
widened together, since widening only the Python-facing setter would have silently
wrapped the value on file write instead of raising.

Verified in a build (IFC2X3 and IFC4, BUILD_IFCGEOM off, no kernels): pre-1901,
post-2038, both 32-bit boundaries, and a 9e12 value all round trip exactly both in
memory and through STEP text serialization (write then reopen). A value outside the
64-bit range now raises a clean exception instead of corrupting data. Ordinary
in-range integers and integer aggregates (e.g. IfcTriangulatedFaceSet.CoordIndex) are
unaffected. The existing util/test_attribute.py and test_file.py suites pass
unchanged; test_entity_instance.py has 5 pre-existing failures unrelated to this
change (confirmed identical on an unfixed build of this branch, caused by a missing
get_info_2 binding and _patch_swig_comparisons never being implemented here).

Generated with the assistance of an AI coding tool.
2026-07-19 13:54:16 +02:00
Thomas Krijnen 552576fcc3 Merge branch 'ifcviewer-wgpu' of https://github.com/IfcOpenShell/IfcOpenShell into ifcviewer-wgpu 2026-07-09 22:02:39 +02:00
Thomas Krijnen 561a23cfbc After-merge clean-ups 2026-07-09 22:01:21 +02:00
Dion Moult 1684513109 ifcparse: parse doubles via C-locale strtod_l on macOS (fix Apple build)
parse_num_ used std::from_chars for both integers and doubles, but the
floating-point from_chars overload is =deleted in Apple clang's libc++, so
the macOS build failed to compile (parse.cpp:136, instantiated for double).

Split parse_num_ with `if constexpr`: integers keep std::from_chars
everywhere; on macOS, doubles parse via strtod_l with a cached "C" locale
(locale-independent, restoring the pre-charconv Apple path). libstdc++ and
the MSVC STL have working float from_chars and are left unchanged.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-09 22:00:41 +10:00
Thomas Krijnen 7fc2d9a998 Merge remote-tracking branch 'origin/v0.8.0' into ifcviewer-wgpu 2026-07-09 13:21:39 +02:00
Thomas Krijnen 4c13e2424c Configurable pointer type; std::from_chars(); aggregate inverses in vector; skip parse_context 2026-06-11 15:51:40 +02:00
Thomas Krijnen a1efdccb4b Add back mutex 2026-05-08 10:07:34 +02:00
Thomas Krijnen 4670715ef3 Work a bit on failing tests 2026-05-06 11:41:43 +02:00
Thomas Krijnen ddfe3bce20 Fixes for WASM build (some temporary) 2026-04-24 13:36:06 +02:00
Thomas Krijnen c42a7f32d0 The proper id / identity fix for rocksdb 2026-04-22 18:11:01 +02:00
Thomas Krijnen 14e9846e35 identity_ for types; id_ for instances 2026-04-22 12:04:24 +02:00
Thomas Krijnen 37c6aea092 forgot to set goosd 2026-04-22 12:04:09 +02:00
Thomas Krijnen 9b13dc8dd6 Get rid of parse context pool 2026-04-22 12:03:58 +02:00
Thomas Krijnen 325db2e57f Export templates 2026-04-21 11:55:04 +02:00
Thomas Krijnen b2fc0c00cc Hierarchical index for inverses 2026-04-10 14:54:47 +02:00
Thomas Krijnen becd38c77d Compilation fixes 2026-04-09 16:18:53 +02:00
Thomas Krijnen a07f56db6f Restructure and rename 2026-03-31 15:32:36 +02:00