Compare commits

...

6 Commits
master ... main

Author SHA1 Message Date
Anthony Stirling
3c7b83ee87 Update survey version cache (#3071)
# Description of Changes

Please provide a summary of the changes, including:

- What was changed
- Why the change was made
- Any challenges encountered

Closes #(issue_number)

---

## Checklist

### General

- [ ] I have read the [Contribution
Guidelines](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/CONTRIBUTING.md)
- [ ] I have read the [Stirling-PDF Developer
Guide](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/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/HowToAddNewLanguage.md)
(if applicable)
- [ ] I have performed a self-review of my own code
- [ ] 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/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/DeveloperGuide.md#6-testing)
for more details.
2025-02-27 10:18:26 +00:00
Ludy
9152e64b9f Remove convertBookTypeToPdf and Improve File Sanitization in FileToPdf (#3072)
# Description of Changes

Please provide a summary of the changes, including:

- **Removed `convertBookTypeToPdf` method**: 
- This method used `ebook-convert` from Calibre, which required external
dependencies.
- Its removal eliminates unnecessary process execution and simplifies
the codebase.
  
- **Enhanced `sanitizeZipFilename` function**:
  - Added handling for drive letters (e.g., `C:\`).
  - Ensured all slashes are normalized to forward slashes.
- Improved recursive path traversal removal to prevent directory escape
vulnerabilities.

- **Refactored `ProcessExecutor` output handling**:
  - Replaced redundant `.size() > 0` checks with `.isEmpty()`.
  
- **Expanded unit tests in `FileToPdfTest`**:
  - Added tests for `sanitizeZipFilename` to cover edge cases.
  - Improved test descriptions and added assertion messages.
  - Added debug print statements for easier test debugging.

---

## 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/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/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/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/DeveloperGuide.md#6-testing)
for more details.
2025-02-26 19:25:35 +00:00
stirlingbot[bot]
96655f7cac Update 3rd Party Licenses (#3070)
Auto-generated by StirlingBot

Signed-off-by: stirlingbot[bot] <1113334+stirlingbot[bot]@users.noreply.github.com>
Co-authored-by: stirlingbot[bot] <195170888+stirlingbot[bot]@users.noreply.github.com>
2025-02-26 16:46:23 +00:00
dependabot[bot]
8f7153b30a Bump ch.qos.logback:logback-classic from 1.5.16 to 1.5.17 (#3069)
Bumps
[ch.qos.logback:logback-classic](https://github.com/qos-ch/logback) from
1.5.16 to 1.5.17.
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/qos-ch/logback/releases">ch.qos.logback:logback-classic's
releases</a>.</em></p>
<blockquote>
<h2>Logback 1.5.17</h2>
<p><strong>2025-02-25 Release of logback version 1.5.17</strong></p>
<p>• Fixed Jansi 2.4.0 color-coded output not working on Windows CMD.exe
console when the default terminal application is set to &quot;Windows
Console Host&quot;. This problem was reported in issues/753 by Michael
Lyubkin.</p>
<p>• Fixed race condition occurring in case MDC class is initialized
while org.slf4j.LoggerFactory is initializing logback-classic's
LoggerContext. When this race conditions occurs, the MDCAdapter instance
used by MDC does not match the instance used by logback-classic. This
issue was reported in SLF4J issues/450. While logback-classic version
1.5.17 remains compatible with SLF4J versions in the 2.0.x series,
fixing this particular MDC issue requires SLF4J version 2.0.17.</p>
<p>• A bit-wise identical binary of this version can be reproduced by
building from source code at commit
10358724ed723b3745c010aa40cb02a2dfed4593 associated with the tag
v_1.5.17. Release built using Java &quot;21&quot; 2023-10-17 LTS build
21.0.1.+12-LTS-29 under Linux Debian 11.6.</p>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="10358724ed"><code>1035872</code></a>
prepare release 1.5.17</li>
<li><a
href="2e6984d1e1"><code>2e6984d</code></a>
bump to slf4j version 2.0.17</li>
<li><a
href="100995244b"><code>1009952</code></a>
use a new LoggerContert instance when running LogbackListenerTest. This
shoul...</li>
<li><a
href="a3bb4b096a"><code>a3bb4b0</code></a>
Merge branch 'master' of github.com:qos-ch/logback</li>
<li><a
href="b507297eaa"><code>b507297</code></a>
Fixed race condition occurring in case MDC class is initialized while
org.slf...</li>
<li><a
href="f5b3bc56cd"><code>f5b3bc5</code></a>
add warning about the deprecation of SerializedModelConfigurator if
activated</li>
<li><a
href="5bc0998ce1"><code>5bc0998</code></a>
Update README.md</li>
<li><a
href="5610c96b4d"><code>5610c96</code></a>
correct relocation address</li>
<li><a
href="f3d100b89d"><code>f3d100b</code></a>
update logback-access evaluator examples</li>
<li><a
href="51e390303e"><code>51e3903</code></a>
fix issues/753 for the second time</li>
<li>Additional commits viewable in <a
href="https://github.com/qos-ch/logback/compare/v_1.5.16...v_1.5.17">compare
view</a></li>
</ul>
</details>
<br />


[![Dependabot compatibility
score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=ch.qos.logback:logback-classic&package-manager=gradle&previous-version=1.5.16&new-version=1.5.17)](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>
2025-02-26 16:23:09 +00:00
dependabot[bot]
366bec602d Bump ch.qos.logback:logback-core from 1.5.16 to 1.5.17 (#3068)
Bumps [ch.qos.logback:logback-core](https://github.com/qos-ch/logback)
from 1.5.16 to 1.5.17.
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/qos-ch/logback/releases">ch.qos.logback:logback-core's
releases</a>.</em></p>
<blockquote>
<h2>Logback 1.5.17</h2>
<p><strong>2025-02-25 Release of logback version 1.5.17</strong></p>
<p>• Fixed Jansi 2.4.0 color-coded output not working on Windows CMD.exe
console when the default terminal application is set to &quot;Windows
Console Host&quot;. This problem was reported in issues/753 by Michael
Lyubkin.</p>
<p>• Fixed race condition occurring in case MDC class is initialized
while org.slf4j.LoggerFactory is initializing logback-classic's
LoggerContext. When this race conditions occurs, the MDCAdapter instance
used by MDC does not match the instance used by logback-classic. This
issue was reported in SLF4J issues/450. While logback-classic version
1.5.17 remains compatible with SLF4J versions in the 2.0.x series,
fixing this particular MDC issue requires SLF4J version 2.0.17.</p>
<p>• A bit-wise identical binary of this version can be reproduced by
building from source code at commit
10358724ed723b3745c010aa40cb02a2dfed4593 associated with the tag
v_1.5.17. Release built using Java &quot;21&quot; 2023-10-17 LTS build
21.0.1.+12-LTS-29 under Linux Debian 11.6.</p>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="10358724ed"><code>1035872</code></a>
prepare release 1.5.17</li>
<li><a
href="2e6984d1e1"><code>2e6984d</code></a>
bump to slf4j version 2.0.17</li>
<li><a
href="100995244b"><code>1009952</code></a>
use a new LoggerContert instance when running LogbackListenerTest. This
shoul...</li>
<li><a
href="a3bb4b096a"><code>a3bb4b0</code></a>
Merge branch 'master' of github.com:qos-ch/logback</li>
<li><a
href="b507297eaa"><code>b507297</code></a>
Fixed race condition occurring in case MDC class is initialized while
org.slf...</li>
<li><a
href="f5b3bc56cd"><code>f5b3bc5</code></a>
add warning about the deprecation of SerializedModelConfigurator if
activated</li>
<li><a
href="5bc0998ce1"><code>5bc0998</code></a>
Update README.md</li>
<li><a
href="5610c96b4d"><code>5610c96</code></a>
correct relocation address</li>
<li><a
href="f3d100b89d"><code>f3d100b</code></a>
update logback-access evaluator examples</li>
<li><a
href="51e390303e"><code>51e3903</code></a>
fix issues/753 for the second time</li>
<li>Additional commits viewable in <a
href="https://github.com/qos-ch/logback/compare/v_1.5.16...v_1.5.17">compare
view</a></li>
</ul>
</details>
<br />


[![Dependabot compatibility
score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=ch.qos.logback:logback-core&package-manager=gradle&previous-version=1.5.16&new-version=1.5.17)](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>
2025-02-26 15:56:35 +00:00
Ludy
c9c8378fe0 Improve Case-Insensitive Key Comparison and Path Normalization in Language Properties Check Script (#3067)
# Description of Changes

Please provide a summary of the changes, including:

- Updated key comparison logic in `update_missing_keys` function to be
case-insensitive by converting keys to lowercase before comparison.
- Introduced `os.path.normpath` for file path normalization to improve
cross-platform compatibility.
- Replaced direct usage of `file_path` with `file_normpath` in security
checks, file size validation, and duplicate key detection to ensure
consistent path handling.

These changes improve the robustness and maintainability of the script,
ensuring more accurate language property checks while enhancing security
validation.

---

## Checklist

### General

- [ ] I have read the [Contribution
Guidelines](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/CONTRIBUTING.md)
- [ ] I have read the [Stirling-PDF Developer
Guide](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/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/HowToAddNewLanguage.md)
(if applicable)
- [ ] I have performed a self-review of my own code
- [ ] 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/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/DeveloperGuide.md#6-testing)
for more details.
2025-02-26 15:56:03 +00:00
7 changed files with 96 additions and 68 deletions

View File

@@ -164,7 +164,7 @@ def update_missing_keys(reference_file, file_list, branch=""):
if current_entry["type"] == "entry":
if ref_entry_copy["type"] != "entry":
continue
if ref_entry_copy["key"] == current_entry["key"]:
if ref_entry_copy["key"].lower() == current_entry["key"].lower():
ref_entry_copy["value"] = current_entry["value"]
updated_properties.append(ref_entry_copy)
write_json_file(os.path.join(branch, file_path), updated_properties)
@@ -199,29 +199,30 @@ def check_for_differences(reference_file, file_list, branch, actor):
base_dir = os.path.abspath(os.path.join(os.getcwd(), "src", "main", "resources"))
for file_path in file_arr:
absolute_path = os.path.abspath(file_path)
file_normpath = os.path.normpath(file_path)
absolute_path = os.path.abspath(file_normpath)
# Verify that file is within the expected directory
if not absolute_path.startswith(base_dir):
raise ValueError(f"Unsafe file found: {file_path}")
raise ValueError(f"Unsafe file found: {file_normpath}")
# Verify file size before processing
if os.path.getsize(os.path.join(branch, file_path)) > MAX_FILE_SIZE:
if os.path.getsize(os.path.join(branch, file_normpath)) > MAX_FILE_SIZE:
raise ValueError(
f"The file {file_path} is too large and could pose a security risk."
f"The file {file_normpath} is too large and could pose a security risk."
)
basename_current_file = os.path.basename(os.path.join(branch, file_path))
basename_current_file = os.path.basename(os.path.join(branch, file_normpath))
if (
basename_current_file == basename_reference_file
or (
# only local windows command
not file_path.startswith(
not file_normpath.startswith(
os.path.join("", "src", "main", "resources", "messages_")
)
and not file_path.startswith(
and not file_normpath.startswith(
os.path.join(os.getcwd(), "src", "main", "resources", "messages_")
)
)
or not file_path.endswith(".properties")
or not file_normpath.endswith(".properties")
or not basename_current_file.startswith("messages_")
):
continue
@@ -292,13 +293,13 @@ def check_for_differences(reference_file, file_list, branch, actor):
else:
report.append("2. **Test Status:** ✅ **_Passed_**")
if find_duplicate_keys(os.path.join(branch, file_path)):
if find_duplicate_keys(os.path.join(branch, file_normpath)):
has_differences = True
output = "\n".join(
[
f" - `{key}`: first at line {first}, duplicate at `line {duplicate}`"
for key, first, duplicate in find_duplicate_keys(
os.path.join(branch, file_path)
os.path.join(branch, file_normpath)
)
]
)

View File

@@ -294,8 +294,8 @@ configurations.all {
dependencies {
//tmp for security bumps
implementation 'ch.qos.logback:logback-core:1.5.16'
implementation 'ch.qos.logback:logback-classic:1.5.16'
implementation 'ch.qos.logback:logback-core:1.5.17'
implementation 'ch.qos.logback:logback-classic:1.5.17'
// Exclude vulnerable BouncyCastle version used in tableau

View File

@@ -169,7 +169,7 @@ public class FileToPdf {
}
}
// search for the main HTML file.
// Search for the main HTML file.
try (Stream<Path> walk = Files.walk(tempDirectory)) {
List<Path> htmlFiles =
walk.filter(file -> file.toString().endsWith(".html"))
@@ -190,46 +190,20 @@ public class FileToPdf {
}
}
public static byte[] convertBookTypeToPdf(byte[] bytes, String originalFilename)
throws IOException, InterruptedException {
if (originalFilename == null || originalFilename.lastIndexOf('.') == -1) {
throw new IllegalArgumentException("Invalid original filename.");
}
String fileExtension = originalFilename.substring(originalFilename.lastIndexOf('.'));
List<String> command = new ArrayList<>();
Path tempOutputFile = Files.createTempFile("output_", ".pdf");
Path tempInputFile = null;
try {
// Create temp file with appropriate extension
tempInputFile = Files.createTempFile("input_", fileExtension);
Files.write(tempInputFile, bytes);
command.add("ebook-convert");
command.add(tempInputFile.toString());
command.add(tempOutputFile.toString());
ProcessExecutorResult returnCode =
ProcessExecutor.getInstance(ProcessExecutor.Processes.CALIBRE)
.runCommandWithOutputHandling(command);
return Files.readAllBytes(tempOutputFile);
} finally {
// Clean up temporary files
if (tempInputFile != null) {
Files.deleteIfExists(tempInputFile);
}
Files.deleteIfExists(tempOutputFile);
}
}
static String sanitizeZipFilename(String entryName) {
if (entryName == null || entryName.trim().isEmpty()) {
return entryName;
return "";
}
// Remove any drive letters (e.g., "C:\") and leading forward/backslashes
entryName = entryName.replaceAll("^[a-zA-Z]:[\\\\/]+", "");
entryName = entryName.replaceAll("^[\\\\/]+", "");
// Recursively remove path traversal sequences
while (entryName.contains("../") || entryName.contains("..\\")) {
entryName = entryName.replace("../", "").replace("..\\", "");
}
// Normalize all backslashes to forward slashes
entryName = entryName.replaceAll("\\\\", "/");
return entryName;
}
}

View File

@@ -1,6 +1,10 @@
package stirling.software.SPDF.utils;
import java.io.*;
import java.io.BufferedReader;
import java.io.File;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.InterruptedIOException;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.List;
@@ -222,7 +226,7 @@ public class ProcessExecutor {
boolean isQpdf =
command != null && !command.isEmpty() && command.get(0).contains("qpdf");
if (outputLines.size() > 0) {
if (!outputLines.isEmpty()) {
String outputMessage = String.join("\n", outputLines);
messages += outputMessage;
if (!liveUpdates) {
@@ -230,7 +234,7 @@ public class ProcessExecutor {
}
}
if (errorLines.size() > 0) {
if (!errorLines.isEmpty()) {
String errorMessage = String.join("\n", errorLines);
messages += errorMessage;
if (!liveUpdates) {

View File

@@ -3,14 +3,14 @@
{
"moduleName": "ch.qos.logback:logback-classic",
"moduleUrl": "http://www.qos.ch",
"moduleVersion": "1.5.16",
"moduleVersion": "1.5.17",
"moduleLicense": "GNU Lesser General Public License",
"moduleLicenseUrl": "http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html"
},
{
"moduleName": "ch.qos.logback:logback-core",
"moduleUrl": "http://www.qos.ch",
"moduleVersion": "1.5.16",
"moduleVersion": "1.5.17",
"moduleLicense": "GNU Lesser General Public License",
"moduleLicenseUrl": "http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html"
},

View File

@@ -51,6 +51,7 @@ document.addEventListener('DOMContentLoaded', function () {
const storedVersion = localStorage.getItem('surveyVersion');
if (storedVersion && storedVersion !== surveyVersion) {
localStorage.setItem('pageViews', '0');
localStorage.setItem('surveyVersion', surveyVersion));
}
let pageViews = parseInt(localStorage.getItem('pageViews') || '0');

View File

@@ -5,31 +5,79 @@ import stirling.software.SPDF.model.api.converters.HTMLToPdfRequest;
import java.io.IOException;
import static org.junit.jupiter.api.Assertions.assertThrows;
import static org.junit.jupiter.api.Assertions.*;
public class FileToPdfTest {
/**
* Test the HTML to PDF conversion.
* This test expects an IOException when an empty HTML input is provided.
*/
@Test
public void testConvertHtmlToPdf() {
HTMLToPdfRequest request = new HTMLToPdfRequest();
byte[] fileBytes = new byte[0]; // Sample file bytes
String fileName = "test.html"; // Sample file name
boolean disableSanitize = false; // Sample boolean value
byte[] fileBytes = new byte[0]; // Sample file bytes (empty input)
String fileName = "test.html"; // Sample file name indicating an HTML file
boolean disableSanitize = false; // Flag to control sanitization
// Check if the method throws IOException
assertThrows(IOException.class, () -> {
FileToPdf.convertHtmlToPdf("/path/",request, fileBytes, fileName, disableSanitize);
});
// Expect an IOException to be thrown due to empty input
Throwable thrown =
assertThrows(
IOException.class,
() ->
FileToPdf.convertHtmlToPdf(
"/path/", request, fileBytes, fileName, disableSanitize));
assertNotNull(thrown);
}
/**
* Test sanitizeZipFilename with null or empty input.
* It should return an empty string in these cases.
*/
@Test
public void testConvertBookTypeToPdf() {
byte[] bytes = new byte[10]; // Sample bytes
String originalFilename = "test.epub"; // Sample original filename
public void testSanitizeZipFilename_NullOrEmpty() {
assertEquals("", FileToPdf.sanitizeZipFilename(null));
assertEquals("", FileToPdf.sanitizeZipFilename(" "));
}
// Check if the method throws IOException
assertThrows(IOException.class, () -> {
FileToPdf.convertBookTypeToPdf(bytes, originalFilename);
});
/**
* Test sanitizeZipFilename to ensure it removes path traversal sequences.
* This includes removing both forward and backward slash sequences.
*/
@Test
public void testSanitizeZipFilename_RemovesTraversalSequences() {
String input = "../some/../path/..\\to\\file.txt";
String expected = "some/path/to/file.txt";
// Print output for debugging purposes
System.out.println("sanitizeZipFilename " + FileToPdf.sanitizeZipFilename(input));
System.out.flush();
// Expect that the method replaces backslashes with forward slashes
// and removes path traversal sequences
assertEquals(expected, FileToPdf.sanitizeZipFilename(input));
}
/**
* Test sanitizeZipFilename to ensure that it removes leading drive letters and slashes.
*/
@Test
public void testSanitizeZipFilename_RemovesLeadingDriveAndSlashes() {
String input = "C:\\folder\\file.txt";
String expected = "folder/file.txt";
assertEquals(expected, FileToPdf.sanitizeZipFilename(input));
input = "/folder/file.txt";
expected = "folder/file.txt";
assertEquals(expected, FileToPdf.sanitizeZipFilename(input));
}
/**
* Test sanitizeZipFilename to verify that safe filenames remain unchanged.
*/
@Test
public void testSanitizeZipFilename_NoChangeForSafeNames() {
String input = "folder/subfolder/file.txt";
assertEquals(input, FileToPdf.sanitizeZipFilename(input));
}
}