fix: declare toolbar icons and ship real PNGs in both archives (closes #371) #376
Reference in New Issue
Block a user
Delete Branch "fix/371-manifest-icons"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Closes #371.
Neither manifest declared an
iconsblock, so both browsers drew the genericpuzzle piece. Both now declare 16/32/48/128 as
icons/icon<size>.png, and thefour PNGs live at
icons/in the tree.What changed
manifest/chrome.json,manifest/firefox.json:iconsat 16/32/48/128.icons/icon{16,32,48,128}.png: new artwork (below).build.js: copies each browser's icons into its own dist directory,reading the sizes out of the manifest that ships next to them rather than
from a second list here. A size a manifest declares and
icons/does not holdfails the build with the missing path; a value that is not a plain file under
icons/is refused before it is joined into any path. The icons are recordedas emitted like everything else, so they are in the build receipt and
script/verify-buildcovers them.tests/manifest.test.js: asserts the declaration in both manifests, that bothdeclare the same set, and that each referenced file is a PNG whose IHDR states
the size the entry claims — a declaration on its own would still permit a
reference to a file that is absent or not an image.
tests/packaging.test.js: pins the case of a manifest naming an icon thearchive does not contain.
script/lib/package.jsneeded no change — itsMANIFEST_PATH_REalready matches.png— but that coverage was incidental,and this is the file it protects.
Icons are inside the built artifacts, verified by unpacking them
make package, thenunzipon the artifacts themselves (not the repo's own zipreader):
Unpacked and inspected, both targets:
Byte-identical to the tree (sha256 of the unpacked chrome icons vs
icons/):A missing icon fails the build — demonstrated, then restored
Removing the file the manifest names:
And the packager's own reference-resolver, reached by making
build.jstemporarily skip one copy so
dist/was complete except for that icon:Both were reverted immediately;
icons/icon48.pngis back at8d2b688321249b4100e9d472a52477593074213a222d6dab00d6229b6cc740dc, and thetemporary
build.jsline is not in the diff (grep TEMPORARY build.jsfindsnothing).
The artwork
Original, and produced here rather than obtained: a throwaway Python program
(standard library only —
zlib+struct, no PIL, no network) rasterisedgeometry defined in that program into RGBA PNGs at the four sizes. The mark is a
flat dark-navy rounded square (
#101A2E) carrying a teal (#35E0C2) triangular"A": one outer triangle minus a triangular counter, drawn from six coordinates,
antialiased by 8x8 supersampling. Nothing was traced, copied, downloaded or
derived from any existing mark, project or trademark, and no font is involved.
One shape in two flat colours is also what a 16px toolbar slot can actually
carry.
The generator itself is deliberately not committed: it is a Python file in a
Node repo and outside this unit's scope. Say the word and it can be filed as a
follow-up so the artwork is regenerable in-tree.
Verification
All run through
make/script/only; lint ran in the pinned container.make check: green — 56 suites, 1023 tests;test-verify-build46 cases;check-censored186 tracked files; eslint + prettier in the lint image.make build: green — 23 emitted files verified against the receipt,4 bundles
autistmask-build-debug=off,check-censored23 files underdist/.make package: green — 11 members per archive.make test-e2e(Chrome): green — 55/55 and 5/5.make test-e2e-firefox: green — 8/8 and 7/7; the second suite installs thepackaged XPI, so the artifact carrying these icons was installed in real
Firefox.
Rebased onto
nextat75a5fa9and re-ranmake checkandmake buildafterthe rebase.
docker ps -ais empty of anything from this run; every e2econtainer ran
--rmand no image or cache was pruned.PASS — DoD of #371 verified in an independent clone at
d0e6758: both archives unpacked withunzipcarry 11 members each including all four icons, byte-identical to the tree (12/12 sha256 match), each archive's ownmanifest.jsondeclares 16/32/48/128;make check(56 suites / 1023 tests, lint executed in the pinned container at 6.5s, notCACHED),make build,make package,make test-e2e(55/55, 5/5) andmake test-e2e-firefox(8/8, 7/7, installing the XPI I built) all green; CI green on the head commit; no conflict with currentnext; one commit, no attribution trailers.Non-blocking observations, reported rather than filed as defects:
icons/icon48.pngwith a non-PNG of the same name leavesmake buildandmake packageat exit 0 and the junk bytes ship inside the archive.make checkdoes catch it — the new IHDR assertion intests/manifest.test.jsfails exactly as intended, so that test is not vacuous — but the build/package path validates only existence, not PNG-ness. Acceptable layering given CI runscheckon every push; noting it becausemake packagealone is not sufficient to trust an artifact's icons.ICON_REF_REcould not be bypassed.icons/../../../../../../etc/passwd.pngand/etc/passwd.pngwere both refused at exit 2 with...which is not a plain file under icons/, before any path join. The class excludes/and\, so no segment can be exactly.., the value must start with the literalicons/so it can never go absolute, and JS$withoutmadmits no trailing-newline trick. Missing-file and traversal failures both discarddist/.build.jsnow names the two manifest source paths twice — inMANIFEST_SOURCESand inline in the "copy manifests" block. Harmless today; if that location ever moves,copyIconscould read a different manifest than the one that ships, and the icons copied would not match the manifest shipped beside them.On the disclosed gap: shipping the four binaries without the committed generator is acceptable at this stage and should not block, but the follow-up to make the artwork regenerable in-tree is worth filing now rather than after the mark first needs changing.