# Reproduction environment for GHSA-f3w6-w445-fwh9.
#
# Stage 1 builds ImageMagick 7 from upstream source WITHOUT librsvg, so the SVG coder
# uses ImageMagick's own internal renderer (the MSVG path) exactly like the reported
# chain.  The Debian/Ubuntu packages of the same era carry extra hardening that refuses
# explicit coder prefixes in SVG references, so a source build of the same upstream
# release is used to model "ImageMagick 6 or 7 under a Debian/Ubuntu-style policy that
# does not deny MSL".
FROM ruby:3.4-bookworm AS imbuild
ARG IM_VERSION=7.1.1-32
RUN apt-get update && apt-get install -y --no-install-recommends \
      build-essential pkg-config wget ca-certificates \
      libxml2-dev libpng-dev libjpeg-dev zlib1g-dev libfreetype-dev >/dev/null \
 && rm -rf /var/lib/apt/lists/*
RUN wget -q -O /tmp/im.tar.gz "https://github.com/ImageMagick/ImageMagick/archive/refs/tags/${IM_VERSION}.tar.gz" \
 && mkdir -p /usr/src/im && tar -xzf /tmp/im.tar.gz -C /usr/src/im --strip-components=1
WORKDIR /usr/src/im
RUN ./configure --prefix=/usr/local --without-perl --without-magick-plus-plus --disable-openmp \
      --without-x --disable-static --enable-shared >/dev/null \
 && make -j"$(nproc)" >/dev/null \
 && make install >/dev/null \
 && ldconfig \
 && magick -version | head -2 \
 && magick -list format | grep -E ' (MSL|MVG|SVG|MSVG|TEXT|EPHEMERAL|MPC) '

FROM ruby:3.4-bookworm
COPY --from=imbuild /usr/local /usr/local
RUN ldconfig \
 && magick -version | head -2 \
 && magick -list format | grep -E ' (MSL|MVG|SVG|MSVG) '
# Install the Debian/Ubuntu-style ImageMagick policy (it does NOT deny MSL) into the
# ImageMagick 7 configuration directory of the source build.
RUN apt-get update && apt-get install -y --no-install-recommends \
      ca-certificates libxml2 libpng16-16 libjpeg62-turbo libfreetype6 \
      libsqlite3-dev sqlite3 >/dev/null \
 && mkdir -p /tmp/im6 && cd /tmp/im6 \
 && apt-get download imagemagick-6-common >/dev/null 2>&1 \
 && dpkg-deb -x imagemagick-6-common*.deb /tmp/im6 \
 && cp /tmp/im6/etc/ImageMagick-6/policy.xml /usr/local/etc/ImageMagick-7/policy.xml \
 && rm -rf /tmp/im6 /var/lib/apt/lists/* \
 && grep -i -c 'MSL' /usr/local/etc/ImageMagick-7/policy.xml || echo "policy: MSL not denied (expected)"

COPY rails-vuln /rails-vuln
COPY rails-fixed /rails-fixed
COPY app /app-src
RUN for v in vuln fixed; do \
      cp -a /app-src /app-$v; \
      sed -i "s#__RAILS_SRC__#/rails-$v#" /app-$v/Gemfile; \
      cp /rails-$v/activestorage/db/migrate/*.rb /app-$v/db/migrate/; \
      chmod +x /app-$v/bin/rails; \
    done
# The fixed release requires mini_magick >= 5.1 to apply its shipped ImageMagick policy
# (below 5.1 it raises at boot, which is itself part of the fix); the vulnerable release
# is exercised with the mini_magick 5.0.x that the advisory names.
RUN sed -i 's#gem "mini_magick", "~> 5.0.0"#gem "mini_magick", "~> 5.1"#' /app-fixed/Gemfile \
 && grep mini_magick /app-fixed/Gemfile
RUN cd /app-vuln  && bundle config set --local path /bundle-vuln  && bundle install -j4 >/dev/null && bin/rails db:migrate >/dev/null
RUN cd /app-fixed && bundle config set --local path /bundle-fixed && bundle install -j4 >/dev/null && bin/rails db:migrate >/dev/null
# The ruby image sets BUNDLE_APP_CONFIG=/usr/local/bundle, so `bundle config set --local`
# writes one shared file for every app.  Each app is run with its own BUNDLE_PATH instead.
RUN rm -f /usr/local/bundle/config
