This fixes a failing unit test on macOS.
`ApplicationPropertiesLogicTest.tempFileManagement_defaults_and_overrides()`
has 4 asserts that will fail with this error on macOS:
```
org.opentest4j.AssertionFailedError: expected: </var/folders/6d/12xt4b4m8xjf3t0059_w18bh0000gn/T/stirling-pdf> but was: </var/folders/6d/12xt4b4m8xjf3t0059_w18bh0000gn/T//stirling-pdf>
at app//org.junit.jupiter.api.AssertionFailureBuilder.build(AssertionFailureBuilder.java:151)
at app//org.junit.jupiter.api.AssertionFailureBuilder.buildAndThrow(AssertionFailureBuilder.java:132)
at app//org.junit.jupiter.api.AssertEquals.failNotEqual(AssertEquals.java:197)
at app//org.junit.jupiter.api.AssertEquals.assertEquals(AssertEquals.java:182)
at app//org.junit.jupiter.api.AssertEquals.assertEquals(AssertEquals.java:177)
at app//org.junit.jupiter.api.Assertions.assertEquals(Assertions.java:1145)
at app//stirling.software.common.model.ApplicationPropertiesLogicTest.tempFileManagement_defaults_and_overrides(ApplicationPropertiesLogicTest.java:40)
at java.base@24.0.2/java.lang.reflect.Method.invoke(Method.java:565)
at java.base@24.0.2/java.util.ArrayList.forEach(ArrayList.java:1604)
at java.base@24.0.2/java.util.ArrayList.forEach(ArrayList.java:1604)
```
Note the double `/` in the actual path here: `/T//stirling-pdf`.
# Description of Changes
The fix creates a lambda:
```
Function<String, String> normalize = s ->Paths.get(s).normalize().toString();
```
and applies it in all 4 broken tests.
## Checklist
### General
- [x] I have read the [Contribution
Guidelines](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/CONTRIBUTING.md)
- [x] I have read the [Stirling-PDF Developer
Guide](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/devGuide/DeveloperGuide.md)
(if applicable)
- [ ] I have read the [How to add new languages to
Stirling-PDF](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/devGuide/HowToAddNewLanguage.md)
(if applicable)
- [x] I have performed a self-review of my own code
- [x] My changes generate no new warnings
### Documentation
- [ ] I have updated relevant docs on [Stirling-PDF's doc
repo](https://github.com/Stirling-Tools/Stirling-Tools.github.io/blob/main/docs/)
(if functionality has heavily changed)
- [ ] I have read the section [Add New Translation
Tags](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/devGuide/HowToAddNewLanguage.md#add-new-translation-tags)
(for new translation tags only)
### UI Changes (if applicable)
- [ ] Screenshots or videos demonstrating the UI changes are attached
(e.g., as comments or direct attachments in the PR)
### Testing (if applicable)
- [x] I have tested my changes locally. Refer to the [Testing
Guide](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/devGuide/DeveloperGuide.md#6-testing)
for more details.
Bumps
[jakarta.mail:jakarta.mail-api](https://github.com/jakartaee/mail-api)
from 2.1.3 to 2.1.4.
<details>
<summary>Commits</summary>
<ul>
<li><a
href="0d13f04450"><code>0d13f04</code></a>
Prepare release jakarta.mail:jakarta.mail-api:2.1.4</li>
<li><a
href="958fb97ab1"><code>958fb97</code></a>
services/jakarta.mail.Provider override not working <a
href="https://redirect.github.com/jakartaee/mail-api/issues/777">#777</a>
(<a
href="https://redirect.github.com/jakartaee/mail-api/issues/779">#779</a>)</li>
<li><a
href="3446c94241"><code>3446c94</code></a>
services/jakarta.mail.Provider override not working <a
href="https://redirect.github.com/jakartaee/mail-api/issues/170">#170</a>
(<a
href="https://redirect.github.com/jakartaee/mail-api/issues/778">#778</a>)</li>
<li><a
href="892fae4ac7"><code>892fae4</code></a>
Multipart performs blocking call in every instantiation <a
href="https://redirect.github.com/jakartaee/mail-api/issues/699">#699</a>
(<a
href="https://redirect.github.com/jakartaee/mail-api/issues/716">#716</a>)</li>
<li><a
href="666ec999d8"><code>666ec99</code></a>
Bump rexml from 3.2.8 to 3.3.6 in /www</li>
<li><a
href="8eddc342b1"><code>8eddc34</code></a>
Bump rexml from 3.2.5 to 3.2.8 in /www</li>
<li><a
href="1259b86a8c"><code>1259b86</code></a>
Bump nokogiri from 1.16.2 to 1.16.5 in /www</li>
<li><a
href="bf2bfc18c0"><code>bf2bfc1</code></a>
Update README.md</li>
<li><a
href="038fa7038a"><code>038fa70</code></a>
Prepare next development cycle for 2.1.4-SNAPSHOT</li>
<li><a
href="1e52027546"><code>1e52027</code></a>
Prepare release jakarta.mail:jakarta.mail-api:2.1.3</li>
<li>See full diff in <a
href="https://github.com/jakartaee/mail-api/compare/2.1.3...2.1.4">compare
view</a></li>
</ul>
</details>
<br />
[](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores)
Dependabot will resolve any conflicts with this PR as long as you don't
alter it yourself. You can also trigger a rebase manually by commenting
`@dependabot rebase`.
[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)
---
<details>
<summary>Dependabot commands and options</summary>
<br />
You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits
that have been made to it
- `@dependabot merge` will merge this PR after your CI passes on it
- `@dependabot squash and merge` will squash and merge this PR after
your CI passes on it
- `@dependabot cancel merge` will cancel a previously requested merge
and block automerging
- `@dependabot reopen` will reopen this PR if it is closed
- `@dependabot close` will close this PR and stop Dependabot recreating
it. You can achieve the same result by closing it manually
- `@dependabot show <dependency name> ignore conditions` will show all
of the ignore conditions of the specified dependency
- `@dependabot ignore this major version` will close this PR and stop
Dependabot creating any more for this major version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this minor version` will close this PR and stop
Dependabot creating any more for this minor version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this dependency` will close this PR and stop
Dependabot creating any more for this dependency (unless you reopen the
PR or upgrade to it yourself)
</details>
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
# Description of Changes
- **What was changed**
- Reworked `ConvertOfficeController` to use a dedicated temporary
working directory per request and cleaned up with directory-level
deletion.
- Added detection for converter availability via `EndpointConfiguration`
to choose between **unoconvert** and a **soffice** headless fallback.
- Ensured safe filename handling (sanitization, extension checks,
lowercase normalization) and early validation errors for missing/invalid
filenames.
- Switched raw temp file writes to `Files.copy` / `Files.writeString`
with `StandardCopyOption.REPLACE_EXISTING`.
- Implemented robust output handling:
- Verified non-zero exit codes and null results.
- Checked for missing/empty PDF outputs.
- Added fallback lookup for any produced `.pdf` within the work
directory if the expected name is not present.
- Introduced `@Slf4j` logging; improved error and cleanup logging.
- Replaced ad-hoc temp cleanup with `FileUtils.deleteDirectory` for full
working-dir removal.
- Minor imports/cleanup: removed unused `Arrays`, added
`StandardCopyOption`, `FileUtils`, and related imports.
- **Why the change was made**
- Increase conversion reliability across environments where either
unoconvert or soffice may be available.
- Harden security and stability through strict input validation and
sanitized HTML processing.
- Prevent orphaned files/directories and ensure consistent cleanup to
reduce disk footprint and operational issues.
- Provide clearer operational signals (logging, explicit exceptions) for
easier troubleshooting.
---
## Checklist
### General
- [x] I have read the [Contribution
Guidelines](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/CONTRIBUTING.md)
- [x] I have read the [Stirling-PDF Developer
Guide](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/devGuide/DeveloperGuide.md)
(if applicable)
- [ ] I have read the [How to add new languages to
Stirling-PDF](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/devGuide/HowToAddNewLanguage.md)
(if applicable)
- [x] I have performed a self-review of my own code
- [x] My changes generate no new warnings
### Documentation
- [ ] I have updated relevant docs on [Stirling-PDF's doc
repo](https://github.com/Stirling-Tools/Stirling-Tools.github.io/blob/main/docs/)
(if functionality has heavily changed)
- [ ] I have read the section [Add New Translation
Tags](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/devGuide/HowToAddNewLanguage.md#add-new-translation-tags)
(for new translation tags only)
### UI Changes (if applicable)
- [ ] Screenshots or videos demonstrating the UI changes are attached
(e.g., as comments or direct attachments in the PR)
### Testing (if applicable)
- [ ] I have tested my changes locally. Refer to the [Testing
Guide](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/devGuide/DeveloperGuide.md#6-testing)
for more details.
# Description of Changes
- **What was changed**
- Added a Spring `@InitBinder` in `StampController` that registers a
`PropertyEditorSupport` for `MultipartFile` to safely handle text inputs
by setting the value to `null`.
- Replaced multiple `switch` statements with modern Java **switch
expressions**:
- Margin selection (`customMargin`) now uses a concise expression.
- Font selection (`alphabet` → font resource path) rewritten as an
expression.
- Position calculations (`calculatePositionX` / `calculatePositionY`)
now return via switch expressions with `yield`.
- Minor readability and maintainability improvements without changing
public API or behavior (besides the binding fix).
- **Why the change was made**
- The `@InitBinder` prevents conversion/binding issues when Spring
attempts to map string form fields to `MultipartFile`, which could cause
exceptions or unexpected behavior in multipart/form-data requests.
- Using switch expressions reduces boilerplate, clarifies intent, and
makes the control flow safer and more maintainable.
---
## Checklist
### General
- [x] I have read the [Contribution
Guidelines](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/CONTRIBUTING.md)
- [x] I have read the [Stirling-PDF Developer
Guide](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/devGuide/DeveloperGuide.md)
(if applicable)
- [ ] I have read the [How to add new languages to
Stirling-PDF](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/devGuide/HowToAddNewLanguage.md)
(if applicable)
- [x] I have performed a self-review of my own code
- [x] My changes generate no new warnings
### Documentation
- [ ] I have updated relevant docs on [Stirling-PDF's doc
repo](https://github.com/Stirling-Tools/Stirling-Tools.github.io/blob/main/docs/)
(if functionality has heavily changed)
- [ ] I have read the section [Add New Translation
Tags](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/devGuide/HowToAddNewLanguage.md#add-new-translation-tags)
(for new translation tags only)
### UI Changes (if applicable)
- [ ] Screenshots or videos demonstrating the UI changes are attached
(e.g., as comments or direct attachments in the PR)
### Testing (if applicable)
- [ ] I have tested my changes locally. Refer to the [Testing
Guide](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/devGuide/DeveloperGuide.md#6-testing)
for more details.
### Description of Changes
This Pull Request was automatically generated to synchronize updates to
translation files and documentation. Below are the details of the
changes made:
#### **1. Synchronization of Translation Files**
- Updated translation files (`messages_*.properties`) to reflect changes
in the reference file `messages_en_GB.properties`.
- Ensured consistency and synchronization across all supported language
files.
- Highlighted any missing or incomplete translations.
#### **2. Update README.md**
- Generated the translation progress table in `README.md`.
- Added a summary of the current translation status for all supported
languages.
- Included up-to-date statistics on translation coverage.
#### **Why these changes are necessary**
- Keeps translation files aligned with the latest reference updates.
- Ensures the documentation reflects the current translation progress.
---
Auto-generated by [create-pull-request][1].
[1]: https://github.com/peter-evans/create-pull-request
---------
Co-authored-by: stirlingbot[bot] <195170888+stirlingbot[bot]@users.noreply.github.com>
# Description of Changes
- **What was changed**
- **URL to PDF flow**
- Changed `ConvertWebsiteToPDF#urlToPdf` to return `ResponseEntity<?>`
and perform a redirect (`303 SEE_OTHER`) back to `/url-to-pdf` with an
`error` query param instead of throwing exceptions.
- Added alert rendering in `url-to-pdf.html` using `param.error` for
localized error display.
- Introduced new translation key `error.invalidUrlFormat` in
`messages_en_GB.properties`.
- **Security / SSRF**
- Migrated `ApplicationProperties.System.UrlSecurity.level` from
`String` to `SsrfProtectionLevel` enum.
- Default now set to `SsrfProtectionLevel.MEDIUM` (`// MAX, MEDIUM,
OFF`).
- This avoids the issue where setting `OFF` returned `false` in
configuration parsing.
- Updated `SsrfProtectionService#parseProtectionLevel` accordingly
(using `level.name()`).
- **Repo hygiene**
- Added `**/LOCAL_APPDATA_FONTCONFIG_CACHE/**` to `.gitignore`.
- **Why the change was made**
- Provide user-friendly, localized error messages instead of exposing
internal exceptions on URL-to-PDF conversions.
- Ensure SSRF protection level parsing is type-safe and consistent—`OFF`
can now be set without yielding a misleading `false` state.
- Prevent unwanted fontconfig cache files from being tracked in Git.
---
## Checklist
### General
- [x] I have read the [Contribution
Guidelines](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/CONTRIBUTING.md)
- [x] I have read the [Stirling-PDF Developer
Guide](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/devGuide/DeveloperGuide.md)
(if applicable)
- [ ] I have read the [How to add new languages to
Stirling-PDF](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/devGuide/HowToAddNewLanguage.md)
(if applicable)
- [x] I have performed a self-review of my own code
- [x] My changes generate no new warnings
### Documentation
- [ ] I have updated relevant docs on [Stirling-PDF's doc
repo](https://github.com/Stirling-Tools/Stirling-Tools.github.io/blob/main/docs/)
(if functionality has heavily changed)
- [ ] I have read the section [Add New Translation
Tags](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/devGuide/HowToAddNewLanguage.md#add-new-translation-tags)
(for new translation tags only)
### UI Changes (if applicable)
- [ ] Screenshots or videos demonstrating the UI changes are attached
(e.g., as comments or direct attachments in the PR)
### Testing (if applicable)
- [ ] I have tested my changes locally. Refer to the [Testing
Guide](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/devGuide/DeveloperGuide.md#6-testing)
for more details.
### Description of Changes
This Pull Request was automatically generated to synchronize updates to
translation files and documentation. Below are the details of the
changes made:
#### **1. Synchronization of Translation Files**
- Updated translation files (`messages_*.properties`) to reflect changes
in the reference file `messages_en_GB.properties`.
- Ensured consistency and synchronization across all supported language
files.
- Highlighted any missing or incomplete translations.
#### **2. Update README.md**
- Generated the translation progress table in `README.md`.
- Added a summary of the current translation status for all supported
languages.
- Included up-to-date statistics on translation coverage.
#### **Why these changes are necessary**
- Keeps translation files aligned with the latest reference updates.
- Ensures the documentation reflects the current translation progress.
---
Auto-generated by [create-pull-request][1].
[1]: https://github.com/peter-evans/create-pull-request
---------
Co-authored-by: stirlingbot[bot] <195170888+stirlingbot[bot]@users.noreply.github.com>
## Summary
- add optional flag to include PDF annotations when converting to images
- expose annotation option via API model and UI checkbox
- add translation for annotation option
## Testing
- `./gradlew spotlessApply`
- `./gradlew build`
------
https://chatgpt.com/codex/tasks/task_b_68b7fa1d5a1c83288342244a0ec85e9d
Bumps
[org.springdoc:springdoc-openapi-starter-webmvc-ui](https://github.com/springdoc/springdoc-openapi)
from 2.8.11 to 2.8.12.
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/springdoc/springdoc-openapi/releases">org.springdoc:springdoc-openapi-starter-webmvc-ui's
releases</a>.</em></p>
<blockquote>
<h2>springdoc-openapi v2.8.12 released!</h2>
<h3>Changed</h3>
<ul>
<li>Upgrade swagger-ui to v5.28.0</li>
<li>Upgrade commons-lang3 to v3.18.0</li>
</ul>
<h3>Fixed</h3>
<ul>
<li><a
href="https://redirect.github.com/springdoc/springdoc-openapi/issues/3073">#3073</a>
- Duplicate key class Parameter when documenting two GET methods with
same path and PathVariable.</li>
<li><a
href="https://redirect.github.com/springdoc/springdoc-openapi/issues/3071">#3071</a>
- <a
href="https://github.com/io"><code>@io</code></a>.swagger.v3.oas.annotations.parameters.RequestBody
does not work well with <a
href="https://github.com/RequestPart"><code>@RequestPart</code></a></li>
<li><a
href="https://redirect.github.com/springdoc/springdoc-openapi/issues/3066">#3066</a>
- Parameter is now required after upgrading to springdoc-openapi
2.8.10</li>
</ul>
<p><strong>Full Changelog</strong>: <a
href="https://github.com/springdoc/springdoc-openapi/compare/v2.8.11...v2.8.12">https://github.com/springdoc/springdoc-openapi/compare/v2.8.11...v2.8.12</a></p>
</blockquote>
</details>
<details>
<summary>Changelog</summary>
<p><em>Sourced from <a
href="https://github.com/springdoc/springdoc-openapi/blob/main/CHANGELOG.md">org.springdoc:springdoc-openapi-starter-webmvc-ui's
changelog</a>.</em></p>
<blockquote>
<h2>[2.8.12] - 2025-09-01</h2>
<h3>Changed</h3>
<ul>
<li>Upgrade swagger-ui to v5.28.0</li>
<li>Upgrade commons-lang3 to v3.18.0</li>
</ul>
<h3>Fixed</h3>
<ul>
<li><a
href="https://redirect.github.com/springdoc/springdoc-openapi/issues/3073">#3073</a>
- Duplicate key class Parameter when documenting two GET methods with
same path and PathVariable.</li>
<li><a
href="https://redirect.github.com/springdoc/springdoc-openapi/issues/3071">#3071</a>
- <a
href="https://github.com/io"><code>@io</code></a>.swagger.v3.oas.annotations.parameters.RequestBody
does not work well with <a
href="https://github.com/RequestPart"><code>@RequestPart</code></a></li>
<li><a
href="https://redirect.github.com/springdoc/springdoc-openapi/issues/3066">#3066</a>
- Parameter is now required after upgrading to springdoc-openapi
2.8.10</li>
</ul>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="493cc68492"><code>493cc68</code></a>
[maven-release-plugin] prepare release v2.8.12</li>
<li><a
href="8ef9eb8199"><code>8ef9eb8</code></a>
CHANGELOG.md update</li>
<li><a
href="bc4ba682eb"><code>bc4ba68</code></a>
upgrade commons-lang3 to v3.18.0</li>
<li><a
href="8741823941"><code>8741823</code></a>
upgrade swagger-ui to v5.28.0</li>
<li><a
href="8d85e0e445"><code>8d85e0e</code></a>
Duplicate key class Parameter when documenting two GET methods with same
path...</li>
<li><a
href="4d505d62dd"><code>4d505d6</code></a>
<a
href="https://github.com/io"><code>@io</code></a>.swagger.v3.oas.annotations.parameters.RequestBody
does not work well with...</li>
<li><a
href="3190ae2c7f"><code>3190ae2</code></a>
Parameter is now required after upgrading to springdoc-openapi 2.8.10.
Fixes ...</li>
<li><a
href="74dcd4f845"><code>74dcd4f</code></a>
[maven-release-plugin] prepare for next development iteration</li>
<li>See full diff in <a
href="https://github.com/springdoc/springdoc-openapi/compare/v2.8.11...v2.8.12">compare
view</a></li>
</ul>
</details>
<br />
[](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores)
Dependabot will resolve any conflicts with this PR as long as you don't
alter it yourself. You can also trigger a rebase manually by commenting
`@dependabot rebase`.
[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)
---
<details>
<summary>Dependabot commands and options</summary>
<br />
You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits
that have been made to it
- `@dependabot merge` will merge this PR after your CI passes on it
- `@dependabot squash and merge` will squash and merge this PR after
your CI passes on it
- `@dependabot cancel merge` will cancel a previously requested merge
and block automerging
- `@dependabot reopen` will reopen this PR if it is closed
- `@dependabot close` will close this PR and stop Dependabot recreating
it. You can achieve the same result by closing it manually
- `@dependabot show <dependency name> ignore conditions` will show all
of the ignore conditions of the specified dependency
- `@dependabot ignore this major version` will close this PR and stop
Dependabot creating any more for this major version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this minor version` will close this PR and stop
Dependabot creating any more for this minor version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this dependency` will close this PR and stop
Dependabot creating any more for this dependency (unless you reopen the
PR or upgrade to it yourself)
</details>
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>