diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
index a07fb0d62..e9e6dfe5a 100644
--- a/.github/workflows/ci.yml
+++ b/.github/workflows/ci.yml
@@ -6,31 +6,25 @@ jobs:
strategy:
matrix:
os: [ubuntu-latest, windows-latest]
- java: [jdk11, jdk15, graalvm]
+ java: [jdk11, jdk18, graalvm]
fail-fast: false
steps:
- name: Check out the repository
uses: actions/checkout@v2
- name: Test in Linux JDK 11
if: matrix.os == 'ubuntu-latest' && matrix.java == 'jdk11'
- run: docker-compose -f docker/Linux-JDK11/docker-compose.yml up --exit-code-from cantaloupe
- - name: Test in Linux JDK 15
- if: matrix.os == 'ubuntu-latest' && matrix.java == 'jdk15'
- run: docker-compose -f docker/Linux-JDK15/docker-compose.yml up --exit-code-from cantaloupe
- - name: Test in Linux JDK 16
- if: matrix.os == 'ubuntu-latest' && matrix.java == 'jdk16'
- run: docker-compose -f docker/Linux-JDK16/docker-compose.yml up --exit-code-from cantaloupe
+ run: docker-compose -f docker/Linux-JDK11/docker-compose.yml up --build --exit-code-from cantaloupe
+ - name: Test in Linux JDK 18
+ if: matrix.os == 'ubuntu-latest' && matrix.java == 'jdk18'
+ run: docker-compose -f docker/Linux-JDK18/docker-compose.yml up --build --exit-code-from cantaloupe
- name: Test in Linux GraalVM
if: matrix.os == 'ubuntu-latest' && matrix.java == 'graalvm'
- run: docker-compose -f docker/Linux-GraalVM20/docker-compose.yml up --exit-code-from cantaloupe
+ run: docker-compose -f docker/Linux-GraalVM20/docker-compose.yml up --build --exit-code-from cantaloupe
- name: Test in Windows JDK 11
if: matrix.os == 'windows-latest' && matrix.java == 'jdk11'
- run: docker-compose -f docker/Windows-JDK11/docker-compose.yml up --exit-code-from cantaloupe
- - name: Test in Windows JDK 15
- if: matrix.os == 'windows-latest' && matrix.java == 'jdk15'
- run: docker-compose -f docker/Windows-JDK15/docker-compose.yml up --exit-code-from cantaloupe
- - name: Test in Windows JDK 16
- if: matrix.os == 'windows-latest' && matrix.java == 'jdk16'
- run: docker-compose -f docker/Windows-JDK16/docker-compose.yml up --exit-code-from cantaloupe
+ run: docker-compose -f docker/Windows-JDK11/docker-compose.yml up --build --exit-code-from cantaloupe
+ - name: Test in Windows JDK 18
+ if: matrix.os == 'windows-latest' && matrix.java == 'jdk18'
+ run: docker-compose -f docker/Windows-JDK18/docker-compose.yml up --build --exit-code-from cantaloupe
# TODO: Windows+GraalVM
diff --git a/CHANGES.md b/CHANGES.md
index 6146b708b..e3ac2baaa 100644
--- a/CHANGES.md
+++ b/CHANGES.md
@@ -37,10 +37,14 @@
## 5.0.6
* IIIF information endpoints always return JSON in HTTP 4xx responses.
+* Fixed a bug whereby the values of the `operations` and `page_count` keys
+ in the delegate context were not set.
* TurboJpegProcessor is able to generate non-JPEG derivative images, which
fixes an HTTP 415 error that would occur when trying to do that.
* Fixed a crop-offset bug that could occur when using PdfBoxProcessor to
generate JPEGs with libjpeg-turbo active.
+* Updating libraries to fix security issues. Full details in [#634](https://github.com/cantaloupe-project/cantaloupe/issues/634)
+* Update of Jena to 4.8 requires RDF to have a populated rdf:about field. May impact some XMP header processing.
## 5.0.5
diff --git a/CREDITS.md b/CREDITS.md
new file mode 100644
index 000000000..e0849d234
--- /dev/null
+++ b/CREDITS.md
@@ -0,0 +1,9 @@
+# Credits
+
+The success of this project is down to the great work done by the developers at the University of Illinois and particularly Alex Dolski who has been the main developer on the project. In 2023 the IIIF consortium offered to help release a security patch as so many IIIF community members are using this great software.
+
+- Cantaloupe 5.0.6
+ * [Glen Robson](https://github.com/glenrobson/) with support from the [IIIF Consortium](https://iiif.io/community/consortium/)
+
+- Cantaloupe v1 - v6
+ * [Alex Dolski](https://github.com/adolski), University of Illinois
\ No newline at end of file
diff --git a/docker/Linux-GraalVM20/Dockerfile b/docker/Linux-GraalVM20/Dockerfile
index 847a3795f..55b7c044c 100644
--- a/docker/Linux-GraalVM20/Dockerfile
+++ b/docker/Linux-GraalVM20/Dockerfile
@@ -1,4 +1,4 @@
-FROM ubuntu:latest
+FROM ubuntu:lunar
ENV JAVA_HOME=/opt/graalvm-ce-java11-20.3.0
ENV GRAALVM_HOME=/opt/graalvm-ce-java11-20.3.0
@@ -20,6 +20,9 @@ RUN apt-get update && apt-get install -y --no-install-recommends \
zlib1g-dev \
libwebp-dev \
libimage-exiftool-perl \
+ libgrokj2k1 \
+ grokj2k-tools \
+ adduser \
&& rm -rf /var/lib/apt/lists/*
# Install TurboJpegProcessor dependencies
@@ -30,10 +33,10 @@ COPY docker/Linux-JDK11/image_files/libjpeg-turbo/lib64 /opt/libjpeg-turbo/lib
COPY dist/deps/Linux-x86-64/lib/* /usr/lib/
# Install GrokProcessor dependencies
-RUN wget -q https://github.com/GrokImageCompression/grok/releases/download/v7.6.5/libgrokj2k1_7.6.5-1_amd64.deb \
- && wget -q https://github.com/GrokImageCompression/grok/releases/download/v7.6.5/grokj2k-tools_7.6.5-1_amd64.deb \
- && dpkg -i ./libgrokj2k1_7.6.5-1_amd64.deb \
- && dpkg -i --ignore-depends=libjpeg62-turbo ./grokj2k-tools_7.6.5-1_amd64.deb
+#RUN wget -q https://github.com/GrokImageCompression/grok/releases/download/v7.6.5/libgrokj2k1_7.6.5-1_amd64.deb \
+# && wget -q https://github.com/GrokImageCompression/grok/releases/download/v7.6.5/grokj2k-tools_7.6.5-1_amd64.deb \
+# && dpkg -i --ignore-depends=libjpeg62-turbo ./grokj2k-tools_7.6.5-1_amd64.deb
+# && dpkg -i ./libgrokj2k1_7.6.5-1_amd64.deb \
# Install GraalVM
RUN wget -q https://github.com/graalvm/graalvm-ce-builds/releases/download/vm-20.3.0/graalvm-ce-java11-linux-amd64-20.3.0.tar.gz \
diff --git a/docker/Linux-JDK11/Dockerfile b/docker/Linux-JDK11/Dockerfile
index fb3eab9d5..3129f9a73 100644
--- a/docker/Linux-JDK11/Dockerfile
+++ b/docker/Linux-JDK11/Dockerfile
@@ -1,4 +1,4 @@
-FROM ubuntu:latest
+FROM ubuntu:lunar
ARG DEBIAN_FRONTEND=noninteractive
@@ -18,6 +18,9 @@ RUN apt-get update && apt-get install -y --no-install-recommends \
zlib1g-dev \
libwebp-dev \
libimage-exiftool-perl \
+ libgrokj2k1 \
+ grokj2k-tools \
+ adduser \
&& rm -rf /var/lib/apt/lists/*
# Install TurboJpegProcessor dependencies
@@ -28,16 +31,16 @@ COPY docker/Linux-JDK11/image_files/libjpeg-turbo/lib64 /opt/libjpeg-turbo/lib
COPY dist/deps/Linux-x86-64/lib/* /usr/lib/
# Install GrokProcessor dependencies
-RUN wget -q https://github.com/GrokImageCompression/grok/releases/download/v7.6.5/libgrokj2k1_7.6.5-1_amd64.deb \
- && wget -q https://github.com/GrokImageCompression/grok/releases/download/v7.6.5/grokj2k-tools_7.6.5-1_amd64.deb \
- && dpkg -i ./libgrokj2k1_7.6.5-1_amd64.deb \
- && dpkg -i --ignore-depends=libjpeg62-turbo ./grokj2k-tools_7.6.5-1_amd64.deb
+#RUN wget -q https://github.com/GrokImageCompression/grok/releases/download/v7.6.5/libgrokj2k1_7.6.5-1_amd64.deb \
+# && wget -q https://github.com/GrokImageCompression/grok/releases/download/v7.6.5/grokj2k-tools_7.6.5-1_amd64.deb \
+# && dpkg -i ./libgrokj2k1_7.6.5-1_amd64.deb \
+# && dpkg -i --ignore-depends=libjpeg62-turbo ./grokj2k-tools_7.6.5-1_amd64.deb
# A non-root user is needed for some FilesystemSourceTest tests to work.
ARG user=cantaloupe
ARG home=/home/$user
RUN adduser --home $home $user
-RUN chown -R $user $home
+RUN chown -R $user $home
USER $user
WORKDIR $home
diff --git a/docker/Linux-JDK15/Dockerfile b/docker/Linux-JDK15/Dockerfile
deleted file mode 100644
index d8ffc2296..000000000
--- a/docker/Linux-JDK15/Dockerfile
+++ /dev/null
@@ -1,57 +0,0 @@
-FROM ubuntu:latest
-
-ENV JAVA_HOME=/opt/jdk
-ENV PATH=$PATH:/opt/jdk/bin
-ARG DEBIAN_FRONTEND=noninteractive
-
-# Install various dependencies
-RUN apt-get update && apt-get install -y --no-install-recommends \
- ffmpeg \
- maven \
- wget \
- libopenjp2-tools \
- liblcms2-dev \
- libpng-dev \
- libzstd-dev \
- libtiff-dev \
- libjpeg-dev \
- zlib1g-dev \
- libwebp-dev \
- libimage-exiftool-perl \
- && rm -rf /var/lib/apt/lists/*
-
-# Install TurboJpegProcessor dependencies
-RUN mkdir -p /opt/libjpeg-turbo/lib
-COPY docker/Linux-JDK11/image_files/libjpeg-turbo/lib64 /opt/libjpeg-turbo/lib
-
-# Install KakaduNativeProcessor dependencies
-COPY dist/deps/Linux-x86-64/lib/* /usr/lib/
-
-# Install GrokProcessor dependencies
-RUN wget -q https://github.com/GrokImageCompression/grok/releases/download/v7.6.5/libgrokj2k1_7.6.5-1_amd64.deb \
- && wget -q https://github.com/GrokImageCompression/grok/releases/download/v7.6.5/grokj2k-tools_7.6.5-1_amd64.deb \
- && dpkg -i ./libgrokj2k1_7.6.5-1_amd64.deb \
- && dpkg -i --ignore-depends=libjpeg62-turbo ./grokj2k-tools_7.6.5-1_amd64.deb
-
-# Install OpenJDK
-RUN wget -q https://github.com/AdoptOpenJDK/openjdk15-binaries/releases/download/jdk-15.0.1%2B9/OpenJDK15U-jdk_x64_linux_hotspot_15.0.1_9.tar.gz \
- && tar xfz OpenJDK15U-jdk_x64_linux_hotspot_15.0.1_9.tar.gz \
- && mv jdk-15.0.1+9 /opt/jdk
-
-# A non-root user is needed for some FilesystemSourceTest tests to work.
-ARG user=cantaloupe
-ARG home=/home/$user
-RUN adduser --home $home $user
-RUN chown -R $user $home
-USER $user
-WORKDIR $home
-
-# Install application dependencies
-COPY ./pom.xml pom.xml
-RUN mvn --quiet dependency:resolve
-
-# Copy the code
-COPY --chown=cantaloupe docker/Linux-JDK11/image_files/test.properties test.properties
-COPY --chown=cantaloupe ./src src
-
-ENTRYPOINT mvn --batch-mode test -Pfreedeps
\ No newline at end of file
diff --git a/docker/Linux-JDK15/docker-compose.yml b/docker/Linux-JDK15/docker-compose.yml
deleted file mode 100644
index 4b4136275..000000000
--- a/docker/Linux-JDK15/docker-compose.yml
+++ /dev/null
@@ -1,21 +0,0 @@
-#
-# N.B.: docker-compose must be invoked from the project root directory:
-#
-# docker-compose -f path/to/docker-compose.yml up --exit-code-from cantaloupe
-#
-version: '3'
-services:
- cantaloupe:
- build:
- context: ../../
- dockerfile: $PWD/docker/Linux-JDK15/Dockerfile
- minio:
- image: minio/minio
- environment:
- MINIO_ACCESS_KEY: MinioUser
- MINIO_SECRET_KEY: OpenSesame
- hostname: minio
- command: server /data
- redis:
- image: redis:alpine
- hostname: redis
\ No newline at end of file
diff --git a/docker/Linux-JDK16/Dockerfile b/docker/Linux-JDK18/Dockerfile
similarity index 61%
rename from docker/Linux-JDK16/Dockerfile
rename to docker/Linux-JDK18/Dockerfile
index 34e828755..ac131292b 100644
--- a/docker/Linux-JDK16/Dockerfile
+++ b/docker/Linux-JDK18/Dockerfile
@@ -1,4 +1,4 @@
-FROM ubuntu:latest
+FROM ubuntu:lunar
ENV JAVA_HOME=/opt/jdk
ENV PATH=$PATH:/opt/jdk/bin:/opt/maven/bin
@@ -23,6 +23,9 @@ RUN apt-get update && apt-get install -y --no-install-recommends \
zlib1g-dev \
libwebp-dev \
libimage-exiftool-perl \
+ libgrokj2k1 \
+ grokj2k-tools \
+ adduser \
&& rm -rf /var/lib/apt/lists/*
# Install TurboJpegProcessor dependencies
@@ -34,19 +37,19 @@ COPY dist/deps/Linux-x86-64/lib/* /usr/lib/
# Install various other dependencies that aren't in apt
# Install GrokProcessor dependencies
-RUN wget -q https://github.com/GrokImageCompression/grok/releases/download/v7.6.5/libgrokj2k1_7.6.5-1_amd64.deb \
- && wget -q https://github.com/GrokImageCompression/grok/releases/download/v7.6.5/grokj2k-tools_7.6.5-1_amd64.deb \
- && dpkg -i ./libgrokj2k1_7.6.5-1_amd64.deb \
- && dpkg -i --ignore-depends=libjpeg62-turbo ./grokj2k-tools_7.6.5-1_amd64.deb \
+#RUN wget -q https://github.com/GrokImageCompression/grok/releases/download/v7.6.5/libgrokj2k1_7.6.5-1_amd64.deb \
+# && wget -q https://github.com/GrokImageCompression/grok/releases/download/v7.6.5/grokj2k-tools_7.6.5-1_amd64.deb \
+# && dpkg -i ./libgrokj2k1_7.6.5-1_amd64.deb \
+# && dpkg -i --ignore-depends=libjpeg62-turbo ./grokj2k-tools_7.6.5-1_amd64.deb \
# Install OpenJDK
- && wget -q https://github.com/AdoptOpenJDK/openjdk16-binaries/releases/download/jdk-16.0.1%2B9/OpenJDK16U-jdk_x64_linux_hotspot_16.0.1_9.tar.gz \
- && tar xfz OpenJDK16U-jdk_x64_linux_hotspot_16.0.1_9.tar.gz \
- && mv jdk-16.0.1+9 /opt/jdk \
- # Install Maven (the one in apt is too old for JDK16 as of 2020-05-14)
- && wget -q https://mirrors.ocf.berkeley.edu/apache/maven/maven-3/3.8.1/binaries/apache-maven-3.8.1-bin.tar.gz \
- && tar xfz apache-maven-3.8.1-bin.tar.gz \
- && mv apache-maven-3.8.1 /opt/maven \
- && rm apache-maven-3.8.1-bin.tar.gz
+RUN wget -q https://download.java.net/java/GA/jdk18/43f95e8614114aeaa8e8a5fcf20a682d/36/GPL/openjdk-18_linux-x64_bin.tar.gz \
+ && tar xfz openjdk-18_linux-x64_bin.tar.gz \
+ && mv jdk-18 /opt/jdk \
+ # Install a newer Maven than the one in apt
+ && wget -q https://dlcdn.apache.org/maven/maven-3/3.8.8/binaries/apache-maven-3.8.8-bin.tar.gz \
+ && tar xfz apache-maven-3.8.8-bin.tar.gz \
+ && mv apache-maven-3.8.8 /opt/maven \
+ && rm apache-maven-3.8.8-bin.tar.gz
# A non-root user is needed for some FilesystemSourceTest tests to work.
ARG user=cantaloupe
diff --git a/docker/Linux-JDK16/docker-compose.yml b/docker/Linux-JDK18/docker-compose.yml
similarity index 89%
rename from docker/Linux-JDK16/docker-compose.yml
rename to docker/Linux-JDK18/docker-compose.yml
index b6518c805..7b2572bc0 100644
--- a/docker/Linux-JDK16/docker-compose.yml
+++ b/docker/Linux-JDK18/docker-compose.yml
@@ -8,7 +8,7 @@ services:
cantaloupe:
build:
context: ../../
- dockerfile: $PWD/docker/Linux-JDK16/Dockerfile
+ dockerfile: $PWD/docker/Linux-JDK18/Dockerfile
minio:
image: minio/minio
environment:
diff --git a/docker/Windows-JDK11/Dockerfile b/docker/Windows-JDK11/Dockerfile
index 8d81bd6d1..ba1008de8 100644
--- a/docker/Windows-JDK11/Dockerfile
+++ b/docker/Windows-JDK11/Dockerfile
@@ -1,4 +1,4 @@
-FROM mcr.microsoft.com/windows/servercore:ltsc2019
+FROM mcr.microsoft.com/windows/servercore:ltsc2022
ENV chocolateyUseWindowsCompression false
diff --git a/docker/Windows-JDK11/Dockerfile-minio b/docker/Windows-JDK11/Dockerfile-minio
index b213b8746..115389668 100644
--- a/docker/Windows-JDK11/Dockerfile-minio
+++ b/docker/Windows-JDK11/Dockerfile-minio
@@ -1,4 +1,4 @@
-FROM mcr.microsoft.com/windows/servercore:ltsc2019
+FROM mcr.microsoft.com/windows/servercore:ltsc2022
ENV MINIO_ACCESS_KEY=MinioUser
ENV MINIO_SECRET_KEY=OpenSesame
diff --git a/docker/Windows-JDK15/Dockerfile b/docker/Windows-JDK15/Dockerfile
deleted file mode 100644
index 79307a09a..000000000
--- a/docker/Windows-JDK15/Dockerfile
+++ /dev/null
@@ -1,28 +0,0 @@
-FROM mcr.microsoft.com/windows/servercore:ltsc2019
-
-ENV chocolateyUseWindowsCompression false
-
-# Install the Chocolatey package manager, which makes it easier to install
-# dependencies.
-RUN powershell -Command \
- iex ((new-object net.webclient).DownloadString('https://chocolatey.org/install.ps1')); \
- choco feature disable --name showDownloadProgress
-
-# Install various dependencies
-# TODO: openjpeg
-RUN choco install -y adoptopenjdk15 maven ffmpeg
-
-# Install TurboJpegProcessor dependencies TODO: libjpeg-turbo
-#RUN mkdir -p /opt/libjpeg-turbo/lib
-#COPY docker/Windows10-JDK11/image_files/libjpeg-turbo/lib64 c:\windows\system32
-
-# Install KakaduNativeProcessor dependencies
-COPY dist/deps/Windows-x86-64/lib/* c:/Windows/System32/
-
-# Install application dependencies
-COPY pom.xml pom.xml
-RUN mvn dependency:resolve
-
-# Copy the code
-COPY docker/Windows-JDK11/image_files/test.properties test.properties
-COPY src src
\ No newline at end of file
diff --git a/docker/Windows-JDK15/Dockerfile-minio b/docker/Windows-JDK15/Dockerfile-minio
deleted file mode 100644
index babcdadfd..000000000
--- a/docker/Windows-JDK15/Dockerfile-minio
+++ /dev/null
@@ -1,10 +0,0 @@
-FROM mcr.microsoft.com/windows/servercore:ltsc2019
-
-ENV MINIO_ACCESS_KEY=MinioUser
-ENV MINIO_SECRET_KEY=OpenSesame
-
-RUN curl.exe --output minio.exe --url https://dl.min.io/server/minio/release/windows-amd64/minio.exe
-
-RUN mkdir c:\data
-
-CMD minio.exe server --address=:9000 c:\data
\ No newline at end of file
diff --git a/docker/Windows-JDK15/docker-compose.yml b/docker/Windows-JDK15/docker-compose.yml
deleted file mode 100644
index e2c44b801..000000000
--- a/docker/Windows-JDK15/docker-compose.yml
+++ /dev/null
@@ -1,19 +0,0 @@
-#
-# N.B.: docker-compose must be invoked from the project root directory:
-#
-# docker-compose -f path/to/docker-compose.yml up --exit-code-from cantaloupe
-#
-version: '3'
-services:
- cantaloupe:
- build:
- context: ../../
- dockerfile: docker/Windows-JDK15/Dockerfile
- minio:
- build:
- context: ../../
- dockerfile: docker/Windows-JDK15/Dockerfile-minio
- environment:
- MINIO_ACCESS_KEY: MinioUser
- MINIO_SECRET_KEY: OpenSesame
- hostname: minio
\ No newline at end of file
diff --git a/docker/Windows-JDK16/Dockerfile b/docker/Windows-JDK18/Dockerfile
similarity index 86%
rename from docker/Windows-JDK16/Dockerfile
rename to docker/Windows-JDK18/Dockerfile
index dc0c9673a..e3f570efc 100644
--- a/docker/Windows-JDK16/Dockerfile
+++ b/docker/Windows-JDK18/Dockerfile
@@ -1,4 +1,4 @@
-FROM mcr.microsoft.com/windows/servercore:ltsc2019
+FROM mcr.microsoft.com/windows/servercore:ltsc2022
ENV chocolateyUseWindowsCompression false
@@ -10,8 +10,9 @@ RUN powershell -Command \
# Install various dependencies
# TODO: openjpeg
-RUN choco install -y adoptopenjdk16 maven ffmpeg
-
+RUN choco install -y maven ffmpeg
+RUN choco install -y openjdk --version=18.0.2
+
# Install TurboJpegProcessor dependencies TODO: libjpeg-turbo
#RUN mkdir -p /opt/libjpeg-turbo/lib
#COPY docker/Windows10-JDK11/image_files/libjpeg-turbo/lib64 c:\windows\system32
diff --git a/docker/Windows-JDK16/Dockerfile-minio b/docker/Windows-JDK18/Dockerfile-minio
similarity index 81%
rename from docker/Windows-JDK16/Dockerfile-minio
rename to docker/Windows-JDK18/Dockerfile-minio
index b213b8746..115389668 100644
--- a/docker/Windows-JDK16/Dockerfile-minio
+++ b/docker/Windows-JDK18/Dockerfile-minio
@@ -1,4 +1,4 @@
-FROM mcr.microsoft.com/windows/servercore:ltsc2019
+FROM mcr.microsoft.com/windows/servercore:ltsc2022
ENV MINIO_ACCESS_KEY=MinioUser
ENV MINIO_SECRET_KEY=OpenSesame
diff --git a/docker/Windows-JDK16/docker-compose.yml b/docker/Windows-JDK18/docker-compose.yml
similarity index 77%
rename from docker/Windows-JDK16/docker-compose.yml
rename to docker/Windows-JDK18/docker-compose.yml
index 1a505d28b..3c5812953 100644
--- a/docker/Windows-JDK16/docker-compose.yml
+++ b/docker/Windows-JDK18/docker-compose.yml
@@ -8,11 +8,11 @@ services:
cantaloupe:
build:
context: ../../
- dockerfile: docker/Windows-JDK16/Dockerfile
+ dockerfile: docker/Windows-JDK18/Dockerfile
minio:
build:
context: ../../
- dockerfile: docker/Windows-JDK16/Dockerfile-minio
+ dockerfile: docker/Windows-JDK18/Dockerfile-minio
environment:
MINIO_ACCESS_KEY: MinioUser
MINIO_SECRET_KEY: OpenSesame
diff --git a/pom.xml b/pom.xml
index 6f0550f0c..fb8027428 100644
--- a/pom.xml
+++ b/pom.xml
@@ -15,12 +15,16 @@
11
UTF-8
UTF-8
- 2.15.28
- 2.11.0
+ 2.21.4
+ 2.15.2
+
+
11.0.5
- 9.2.17.0
- 1.2.8
- 3.0.0-M3
+ 9.4.3.0
+ 3.0.0-M5
+ 2.53.1
+ 1.2.13
+ 1.7.36
@@ -70,25 +74,25 @@
net.logstash.logback
logstash-logback-encoder
- 6.1
+ 7.4
com.github.ben-manes.caffeine
caffeine
- 2.5.6
+ 3.1.6
com.google.protobuf
protobuf-java
- 3.5.1
+ 4.0.0-rc-2
com.h2database
h2
- 1.4.196
+ 2.2.220
test
@@ -101,19 +105,19 @@
com.microsoft.azure
azure-storage
- 5.2.0
+ 8.6.6
com.squareup.okhttp3
okhttp
- 3.13.1
+ 5.0.0-alpha.12
com.zaxxer
HikariCP
- 2.7.2
+ 4.0.3
@@ -126,7 +130,7 @@
commons-io
commons-io
- 2.4
+ 2.13.0
edu.illinois.library
@@ -137,63 +141,64 @@
io.lettuce
lettuce-core
- 6.0.1.RELEASE
+ 6.2.7.RELEASE
javax.xml.bind
jaxb-api
- 2.3.0
+ 2.4.0-b180830.0359
it.geosolutions.imageio-ext
imageio-ext-tiff
+
1.3.2
javax.servlet
javax.servlet-api
- 3.1.0
+ 4.0.1
org.apache.commons
commons-lang3
- 3.6
+ 3.12.0
org.apache.pdfbox
pdfbox
- 2.0.23
+ 2.0.29
org.apache.pdfbox
jbig2-imageio
- 3.0.3
+ 3.0.4
org.junit.jupiter
junit-jupiter-engine
- 5.4.2
+ 5.10.0-RC1
test
org.openjdk.jmh
jmh-core
- 1.19
+ 1.36
test
org.openjdk.jmh
jmh-generator-annprocess
- 1.19
+ 1.36
test
org.apache.tika
tika-core
- 1.24.1
+ 2.8.0
org.bouncycastle
- bcprov-jdk15on
- 1.64
+ bcprov-jdk18on
+ 1.76
org.codehaus.janino
janino
- 2.7.8
+ 3.1.10
@@ -330,45 +335,45 @@
org.apache.velocity
velocity-engine-core
- 2.0
+ 2.3
org.seleniumhq.selenium
htmlunit-driver
- 2.21
+ 2.21
test
org.seleniumhq.selenium
selenium-api
- 2.53.0
+ ${seleniumhq.version}
test
org.seleniumhq.selenium
selenium-support
- 2.53.0
+ ${seleniumhq.version}
test
org.slf4j
slf4j-api
- 1.7.25
+ ${slf4j.version}
org.slf4j
jcl-over-slf4j
- 1.7.25
+ ${slf4j.version}
org.apache.maven.plugins
maven-assembly-plugin
- 3.1.1
+ 3.6.0
maven-plugin
@@ -420,8 +425,9 @@
random
false
-
- --illegal-access=permit
+
+
+ --add-opens java.desktop/sun.awt.image=ALL-UNNAMED --illegal-access=permit
@@ -429,13 +435,13 @@
com.github.spotbugs
spotbugs-maven-plugin
- 4.1.3
+ 4.8.3.0
com.github.spotbugs
spotbugs
- 4.1.4
+ 4.8.3
@@ -499,7 +505,7 @@
maven-assembly-plugin
- 3.1.1
+ 3.6.0
package
@@ -530,7 +536,7 @@
org.owasp
dependency-check-maven
- 5.2.4
+ 9.0.9
@@ -557,6 +563,8 @@
random
false
+
+ --add-opens java.desktop/sun.awt.image=ALL-UNNAMED
AzureStorage*Test
FfmpegProcessorTest
@@ -586,6 +594,8 @@
random
false
+
+ --add-opens java.desktop/sun.awt.image=ALL-UNNAMED
Azure*Test
diff --git a/src/main/java/edu/illinois/library/cantaloupe/cache/JdbcCache.java b/src/main/java/edu/illinois/library/cantaloupe/cache/JdbcCache.java
index f147f0700..58ce6caca 100644
--- a/src/main/java/edu/illinois/library/cantaloupe/cache/JdbcCache.java
+++ b/src/main/java/edu/illinois/library/cantaloupe/cache/JdbcCache.java
@@ -102,7 +102,9 @@ public void close() throws IOException {
throw new IOException(e.getMessage(), e);
} finally {
try {
- statement.close();
+ if (statement != null) {
+ statement.close();
+ }
} catch (SQLException e) {
LOGGER.error(e.getMessage(), e);
}
@@ -361,7 +363,7 @@ public InputStream newDerivativeImageInputStream(OperationList opList)
DERIVATIVE_IMAGE_TABLE_LAST_ACCESSED_COLUMN);
try (Connection conn = getConnection();
- PreparedStatement statement = conn.prepareStatement(sql)) {
+ PreparedStatement statement = conn.prepareStatement(sql)) {
statement.setString(1, opList.toString());
statement.setTimestamp(2, earliestValidDate());
@@ -390,6 +392,7 @@ public InputStream newDerivativeImageInputStream(OperationList opList)
try {
return new ImageBlobOutputStream(getConnection(), ops);
} catch (SQLException e) {
+ LOGGER.error("Throwing Except: {}", e);
throw new IOException(e.getMessage(), e);
}
}
diff --git a/src/main/java/edu/illinois/library/cantaloupe/image/MediaType.java b/src/main/java/edu/illinois/library/cantaloupe/image/MediaType.java
index 1c4b0b367..d5370f3c0 100644
--- a/src/main/java/edu/illinois/library/cantaloupe/image/MediaType.java
+++ b/src/main/java/edu/illinois/library/cantaloupe/image/MediaType.java
@@ -12,6 +12,7 @@
import org.apache.tika.detect.Detector;
import org.apache.tika.io.TikaInputStream;
import org.apache.tika.metadata.Metadata;
+import org.apache.tika.metadata.TikaCoreProperties;
import org.apache.tika.parser.AutoDetectParser;
import java.io.IOException;
@@ -99,7 +100,7 @@ public static List detectMediaTypes(Path path)
AutoDetectParser parser = new AutoDetectParser();
Detector detector = parser.getDetector();
Metadata md = new Metadata();
- md.add(Metadata.RESOURCE_NAME_KEY, path.toString());
+ md.add(TikaCoreProperties.RESOURCE_NAME_KEY, path.toString());
org.apache.tika.mime.MediaType mediaType = detector.detect(is, md);
types.add(new MediaType(mediaType.toString()));
}
diff --git a/src/main/java/edu/illinois/library/cantaloupe/image/Metadata.java b/src/main/java/edu/illinois/library/cantaloupe/image/Metadata.java
index 1baa942c2..8a2d26819 100644
--- a/src/main/java/edu/illinois/library/cantaloupe/image/Metadata.java
+++ b/src/main/java/edu/illinois/library/cantaloupe/image/Metadata.java
@@ -123,6 +123,9 @@ public Orientation getOrientation() {
} catch (IllegalArgumentException e) {
LOGGER.info("readOrientation(): {}", e.getMessage());
orientation = Orientation.ROTATE_0;
+ } catch (RiotException e) {
+ LOGGER.info("readOrientation(): {}", e.getMessage());
+ orientation = Orientation.ROTATE_0;
}
}
return orientation;
@@ -209,10 +212,27 @@ private void loadXMP() {
RIOT.init();
xmpModel = ModelFactory.createDefaultModel();
+ String base = null;
+ if (xmp.get().indexOf("rdf:about=''") != -1 || xmp.get().indexOf("rdf:about=\"\"") != -1) {
+ // Version 4.8+ of jena requires a rdf:about link to not be empty
+ base = "http://example.com";
+ }
try (StringReader reader = new StringReader(xmp.get())) {
- xmpModel.read(reader, null, "RDF/XML");
- } catch (RiotException | NullPointerException e) {
+ xmpModel.read(reader, base, "RDF/XML");
+ } catch (RiotException e) {
+ if (e.getMessage().indexOf("Base URI is null, but there are relative URIs to resolve") != -1) {
+ // Version 4.8+ of jena requires a rdf:about link to not be empty
+ try (StringReader reader = new StringReader(xmp.get())) {
+ xmpModel.read(reader, "http://example.com", "RDF/XML");
+ } catch (RiotException exception) {
+ LOGGER.info("loadXMP(): {}", exception.getMessage());
+ }
+ } else {
+ LOGGER.info("loadXMP(): {}", e.getMessage());
+ throw e;
+ }
+ } catch (NullPointerException e) {
// The XMP string may be invalid RDF/XML, or there may be a bug
// in Jena (that would be the NPE). Not much we can do.
LOGGER.info("loadXMP(): {}", e.getMessage());
diff --git a/src/main/java/edu/illinois/library/cantaloupe/processor/PdfBoxProcessor.java b/src/main/java/edu/illinois/library/cantaloupe/processor/PdfBoxProcessor.java
index 0197feab7..6de50010c 100644
--- a/src/main/java/edu/illinois/library/cantaloupe/processor/PdfBoxProcessor.java
+++ b/src/main/java/edu/illinois/library/cantaloupe/processor/PdfBoxProcessor.java
@@ -142,7 +142,8 @@ public boolean isSeeking() {
private void readDocument() throws IOException {
if (doc == null) {
final Stopwatch watch = new Stopwatch();
-
+ // For PDF Box v3 this would need to change to a loader:
+ // https://pdfbox.apache.org/3.0/migration.html#use-loader-to-get-a-pdf-document
if (sourceFile != null) {
doc = PDDocument.load(sourceFile.toFile(),
getMemoryUsageSetting());
diff --git a/src/main/java/edu/illinois/library/cantaloupe/processor/codec/jpeg/Util.java b/src/main/java/edu/illinois/library/cantaloupe/processor/codec/jpeg/Util.java
index b1fce36b0..c73507dd4 100644
--- a/src/main/java/edu/illinois/library/cantaloupe/processor/codec/jpeg/Util.java
+++ b/src/main/java/edu/illinois/library/cantaloupe/processor/codec/jpeg/Util.java
@@ -6,6 +6,7 @@
import org.apache.jena.rdf.model.ModelFactory;
import org.apache.jena.rdf.model.RDFNode;
import org.apache.jena.rdf.model.StmtIterator;
+import org.apache.jena.riot.RiotException;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
@@ -119,8 +120,18 @@ private static String mergeXMPModels(String standardXMP,
private static Model readModel(String rdfXML) {
Model model = ModelFactory.createDefaultModel();
+ String base = null;
try (StringReader reader = new StringReader(rdfXML)) {
- model.read(reader, null, "RDF/XML");
+ model.read(reader, base, "RDF/XML");
+ } catch (RiotException exception) {
+ if (exception.getMessage().indexOf("Base URI is null, but there are relative URIs to resolve") != -1) {
+ // Version 4.8+ of jena requires a rdf:about link to not be empty
+ try (StringReader reader = new StringReader(rdfXML)) {
+ model.read(reader, "http://example.com", "RDF/XML");
+ }
+ } else {
+ throw exception;
+ }
}
return model;
}
diff --git a/src/main/java/edu/illinois/library/cantaloupe/resource/ImageRequestHandler.java b/src/main/java/edu/illinois/library/cantaloupe/resource/ImageRequestHandler.java
index 57a7b2cf1..31f1cfb6f 100644
--- a/src/main/java/edu/illinois/library/cantaloupe/resource/ImageRequestHandler.java
+++ b/src/main/java/edu/illinois/library/cantaloupe/resource/ImageRequestHandler.java
@@ -398,10 +398,12 @@ public void handle(OutputStream outputStream) throws Exception {
try {
fullSize = info.getSize(operationList.getPageIndex());
requestContext.setMetadata(info.getMetadata());
- operationList.applyNonEndpointMutations(info, delegateProxy);
- operationList.freeze();
requestContext.setOperationList(operationList, fullSize);
requestContext.setPageCount(info.getNumPages());
+ // This must be done *after* the request context is fully
+ // populated, as some of the mutations may depend on it.
+ operationList.applyNonEndpointMutations(info, delegateProxy);
+ operationList.freeze();
} catch (IllegalArgumentException | IndexOutOfBoundsException e) {
throw new IllegalClientArgumentException(e);
}
diff --git a/src/test/java/edu/illinois/library/cantaloupe/cache/AbstractCacheTest.java b/src/test/java/edu/illinois/library/cantaloupe/cache/AbstractCacheTest.java
index f2260977b..8b04f03d6 100644
--- a/src/test/java/edu/illinois/library/cantaloupe/cache/AbstractCacheTest.java
+++ b/src/test/java/edu/illinois/library/cantaloupe/cache/AbstractCacheTest.java
@@ -325,6 +325,9 @@ void testPurge() throws Exception {
// purge everything
instance.purge();
+ // Allow time for purge but not as long as upload
+ Thread.sleep(ASYNC_WAIT / 2);
+
// assert that the info has been purged
assertFalse(instance.getInfo(identifier).isPresent());
diff --git a/src/test/java/edu/illinois/library/cantaloupe/cache/S3CacheTest.java b/src/test/java/edu/illinois/library/cantaloupe/cache/S3CacheTest.java
index 1d534c6c2..6f00ec903 100644
--- a/src/test/java/edu/illinois/library/cantaloupe/cache/S3CacheTest.java
+++ b/src/test/java/edu/illinois/library/cantaloupe/cache/S3CacheTest.java
@@ -317,6 +317,9 @@ void testPurgeWithKeyPrefix() throws Exception {
// purge everything
instance.purge();
+ // Allow some time for the purge to succeed
+ Thread.sleep(ASYNC_WAIT / 2);
+
// assert that the info has been purged
assertFalse(instance.getInfo(identifier).isPresent());
diff --git a/src/test/java/edu/illinois/library/cantaloupe/image/MetadataTest.java b/src/test/java/edu/illinois/library/cantaloupe/image/MetadataTest.java
index 366c9cb77..de3d914f6 100644
--- a/src/test/java/edu/illinois/library/cantaloupe/image/MetadataTest.java
+++ b/src/test/java/edu/illinois/library/cantaloupe/image/MetadataTest.java
@@ -12,6 +12,8 @@
import edu.illinois.library.cantaloupe.test.BaseTest;
import edu.illinois.library.cantaloupe.test.TestUtil;
import org.apache.jena.rdf.model.Model;
+import org.apache.jena.riot.RDFDataMgr;
+import org.apache.jena.riot.RDFFormat;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
@@ -444,7 +446,7 @@ void testToMap() {
expectedMap.put("iptc", List.of(new DataSet(
edu.illinois.library.cantaloupe.image.iptc.Tag.CITY,
"Urbana".getBytes()).toMap()));
- expectedMap.put("xmp_string", "");
+ expectedMap.put("xmp_string", "");
expectedMap.put("xmp_elements", Collections.emptyMap());
expectedMap.put("native", Map.of("key1", "value1", "key2", "value2"));
@@ -464,7 +466,7 @@ void testToMap() {
"Urbana".getBytes()));
instance.setIPTC(iptc);
// XMP
- instance.setXMP("");
+ instance.setXMP("");
// native
instance.setNativeMetadata(Map.of("key1", "value1", "key2", "value2"));
diff --git a/src/test/java/edu/illinois/library/cantaloupe/operation/EncodeTest.java b/src/test/java/edu/illinois/library/cantaloupe/operation/EncodeTest.java
index ee8f5b614..0fc0b9aac 100644
--- a/src/test/java/edu/illinois/library/cantaloupe/operation/EncodeTest.java
+++ b/src/test/java/edu/illinois/library/cantaloupe/operation/EncodeTest.java
@@ -137,7 +137,7 @@ void testToMap() {
instance.setBackgroundColor(Color.BLUE);
instance.setMaxComponentSize(10);
Metadata metadata = new Metadata();
- metadata.setXMP("");
+ metadata.setXMP("");
instance.setMetadata(metadata);
Dimension size = new Dimension(500, 500);
@@ -150,7 +150,7 @@ void testToMap() {
assertTrue((boolean) map.get("interlace"));
assertEquals(50, map.get("quality"));
assertEquals(10, map.get("max_sample_size"));
- assertEquals("",
+ assertEquals("",
((Map) map.get("metadata")).get("xmp_string"));
}
diff --git a/src/test/java/edu/illinois/library/cantaloupe/processor/codec/png/PNGMetadataTest.java b/src/test/java/edu/illinois/library/cantaloupe/processor/codec/png/PNGMetadataTest.java
index cf709ab1a..31ddace80 100644
--- a/src/test/java/edu/illinois/library/cantaloupe/processor/codec/png/PNGMetadataTest.java
+++ b/src/test/java/edu/illinois/library/cantaloupe/processor/codec/png/PNGMetadataTest.java
@@ -45,9 +45,10 @@ void testGetNativeMetadata() throws IOException {
@Test
void testGetXMP() throws IOException {
- final String rdf = getInstance("png-xmp.png").getXMP().orElseThrow();
+ final String fixtureName = "png-xmp.png";
+ final String rdf = getInstance(fixtureName).getXMP().orElseThrow();
final Model model = ModelFactory.createDefaultModel();
- model.read(new StringReader(rdf), null, "RDF/XML");
+ model.read(new StringReader(rdf), "file://" + TestUtil.getImage(fixtureName).getParent().toAbsolutePath(), "RDF/XML");
}
}
diff --git a/src/test/java/edu/illinois/library/cantaloupe/processor/codec/tiff/TIFFMetadataTest.java b/src/test/java/edu/illinois/library/cantaloupe/processor/codec/tiff/TIFFMetadataTest.java
index 7104e06be..132cf7bc9 100644
--- a/src/test/java/edu/illinois/library/cantaloupe/processor/codec/tiff/TIFFMetadataTest.java
+++ b/src/test/java/edu/illinois/library/cantaloupe/processor/codec/tiff/TIFFMetadataTest.java
@@ -4,6 +4,8 @@
import edu.illinois.library.cantaloupe.test.TestUtil;
import org.apache.jena.rdf.model.Model;
import org.apache.jena.rdf.model.ModelFactory;
+import org.apache.jena.riot.RDFDataMgr;
+import org.apache.jena.riot.RDFFormat;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
@@ -80,7 +82,7 @@ void testGetXMP() throws IOException {
try (ImageInputStream is = ImageIO.createImageInputStream(srcFile.toFile())) {
final String rdf = newInstance(is).getXMP().orElseThrow();
final Model model = ModelFactory.createDefaultModel();
- model.read(new StringReader(rdf), null, "RDF/XML");
+ model.read(new StringReader(rdf), "file://" + srcFile.getParent().toAbsolutePath(), "RDF/XML");
}
}
diff --git a/src/test/resources/delegates.rb b/src/test/resources/delegates.rb
index 3ad145081..509ee0dda 100644
--- a/src/test/resources/delegates.rb
+++ b/src/test/resources/delegates.rb
@@ -2,6 +2,7 @@
require 'java'
require 'uri'
+require 'cgi'
class CustomDelegate
@@ -166,11 +167,11 @@ def httpsource_resource_info(options = {})
elsif context['client_ip'] == '1.2.3.4'
if context['request_headers']['X-Forwarded-Proto'] == 'https'
return {
- 'uri' => 'https://other-example.org/bleh/' + URI.escape(identifier)
+ 'uri' => 'https://other-example.org/bleh/' + CGI.escape(identifier)
}
else
return {
- 'uri' => 'http://other-example.org/bleh/' + URI.escape(identifier)
+ 'uri' => 'http://other-example.org/bleh/' + CGI.escape(identifier)
}
end
end
@@ -178,7 +179,7 @@ def httpsource_resource_info(options = {})
case identifier
when 'http-jpg-rgb-64x56x8-baseline.jpg'
return {
- 'uri' => 'http://example.org/bla/' + URI.escape(identifier),
+ 'uri' => 'http://example.org/bla/' + CGI.escape(identifier),
'headers' => {
'X-Custom' => 'yes'
},
@@ -186,7 +187,7 @@ def httpsource_resource_info(options = {})
}
when 'https-jpg-rgb-64x56x8-baseline.jpg'
return {
- 'uri' => 'https://example.org/bla/' + URI.escape(identifier),
+ 'uri' => 'https://example.org/bla/' + CGI.escape(identifier),
'headers' => {
'X-Custom' => 'yes'
},
@@ -194,7 +195,7 @@ def httpsource_resource_info(options = {})
}
when 'http-jpg-rgb-64x56x8-plane.jpg'
return {
- 'uri' => 'http://example.org/bla/' + URI.escape(identifier),
+ 'uri' => 'http://example.org/bla/' + CGI.escape(identifier),
'username' => 'username',
'secret' => 'secret',
'headers' => {
@@ -204,7 +205,7 @@ def httpsource_resource_info(options = {})
}
when 'https-jpg-rgb-64x56x8-plane.jpg'
return {
- 'uri' => 'https://example.org/bla/' + URI.escape(identifier),
+ 'uri' => 'https://example.org/bla/' + CGI.escape(identifier),
'username' => 'username',
'secret' => 'secret',
'headers' => {