fix(#1977): retire the iccPawgReport --read option - #1978
Merged
Conversation
--read was documented as a fallback that would still assess a profile the strict validation path rejected. It could never do that. ValidateIccProfile() returns NULL on a parsed profile only when ReadValidate() reaches icValidateCriticalError, and the two conditions that get it there -- ReadBasic() failing (IccProfile.cpp:941) and any LoadTag() failing (:992) -- are exactly the conditions CIccProfile::Read() bails on (:874, :905), so ReadIccProfile() returned NULL for the same inputs. CheckTagLayout(), the only other contributor, tops out at icValidateWarning. The branch therefore only ever assigned NULL over NULL. xsscx confirmed on #1972 that the option was leftover prototyping scaffolding rather than an intended feature; it has been present since the tool's first commit 068a3d3 "Add: iccPawgReport (#1026)". The graceful degradation it was reaching for already exists and does not depend on it: LoadRawProfile() runs unconditionally before any IccProfLib parsing, so a file the library refuses still gets the full raw-byte assessment with the parsed-profile items reported as NOT RUN. That is noted where the fallback used to sit, since it is the reason a strict-only load is acceptable here. The option is retired rather than accepted-and-ignored: it now falls through to the existing unrecognised-switch branch, so a caller still passing it is told plainly instead of believing a fallback ran. Scripts move with the source, or CI goes red -- icc-pawg-qa-scan.sh drove two of its four variants through --read and runs from ci-iccdev-tool-tests.yml. Those two are dropped rather than replaced: both executed the same code path as their non---read counterparts. The pawg-read-option-fidelity regression case, which only ever asserted that a good profile reports identically with the flag, is replaced by pawg-read-option-retired, which pins the rejection. Not touched: iccDumpProfile's separate --read, which is a live option with different semantics (eager instead of lazy load, not a post-failure fallback). Verified: report output byte-identical across all 80 tracked Testing/*.icc profiles in both text and JSON modes, with the version string normalised (12639 lines, 0 diff); 7 pawg CTests pass; the new case red-tests correctly, failing with "--read was accepted" when the option is silently re-accepted; shellcheck clean on both scripts.
colourbill-ctrl
requested review from
ChrisCoxArt,
dwtza and
xsscx
as code owners
August 5, 2026 03:47
The pre-flight gate runs `shellcheck` bare -- no -x, no severity filter -- over files changed by the PR (preflight-safety-checks.sh:1051). The `# shellcheck source=` directive records where the sourced helper lives but does not stop SC1091 being reported when shellcheck is not following external sources, so the gate failed on a line this change did not introduce. The finding is pre-existing and identical on master (line 20 there, line 21 here), and is reached only because the gate lints changed files and this is the first change to touch this script since the gate existed. The two sibling scripts, icc-dumpprofile-qa-scan.sh and icc-roundtrip-qa-scan.sh, carry the same latent finding and will fail the same way when something first touches them; they are left alone rather than swept into this change. Both directives are kept: source= still documents the path for anyone running shellcheck -x, and disable=SC1091 silences the info-level report for the way the gate actually invokes it. Verified with the gate's own invocation form -- both changed scripts in a single bare shellcheck call, rc=0 -- and the scan still resolves its two remaining variants.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Part of #1977.
Retires
iccPawgReport --read. @xsscx confirmed on #1972 that it was leftover prototyping scaffolding rather than an intended feature, and #1977 records the mechanism and scope.Why it can never have worked
DumpPawgReport()only consulted the flag after the strict path had already returned NULL:ValidateIccProfile()returns NULL on a parsed profile only whenReadValidate()reachesicValidateCriticalError, and the two conditions that get it there are exactly the conditionsCIccProfile::Read()— behindReadIccProfile()— bails on:ReadValidate()CIccProfile::Read()ReadBasic()failsIccProfile.cpp:941return false,:874LoadTag()fails:992return false,:905CheckTagLayout()icValidateWarningSupporting facts, both checked rather than assumed:
icValidateStatusis orderedOK(0) < Warning(1) < NonCompliant(2) < CriticalError(3)(IccDefs.h:106-111), so>= icValidateCriticalErrormatches only the maximum and theNonCompliant/Warningheader checks cannot trigger the NULL return; andLoadTag()opens with an absoluteSeek(offset, icSeekSet), so the repositioningReadValidate()does beforehand cannot change its outcome relative toRead()'s loop.The root of the mistake is that
ReadIccProfile()is the eager loader, not a permissive one. On tag structure it is stricter than a lazyOpenIccProfile(), so it fails on precisely the conditions that just madeReadValidate()report critical.Nothing is lost
The graceful degradation
--readwas reaching for already exists and never depended on it.LoadRawProfile()runs unconditionally at the top ofDumpPawgReport(), before and independently of any IccProfLib parsing, so a file the library refuses still receives the full raw-byte security assessment with the parsed-profile items reported asNOT RUN. That reasoning is now recorded where the fallback used to sit, because it is what makes a strict-only load acceptable here.Retired, not accepted-and-ignored
--readnow falls through to the existing unrecognised-switch branch:A caller still passing it is told plainly, rather than believing a fallback ran.
Scripts move with the source
icc-pawg-qa-scan.shdrove two of its four QA variants through--readand runs in CI fromci-iccdev-tool-tests.yml. Leaving it would turn those two intoexit 1. They are dropped rather than replaced — both executed the same code path as their non---readcounterparts.pawg-read-option-fidelity, which only ever asserted that a good profile reports identically with the flag set, is replaced bypawg-read-option-retired, which pins the rejection.Not touched
iccDumpProfilehas a separate--readwith different semantics — eagerReadIccProfile()instead of lazyOpenIccProfile(), not a post-failure fallback (iccDumpProfile.cpp:210). It is live and working, and along withicc-dumpprofile-qa-scan.shanddocs/ctest.md:273is deliberately left alone.Verification
Acceptance test from #1977 — report output unchanged. All 80 tracked
Testing/*.iccprofiles, text and JSON modes, version string normalised: 12639 lines, 0 diff against pre-removal master.The new regression case is red-tested. Silently re-accepting
--readmakes it fail with--read was accepted (expected non-zero exit; the option is retired), so it catches the accepted-and-ignored mode specifically rather than just the presence of the flag.Build and suite.
IccPawgReport.cppandPawgReport.cppcompile clean under-Wall -Wextra -Wpedantic -Werroron gcc and clangshellcheck -S errorclean on both changed scriptsspectral-tiff-preview(missing pythonimagecodecs) andqa-profile-manifest(0 mismatched, one unlisted stray untracked file in my working tree)Rebased onto
c0cd71dbso CI validates the landing tree.