diff --git a/CHANGES.md b/CHANGES.md index 201debf..0862ef1 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -4,6 +4,7 @@ ### Add +* SVG decode support for ImageMagick. `imagemagick-svg` (the librsvg-backed coder) is now installed, and the hardened policy grants the `SVG`/`SVGZ` coders read-only rights so Imagick can rasterize SVG uploads for preview transformations. The guards that made SVG worth blocking stay in force: HTTP/HTTPS delegates and `@*` path reads remain denied (no external hrefs, no local file leaks), `MSVG` — ImageMagick's internal, riskier SVG renderer — stays blocked so it cannot be reached even if librsvg goes missing, and SVG encode is still denied. The policy install step now decodes a probe SVG so the build fails loudly if SVG support regresses, and structure tests assert the delegate, the read-only policy pairing, and a real decode. * Weekly dependency automation (`.github/workflows/dependencies.yml`). A scheduled job resolves the newest upstream release for every pinned Dockerfile source, rewrites the pins, opens a pull request, waits for the exact CI runs for that head, approves and merges it, then tags, builds, and publishes the release. A `recover` step resumes a run that died between merge and publish, so a half-finished release is completed rather than duplicated. * PHP automation domain under `.github/scripts` — `Dependency` (catalog, resolvers, Dockerfile pin rewriting, reporting), `Automation` (release orchestration, version selection, merge and target validation, recovery), `Command`, and `Parity`. Entry points are `bin/dependencies.php`, `bin/orchestrator.php`, and `bin/parity.php`. * Composer tooling for the automation: `lint` (Pint), `check` (PHPStan), `test` (PHPUnit), `parity` (asserts every source class has covering tests), and `verify` to run all four. CI runs `composer verify` before touching any dependency. diff --git a/Dockerfile b/Dockerfile index 18b0702..3764da2 100644 --- a/Dockerfile +++ b/Dockerfile @@ -267,6 +267,7 @@ RUN apk update && \ icu-libs \ imagemagick \ imagemagick-heic \ + imagemagick-svg \ libavif \ libgomp \ libheif \ @@ -294,7 +295,10 @@ RUN set -eux; \ POLICY_DIR="$(identify -list configure | awk '/^CONFIGURE_PATH/ {print $2}' | cut -d: -f1)"; \ cp /tmp/policy.xml "${POLICY_DIR%/}/policy.xml"; \ rm /tmp/policy.xml; \ - identify -list policy | grep -q '50KP' + identify -list policy | grep -q '50KP'; \ + printf '' > /tmp/probe.svg; \ + identify /tmp/probe.svg; \ + rm /tmp/probe.svg WORKDIR /usr/src/code diff --git a/policy.xml b/policy.xml index ea431ba..10c930f 100644 --- a/policy.xml +++ b/policy.xml @@ -23,7 +23,7 @@ allocated, and disk caps the pixel-cache spill. memory/map/area merely change when the cache moves to disk. All values are tunable. - Preview inputs are limited to JPEG, PNG, HEIC, WEBP and GIF (output adds + Preview inputs are limited to JPEG, PNG, HEIC, WEBP, GIF and SVG (output adds AVIF), so the delegate coders disabled below are never used and only add risk. Validate changes with https://imagemagick-secevaluator.doyensec.com/. --> @@ -60,13 +60,16 @@ - + - - + + diff --git a/tests.yaml b/tests.yaml index 228e1f3..39d3436 100644 --- a/tests.yaml +++ b/tests.yaml @@ -102,6 +102,7 @@ commandTests: args: ["-i"] expectedOutput: - "ImageMagick supported formats .*WEBP.*" + - "ImageMagick supported formats .*SVG.*" - name: 'ImageMagick hardened policy loaded' command: "identify" args: ["-list", "policy"] @@ -110,6 +111,11 @@ commandTests: - "name: height" - "name: disk" - "50KP" + - "rights: Read\\s+pattern: \\{SVG,SVGZ\\}" + - name: 'ImageMagick SVG decode' + command: "php" + args: ["-r", "$i = new Imagick(); $i->readImageBlob(''); print($i->getImageWidth());"] + expectedOutput: ["8"] - name: 'PHP intl' command: "php" args: ["-r", 'print(\Normalizer::FORM_D);']