QA Summary for XML Parsing
2026-09-04 02:44:19 UTC
Edited by @xsscx
Codex Report
Finding 1: ProfileVersion sub-class components lose leading digits
At IccProfileXml.cpp:473-486, the third and fourth component loops assign ver = *szVer instead of appending with ver += *szVer. Therefore only the last digit of each component reaches the otherwise strict parseVersion helper.
The fixture requests 5.10.12.34. iccFromXml exits zero and says it saved the profile correctly. iccDumpProfile and iccToXml both report 5.10.2.04.
Specs
- ICC.2:2023 section 7.2.6, PDF page 19, requires bytes 8 through 11 to encode the profile and sub-class versions as binary-coded decimal. Byte 10 is sub-class major and byte 11 is sub-class minor
- ICC.2:2023 section 7.2.17, PDF page 24, defines only Perceptual (0), media-relative colorimetric (1), Saturation (2), and ICC-absolute colorimetric (3) for the rendering intent field
PoC
<?xml version="1.0" encoding="UTF-8"?>
<IccProfile>
<Header>
<ProfileVersion>5.10.12.34</ProfileVersion>
<ProfileDeviceClass>cenc</ProfileDeviceClass>
<ProfileDeviceSubClass>test</ProfileDeviceSubClass>
<DataColourSpace>RGB </DataColourSpace>
</Header>
<Tags>
<utf8TextType>
<TagSignature>rfnm</TagSignature>
<TextData>QA four-component profile version</TextData>
</utf8TextType>
</Tags>
</IccProfile>
CLI Repro
iccFromXml foo.xml foo.icc
Incorrect Output
iccDumpProfile foo.bar | grep -E 'Version:|SubClass Version:'
Version: 5.10
SubClass Version: 2.04
Expected Output
Expected: Profile Version 5.10 and SubClass Version 12.34.
Finding 2: explicit ProfileSubClassVersion is parsed as last-digit.00
PoC
<?xml version="1.0" encoding="UTF-8"?>
<IccProfile>
<Header>
<ProfileVersion>5.10</ProfileVersion>
<ProfileDeviceClass>cenc</ProfileDeviceClass>
<ProfileDeviceSubClass>test</ProfileDeviceSubClass>
<ProfileSubClassVersion>12.34</ProfileSubClassVersion>
<DataColourSpace>RGB </DataColourSpace>
</Header>
<Tags>
<utf8TextType>
<TagSignature>rfnm</TagSignature>
<TextData>QA explicit profile subclass version</TextData>
</utf8TextType>
</Tags>
</IccProfile>
At IccProfileXml.cpp:513-526, the major loop also assigns rather than appends. After that loop stops at the separator, the code does not advance szVer. The minor loop consequently executes zero times and atoi("") supplies zero. This path also bypasses parseVersion and its digit/range checks.
The fixture requests 12.34. The tool exits zero and the ICC and round-trip XML contain 2.00.
Finding 3: unknown RenderingIntent silently becomes Perceptual
PoC
<?xml version="1.0" encoding="UTF-8"?>
<IccProfile>
<Header>
<ProfileVersion>5.10</ProfileVersion>
<ProfileDeviceClass>cenc</ProfileDeviceClass>
<DataColourSpace>RGB </DataColourSpace>
<RenderingIntent>Typographical Error</RenderingIntent>
</Header>
<Tags>
<utf8TextType>
<TagSignature>rfnm</TagSignature>
<TextData>QA unknown rendering intent</TextData>
</utf8TextType>
</Tags>
</IccProfile>
At IccProfileXml.cpp:593-606, four recognized strings assign a value, but an unknown non-empty string has no rejecting else branch. ParseBasic zeroes the header at line 436, so the unassigned enum remains zero, which is Perceptual.
The fixture supplies Typographical Error. The tool exits zero, reports a correct save, and the ICC and round-trip XML report Perceptual.
Finding 4: malformed ProfileVersion is saved and exits zero
PoC
?xml version="1.0" encoding="UTF-8"?>
<IccProfile>
<Header>
<ProfileVersion>5.x</ProfileVersion>
<ProfileDeviceClass>cenc</ProfileDeviceClass>
<DataColourSpace>RGB </DataColourSpace>
</Header>
<Tags>
<utf8TextType>
<TagSignature>rfnm</TagSignature>
<TextData>QA malformed profile version</TextData>
</utf8TextType>
</Tags>
</IccProfile>
The issue #1845 repair made parseVersion strict. On failure, IccProfileXml.cpp:492-499 appends a reason and leaves version zero, but ParseBasic returns true at line 704. IccFromXml.cpp prints the parse reason only when LoadXml returns false (lines 77-84). It then deliberately saves profiles whose profile validation is worse than warning (lines 101-117) and returns EXIT_SUCCESS.
With 5.x, the tool says only that an invalid profile was saved, emits the downstream ColorEncoding/version error, writes version 0.00, and exits zero. The useful Cannot parse ProfileVersion '5.x' reason is suppressed.
Finding 5: bare -v fails open when its schema is absent
IccFromXml.cpp:45-73 searches for SampleIccRELAX.rng. If fopen fails, it leaves the schema string empty without a diagnostic. LoadXml validates only when that string is non-empty (IccProfileXml.cpp:1062). The reviewed build directory does not contain SampleIccRELAX.rng, so bare -v is behaviorally identical to no -v. Supplying an explicit reject-all schema correctly rejects the same document with exit 1 and no ICC output.
QA Summary for XML Parsing
2026-09-04 02:44:19 UTC
Edited by @xsscx
Codex Report
Finding 1: ProfileVersion sub-class components lose leading digits
At IccProfileXml.cpp:473-486, the third and fourth component loops assign
ver = *szVerinstead of appending withver += *szVer. Therefore only the last digit of each component reaches the otherwise strict parseVersion helper.The fixture requests 5.10.12.34. iccFromXml exits zero and says it saved the profile correctly. iccDumpProfile and iccToXml both report 5.10.2.04.
Specs
PoC
CLI Repro
Incorrect Output
Expected Output
Finding 2: explicit ProfileSubClassVersion is parsed as last-digit.00
PoC
At IccProfileXml.cpp:513-526, the major loop also assigns rather than appends. After that loop stops at the separator, the code does not advance szVer. The minor loop consequently executes zero times and atoi("") supplies zero. This path also bypasses parseVersion and its digit/range checks.
The fixture requests 12.34. The tool exits zero and the ICC and round-trip XML contain 2.00.
Finding 3: unknown RenderingIntent silently becomes Perceptual
PoC
At IccProfileXml.cpp:593-606, four recognized strings assign a value, but an unknown non-empty string has no rejecting else branch. ParseBasic zeroes the header at line 436, so the unassigned enum remains zero, which is Perceptual.
The fixture supplies
Typographical Error. The tool exits zero, reports a correct save, and the ICC and round-trip XML report Perceptual.Finding 4: malformed ProfileVersion is saved and exits zero
PoC
The issue #1845 repair made parseVersion strict. On failure, IccProfileXml.cpp:492-499 appends a reason and leaves version zero, but ParseBasic returns true at line 704. IccFromXml.cpp prints the parse reason only when LoadXml returns false (lines 77-84). It then deliberately saves profiles whose profile validation is worse than warning (lines 101-117) and returns EXIT_SUCCESS.
With 5.x, the tool says only that an invalid profile was saved, emits the downstream ColorEncoding/version error, writes version 0.00, and exits zero. The useful
Cannot parse ProfileVersion '5.x'reason is suppressed.Finding 5: bare -v fails open when its schema is absent
IccFromXml.cpp:45-73 searches for SampleIccRELAX.rng. If fopen fails, it leaves the schema string empty without a diagnostic. LoadXml validates only when that string is non-empty (IccProfileXml.cpp:1062). The reviewed build directory does not contain SampleIccRELAX.rng, so bare -v is behaviorally identical to no -v. Supplying an explicit reject-all schema correctly rejects the same document with exit 1 and no ICC output.