Describe the Bug
The iccFromXml round-trip stage of the full-test sweep silently covers 214 of the 215
profiles it reports on. Testing/ApplyDataFiles/test-profiles/sRGB_D65_MAT.icc — a tracked
fixture — is never round-tripped, because a different profile that happens to share its
basename overwrites its intermediate XML.
.github/workflows/_build-test-unix.yml:412-413 keys the intermediate on the basename
alone, flattening the whole Testing/ tree into one namespace:
base="$(basename "$icc" .icc)"
xmlout="$XMLDIR/${base}.xml"
Two different profiles collide there:
| path |
bytes |
provenance |
Testing/ApplyDataFiles/test-profiles/sRGB_D65_MAT.icc |
24712 |
tracked (blob ea0af959) |
Testing/Display/sRGB_D65_MAT.icc |
24708 |
generated by Testing/CreateAllProfiles.sh from Testing/Display/sRGB_D65_MAT.xml |
They are not copies of each other — different sizes, different content. The source list is
find "${WORKSPACE_DIR}/Testing" -name '*.icc' -type f | sort, so ApplyDataFiles/...
is visited first and Display/... second; the second write wins. The next step then
iterates "$XMLDIR"/*.xml, so only the Display/ variant is ever reconstructed and
classified.
The iccToXml step itself is unaffected — it runs on both files and checks each log before
the next iteration overwrites it. The loss is confined to the round-trip stage, and to the
per-file iccToXml log, which is also keyed on the bare basename (:372, :412).
Scope today is exactly one profile, but the flattening is structural: any future fixture
added under a second directory with an existing basename is dropped the same way, silently
and with the totals still looking right.
Build Instructions
cmake -S Build/Cmake -B build -DCMAKE_BUILD_TYPE=Debug -DENABLE_TOOLS=ON -DENABLE_ICCXML=ON
cmake --build build -j4
Reproduce Bug or Crash
Static check — no build needed. Enumerate tracked .icc plus the names
CreateAllProfiles.sh generates, and look for a duplicate basename:
{ git ls-tree -r --name-only origin/master -- Testing | grep '\.icc$'
git show origin/master:Testing/CreateAllProfiles.sh \
| grep -oE 'iccFromXml +[^ ]+ +([^ ]+\.icc)' | awk '{print $3}'
} | xargs -n1 basename | sort | uniq -d
Dynamic — reproduce the sweep's own arithmetic after sh CreateAllProfiles.sh:
cd Testing && sh CreateAllProfiles.sh >/dev/null 2>&1 && cd ..
find Testing -name '*.icc' -type f | wc -l # 215
find Testing -name '*.icc' -type f | xargs -n1 basename | sort -u | wc -l # 214
find Testing -name 'sRGB_D65_MAT.icc' -type f | sort | xargs md5sum
215
214
89a3692c... Testing/Display/sRGB_D65_MAT.icc <- wins
0da9f8d4... Testing/ApplyDataFiles/test-profiles/sRGB_D65_MAT.icc <- dropped
(The Display/ md5 varies per run — CreateAllProfiles.sh regenerates it and the header
carries a fresh dateTime/profileID. The size difference, 24708 vs 24712, is stable.)
Measured on 487e1994; f03b1e3e adds no .icc and does not touch profile generation, so
the count is unchanged on current master.
Triage
Coverage loss in CI tooling, not a library defect. No crash, no wrong output — the sweep
reports 214 logs ... 0 unclassified and passes. The failure mode is that it reports on a
corpus one profile smaller than the one it enumerated, without saying so.
Surfaced while measuring the corpus for #2265 (PR #2273).
Expected Behavior
Two defensible fixes; the choice is yours:
(a) Make the intermediate name unique. Derive it from the path relative to Testing/
with separators substituted, e.g. ApplyDataFiles_test-profiles_sRGB_D65_MAT. Restores full
coverage and is collision-proof for future fixtures. It renames every log and intermediate,
so any tooling that greps those names by hand would need a look.
(b) Detect and fail. Keep the flat naming and refuse to overwrite an existing
$xmlout, so a collision is a red lane rather than a silent drop. Smaller and louder, but
it leaves the profile untested until someone renames a fixture.
I'd lean (a), with the totals line reporting enumerated-vs-converted so a future mismatch is
visible either way. Happy to open the PR once you rule.
Environment
- Affects the
ubuntu-latest full-test leg only — _build-matrix.yml:67 gates
run-full-tests on that OS, and the steps are guarded by if: inputs.run-full-tests.
- Reproduced locally: Ubuntu (WSL2), clang-18 / GCC 15.2.0,
CMAKE_BUILD_TYPE=Debug.
Additional Context
The same basename keying appears in the iccDumpProfile sweep (:372) and the iccToXml
sweep (:412). Those two run the tool once per file, so only their per-file logs collide;
the round-trip stage at :441 is the one that loses a test, because it consumes the
directory the collision wrote into.
Describe the Bug
The
iccFromXmlround-trip stage of the full-test sweep silently covers 214 of the 215profiles it reports on.
Testing/ApplyDataFiles/test-profiles/sRGB_D65_MAT.icc— a trackedfixture — is never round-tripped, because a different profile that happens to share its
basename overwrites its intermediate XML.
.github/workflows/_build-test-unix.yml:412-413keys the intermediate on the basenamealone, flattening the whole
Testing/tree into one namespace:Two different profiles collide there:
Testing/ApplyDataFiles/test-profiles/sRGB_D65_MAT.iccea0af959)Testing/Display/sRGB_D65_MAT.iccTesting/CreateAllProfiles.shfromTesting/Display/sRGB_D65_MAT.xmlThey are not copies of each other — different sizes, different content. The source list is
find "${WORKSPACE_DIR}/Testing" -name '*.icc' -type f | sort, soApplyDataFiles/...is visited first and
Display/...second; the second write wins. The next step theniterates
"$XMLDIR"/*.xml, so only theDisplay/variant is ever reconstructed andclassified.
The
iccToXmlstep itself is unaffected — it runs on both files and checks each log beforethe next iteration overwrites it. The loss is confined to the round-trip stage, and to the
per-file
iccToXmllog, which is also keyed on the bare basename (:372,:412).Scope today is exactly one profile, but the flattening is structural: any future fixture
added under a second directory with an existing basename is dropped the same way, silently
and with the totals still looking right.
Build Instructions
Reproduce Bug or Crash
Static check — no build needed. Enumerate tracked
.iccplus the namesCreateAllProfiles.shgenerates, and look for a duplicate basename:{ git ls-tree -r --name-only origin/master -- Testing | grep '\.icc$' git show origin/master:Testing/CreateAllProfiles.sh \ | grep -oE 'iccFromXml +[^ ]+ +([^ ]+\.icc)' | awk '{print $3}' } | xargs -n1 basename | sort | uniq -dDynamic — reproduce the sweep's own arithmetic after
sh CreateAllProfiles.sh:(The
Display/md5 varies per run —CreateAllProfiles.shregenerates it and the headercarries a fresh
dateTime/profileID. The size difference, 24708 vs 24712, is stable.)Measured on
487e1994;f03b1e3eadds no.iccand does not touch profile generation, sothe count is unchanged on current master.
Triage
Coverage loss in CI tooling, not a library defect. No crash, no wrong output — the sweep
reports
214 logs ... 0 unclassifiedand passes. The failure mode is that it reports on acorpus one profile smaller than the one it enumerated, without saying so.
Surfaced while measuring the corpus for #2265 (PR #2273).
Expected Behavior
Two defensible fixes; the choice is yours:
(a) Make the intermediate name unique. Derive it from the path relative to
Testing/with separators substituted, e.g.
ApplyDataFiles_test-profiles_sRGB_D65_MAT. Restores fullcoverage and is collision-proof for future fixtures. It renames every log and intermediate,
so any tooling that greps those names by hand would need a look.
(b) Detect and fail. Keep the flat naming and refuse to overwrite an existing
$xmlout, so a collision is a red lane rather than a silent drop. Smaller and louder, butit leaves the profile untested until someone renames a fixture.
I'd lean (a), with the totals line reporting enumerated-vs-converted so a future mismatch is
visible either way. Happy to open the PR once you rule.
Environment
ubuntu-latestfull-test leg only —_build-matrix.yml:67gatesrun-full-testson that OS, and the steps are guarded byif: inputs.run-full-tests.CMAKE_BUILD_TYPE=Debug.Additional Context
The same basename keying appears in the
iccDumpProfilesweep (:372) and theiccToXmlsweep (
:412). Those two run the tool once per file, so only their per-file logs collide;the round-trip stage at
:441is the one that loses a test, because it consumes thedirectory the collision wrote into.