Skip to content

fix(dwg): Prevent integer underflow in class count calculation - #33

Merged
marevol merged 1 commit into
masterfrom
fix/dwg-class-count-underflow
Feb 5, 2026
Merged

marevol merged 1 commit into
masterfrom
fix/dwg-class-count-underflow

Conversation

@marevol

@marevol marevol commented Feb 5, 2026

Copy link
Copy Markdown
Contributor

Summary

  • Fixes integer underflow bug in DWG class parsing that caused memory explosion (80GB+) and infinite loops
  • Adds underflow protection to both dwgreader18.cpp and dwgreader21.cpp
  • Adds comprehensive test coverage for the fix

Changes Made

  • src/intern/dwgreader18.cpp: Add bounds check before calculating endDataPos to prevent unsigned integer underflow when maxClassNum <= 499
  • src/intern/dwgreader21.cpp: Same fix applied for consistency across DWG format readers
  • tests/test_class_underflow.cpp: Unit tests verifying the underflow fix logic with various boundary values
  • tests/test_dwg_classes.cpp: Integration tests for DWG class parsing including memory safety checks
  • CMakeLists.txt: Register new test executables

Technical Details

The original calculation endDataPos = maxClassNum - 499 caused unsigned integer wraparound when maxClassNum <= 499. For example:

  • maxClassNum = 236 (common in AC1032 files from DWG TrueView)
  • Original: 236 - 499 = 4294967033 (unsigned wraparound)
  • Fixed: (236 > 499) ? (236 - 499) : 0 = 0

Since classes 0-499 are reserved built-in DWG classes and custom classes start at 500, files with maxClassNum <= 499 have no custom classes to parse, making endDataPos = 0 the correct value.

Testing

  • Unit tests verify correct calculation for boundary values (0, 499, 500, 1000)
  • Integration tests verify no memory explosion occurs with problematic class counts
  • All existing tests continue to pass

🤖 Generated with Claude Code

The original code calculated `endDataPos = maxClassNum - 499` which caused
an unsigned integer underflow when maxClassNum <= 499. For example, with
maxClassNum=236 (common in AC1032 files from DWG TrueView), this resulted
in endDataPos=4294967033 due to unsigned wraparound.

This caused massive memory allocation (80GB+) and effectively infinite
loops when parsing certain DWG files.

The fix adds a bounds check:
  endDataPos = (maxClassNum > 499) ? (maxClassNum - 499) : 0

Since classes 0-499 are built-in DWG classes and custom classes only start
at 500, files with maxClassNum <= 499 simply have no custom classes to parse.

Changes:
- dwgreader18.cpp: Add underflow protection
- dwgreader21.cpp: Add underflow protection
- Add unit tests for the underflow fix
- Add integration tests for DWG class parsing

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
@marevol
marevol merged commit 7b04824 into master Feb 5, 2026
4 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.

1 participant