From e087b54cf06be55d3384c9b72486462ea529a0d4 Mon Sep 17 00:00:00 2001 From: Ludy Date: Thu, 23 Apr 2026 14:31:21 +0200 Subject: [PATCH] build(docker): pin base container images to immutable digests (#6173) --- .../stirling/software/common/util/FormUtils.java | 14 ++++++++------ docker/base/Dockerfile | 10 +++++----- docker/embedded/Dockerfile | 4 ++-- engine/Dockerfile | 2 +- 4 files changed, 16 insertions(+), 14 deletions(-) diff --git a/app/common/src/main/java/stirling/software/common/util/FormUtils.java b/app/common/src/main/java/stirling/software/common/util/FormUtils.java index 2ae5ace9e..a08463b8a 100644 --- a/app/common/src/main/java/stirling/software/common/util/FormUtils.java +++ b/app/common/src/main/java/stirling/software/common/util/FormUtils.java @@ -629,11 +629,12 @@ public class FormUtils { } log.debug("Skipping form fill because document has no AcroForm"); if (flatten) { - flattenEntireDocument(document, null, false); + flattenEntireDocument(document, null, false, false); } return; } + boolean valuesProvided = values != null && !values.isEmpty(); boolean valuesApplied = false; if (values != null && !values.isEmpty()) { acroForm.setCacheFields(true); @@ -679,7 +680,7 @@ public class FormUtils { repairWidgetGeometry(document, acroForm); if (flatten) { - flattenEntireDocument(document, acroForm, valuesApplied); + flattenEntireDocument(document, acroForm, valuesApplied, valuesProvided); } } @@ -726,15 +727,16 @@ public class FormUtils { // Forcing appearance regeneration via setNeedAppearances(true) drives // PDFBox into refreshAppearances inside flatten(), where it can hang on // certain documents (PDFBOX-5962). We therefore only regenerate when we - // actually wrote new values, or when some widgets are missing appearance - // streams and would otherwise flatten blank. + // actually wrote new values, or when the request included values and the + // document has widgets without appearance streams. private void flattenEntireDocument( - PDDocument document, PDAcroForm acroForm, boolean valuesWritten) throws IOException { + PDDocument document, PDAcroForm acroForm, boolean valuesWritten, boolean valuesProvided) + throws IOException { if (document == null || acroForm == null) { return; } - if (valuesWritten || hasWidgetWithoutAppearance(acroForm)) { + if (valuesWritten || (valuesProvided && hasWidgetWithoutAppearance(acroForm))) { ensureAppearances(acroForm); } else { acroForm.setNeedAppearances(false); diff --git a/docker/base/Dockerfile b/docker/base/Dockerfile index 4b288b010..e620bbfb0 100644 --- a/docker/base/Dockerfile +++ b/docker/base/Dockerfile @@ -5,7 +5,7 @@ ARG TARGETPLATFORM # Stage 1: Build and strip Calibre -FROM ubuntu:noble AS calibre-build +FROM ubuntu:noble@sha256:c4a8d5503dfb2a3eb8ab5f807da5bc69a85730fb49b5cfca2330194ebcc41c7b AS calibre-build ARG TARGETPLATFORM ARG CALIBRE_VERSION=9.4.0 ARG CALIBRE_STRIP_WEBENGINE=false @@ -270,7 +270,7 @@ RUN if [ "${CALIBRE_STRIP_WEBENGINE}" = "true" ]; then \ # Stage 2: Build Ghostscript from source -FROM ubuntu:noble AS gs-build +FROM ubuntu:noble@sha256:c4a8d5503dfb2a3eb8ab5f807da5bc69a85730fb49b5cfca2330194ebcc41c7b AS gs-build ARG TARGETPLATFORM ARG GS_VERSION=10.06.0 @@ -294,7 +294,7 @@ RUN --mount=type=cache,target=/var/cache/apt,sharing=locked \ # Stage 3: Build PDF Tools (QPDF and ImageMagick 7) -FROM ubuntu:noble AS pdf-tools-build +FROM ubuntu:noble@sha256:c4a8d5503dfb2a3eb8ab5f807da5bc69a85730fb49b5cfca2330194ebcc41c7b AS pdf-tools-build ARG TARGETPLATFORM ARG QPDF_VERSION=12.3.2 ARG IM_VERSION=7.1.2-13 @@ -339,7 +339,7 @@ RUN mkdir -p /magick-export/usr/bin \ # Stage 4: Build Python venv -FROM ubuntu:noble AS python-venv-build +FROM ubuntu:noble@sha256:c4a8d5503dfb2a3eb8ab5f807da5bc69a85730fb49b5cfca2330194ebcc41c7b AS python-venv-build ARG TARGETPLATFORM ARG UNOSERVER_VERSION=3.6 @@ -364,7 +364,7 @@ RUN --mount=type=cache,target=/root/.cache/pip,sharing=locked \ # Final runtime image - the actual base image -FROM eclipse-temurin:25-jre-noble AS runtime +FROM eclipse-temurin:25-jre-noble@sha256:a051234f864d7ab78bf0188c3c540ac06c711a3b566f00f246be37073cc99dce AS runtime SHELL ["/bin/bash", "-o", "pipefail", "-c"] diff --git a/docker/embedded/Dockerfile b/docker/embedded/Dockerfile index 6f6a5ff02..a51744cb2 100644 --- a/docker/embedded/Dockerfile +++ b/docker/embedded/Dockerfile @@ -5,7 +5,7 @@ ARG BASE_VERSION=1.0.2 ARG BASE_IMAGE=stirlingtools/stirling-pdf-base:${BASE_VERSION} # Stage 1: Build the Java application and frontend -FROM gradle:9.3.1-jdk25 AS app-build +FROM gradle:9.3.1-jdk25@sha256:85aec999629f4774a383cb792da4b598bdf5a7e69c4b9570bb70c0f919179183 AS app-build ARG TASK_VERSION=3.49.1 RUN apt-get update \ @@ -48,7 +48,7 @@ RUN DISABLE_ADDITIONAL_FEATURES=false \ --no-daemon # Stage 2: Extract Spring Boot Layers -FROM eclipse-temurin:25-jre-noble AS jar-extract +FROM eclipse-temurin:25-jre-noble@sha256:a051234f864d7ab78bf0188c3c540ac06c711a3b566f00f246be37073cc99dce AS jar-extract WORKDIR /tmp COPY --from=app-build /app/app/core/build/libs/*.jar app.jar RUN java -Djarmode=tools -jar app.jar extract --layers --destination /layers diff --git a/engine/Dockerfile b/engine/Dockerfile index 5caeb5d6b..c9c8d2239 100644 --- a/engine/Dockerfile +++ b/engine/Dockerfile @@ -1,5 +1,5 @@ # syntax=docker/dockerfile:1.5 -FROM ghcr.io/astral-sh/uv:python3.13-bookworm-slim +FROM ghcr.io/astral-sh/uv:python3.13-bookworm-slim@sha256:531f855bda2c73cd6ef67d56b733b357cea384185b3022bd09f05e002cd144ca ARG TASK_VERSION=3.49.1 RUN apt-get update \