Skip to content

Fix: signed->unsigned SeamlessIndicator conversion in image ParseXml (#1342, #1343)#1344

Merged
xsscx merged 1 commit into
InternationalColorConsortium:masterfrom
colourbill-ctrl:fix-1342-1343-imageparse-signed-unsigned
Jun 14, 2026
Merged

Fix: signed->unsigned SeamlessIndicator conversion in image ParseXml (#1342, #1343)#1344
xsscx merged 1 commit into
InternationalColorConsortium:masterfrom
colourbill-ctrl:fix-1342-1343-imageparse-signed-unsigned

Conversation

@colourbill-ctrl

Copy link
Copy Markdown
Contributor

Summary

Fixes #1342 and #1343 (same root cause, same fix pattern), both UBSan implicit-integer-sign-change findings from the xsscx fuzz/QA wave (bisected to bab6678).

CIccTagXmlEmbeddedHeightImage::ParseXml() (IccTagXml.cpp:5548, #1342) and CIccTagXmlEmbeddedNormalImage::ParseXml() (IccTagXml.cpp:5651, #1343) read the SeamlessIndicator XML attribute with atoi() (signed int) and assigned it directly to the unsigned 32-bit member m_nSeamlesIndicator. A negative attribute value wrapped to a huge unsigned value via the implicit int -> icUInt32Number conversion:

IccTagXml.cpp:5548:25: runtime error: implicit conversion from type 'int' of value
-98 (32-bit, signed) to type 'icUInt32Number' (aka 'unsigned int') changed the value
to 4294967198 (32-bit, unsigned)

Fix

Both sites parse into a signed temporary and floor any negative (invalid) value to 0 before the unsigned assignment, so the stored indicator is always a well-defined non-negative number. Positive values pass through unchanged — atoi already capped at int range, so the XML path could never represent a value above INT_MAX; only the previously-UB negative case now resolves to 0. The binary Read() path (Read32) is unaffected.

Verification

Built iccFromXml with -fsanitize=implicit-conversion -fno-sanitize-recover=all (clang-18):

PoC Pre-fix Post-fix
...EmbeddedHeightImage-...Line5548.xml (SeamlessIndicator="-98") UBSan runtime error clean, normal compliance reporting
...EmbeddedNormalImage-...Line5651.xml (SeamlessIndicator="-5655") UBSan runtime error clean

A valid positive SeamlessIndicator (e.g. 7) still parses and stores unchanged.

Notes

  • Library-only change (IccXML/), no fork-gate split needed.
  • The deterministic CTest regression for both issues is filed separately as an upstream PR (it touches .github/ + Build/Cmake, which the fork-PR automation gate blocks). Merge this fix first; the test PR goes green once this lands.

🤖 Generated with Claude Code

…ml (InternationalColorConsortium#1342, InternationalColorConsortium#1343)

CIccTagXmlEmbeddedHeightImage::ParseXml() and
CIccTagXmlEmbeddedNormalImage::ParseXml() read the "SeamlessIndicator"
attribute with atoi() (a signed int) and assigned it directly to the
unsigned 32-bit member m_nSeamlesIndicator. A negative attribute value
wrapped to a huge unsigned value through the implicit int ->
icUInt32Number conversion, which UBSan's implicit-integer-sign-change
check flags as a runtime error (IccTagXml.cpp:5548 InternationalColorConsortium#1342 / :5651 InternationalColorConsortium#1343).

Both sites now parse into a signed temporary and floor any negative
(invalid) value to 0 before the unsigned assignment, so the stored
indicator is always a well-defined non-negative number. Positive values
pass through unchanged (atoi already capped at int range, so the XML
path could never represent a value above INT_MAX); only the invalid
negative case -- which previously triggered the UB -- now resolves to 0.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

@xsscx xsscx left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

2026-06-14 19:01:54 UTC

@xsscx xsscx added this to the v2.3.2.2 milestone Jun 14, 2026
@xsscx xsscx linked an issue Jun 14, 2026 that may be closed by this pull request
@xsscx xsscx added the Merge Ready Approved, mergeable, and all CI checks passed label Jun 14, 2026
@xsscx xsscx merged commit 952b6be into InternationalColorConsortium:master Jun 14, 2026
31 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Merge Ready Approved, mergeable, and all CI checks passed Source C or C++ source code changes

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Bisect bab6678 CIccTagXmlEmbeddedHeightImage::ParseXml()

2 participants