utf8Fix
This commit is contained in:
@@ -242,6 +242,42 @@ public class GeneralUtils {
|
||||
return safeName;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sanitizes a filename to ASCII-safe characters for use with external processes. Replaces
|
||||
* non-ASCII characters and special characters with underscores to prevent InvalidPathException
|
||||
* and encoding issues when filenames are passed to external programs like LibreOffice,
|
||||
* Ghostscript, etc.
|
||||
*
|
||||
* <p>This method is specifically designed for temporary filenames used in ProcessExecutor calls
|
||||
* where non-ASCII characters (e.g., Polish "ł", Chinese characters, etc.) can cause path
|
||||
* encoding issues.
|
||||
*
|
||||
* @param filename the filename to sanitize, may be null
|
||||
* @return ASCII-safe filename with only alphanumeric, dot, dash, and underscore characters, or
|
||||
* "file" if input is null/empty
|
||||
*/
|
||||
public String sanitizeFilenameForProcess(String filename) {
|
||||
if (filename == null || filename.isBlank()) {
|
||||
return "file";
|
||||
}
|
||||
|
||||
// Replace non-ASCII and non-alphanumeric characters (except dot, dash, underscore) with
|
||||
// underscore
|
||||
String sanitized = filename.replaceAll("[^a-zA-Z0-9._-]", "_");
|
||||
|
||||
// Handle cases where the entire filename became underscores
|
||||
if (sanitized.isBlank() || sanitized.matches("^[._-]+$")) {
|
||||
return "file";
|
||||
}
|
||||
|
||||
// Limit length to prevent excessively long filenames
|
||||
if (sanitized.length() > 200) {
|
||||
sanitized = sanitized.substring(0, 200);
|
||||
}
|
||||
|
||||
return sanitized;
|
||||
}
|
||||
|
||||
// Get resources from a location pattern
|
||||
public Resource[] getResourcesFromLocationPattern(
|
||||
String locationPattern, ResourceLoader resourceLoader) throws Exception {
|
||||
|
||||
@@ -81,6 +81,8 @@ public class PDFToFile {
|
||||
if (originalPdfFileName.contains(".")) {
|
||||
pdfBaseName = originalPdfFileName.substring(0, originalPdfFileName.lastIndexOf('.'));
|
||||
}
|
||||
// Sanitize to ASCII-safe characters for external process compatibility
|
||||
String sanitizedBaseName = GeneralUtils.sanitizeFilenameForProcess(pdfBaseName);
|
||||
|
||||
byte[] fileBytes;
|
||||
String fileName;
|
||||
@@ -97,7 +99,7 @@ public class PDFToFile {
|
||||
"-noframes",
|
||||
"-c",
|
||||
tempInputFile.getAbsolutePath(),
|
||||
pdfBaseName));
|
||||
sanitizedBaseName));
|
||||
|
||||
ProcessExecutorResult returnCode =
|
||||
ProcessExecutor.getInstance(ProcessExecutor.Processes.PDFTOHTML)
|
||||
@@ -169,6 +171,8 @@ public class PDFToFile {
|
||||
if (originalPdfFileName.contains(".")) {
|
||||
pdfBaseName = originalPdfFileName.substring(0, originalPdfFileName.lastIndexOf('.'));
|
||||
}
|
||||
// Sanitize to ASCII-safe characters for external process compatibility
|
||||
String sanitizedBaseName = GeneralUtils.sanitizeFilenameForProcess(pdfBaseName);
|
||||
|
||||
byte[] fileBytes;
|
||||
String fileName;
|
||||
@@ -186,7 +190,7 @@ public class PDFToFile {
|
||||
List<String> command =
|
||||
new ArrayList<>(
|
||||
Arrays.asList(
|
||||
"pdftohtml", "-c", tempInputFile.toString(), pdfBaseName));
|
||||
"pdftohtml", "-c", tempInputFile.toString(), sanitizedBaseName));
|
||||
|
||||
ProcessExecutorResult returnCode =
|
||||
ProcessExecutor.getInstance(ProcessExecutor.Processes.PDFTOHTML)
|
||||
@@ -238,6 +242,8 @@ public class PDFToFile {
|
||||
if (originalPdfFileName.contains(".")) {
|
||||
pdfBaseName = originalPdfFileName.substring(0, originalPdfFileName.lastIndexOf('.'));
|
||||
}
|
||||
// Sanitize to ASCII-safe characters for external process compatibility
|
||||
String sanitizedBaseName = GeneralUtils.sanitizeFilenameForProcess(pdfBaseName);
|
||||
// Validate output format
|
||||
List<String> allowedFormats =
|
||||
Arrays.asList("doc", "docx", "odt", "ppt", "pptx", "odp", "rtf", "xml", "txt:Text");
|
||||
@@ -256,7 +262,7 @@ public class PDFToFile {
|
||||
Path tempOutputDir = outputDirTemp.getPath();
|
||||
Path unoOutputFile =
|
||||
tempOutputDir.resolve(
|
||||
pdfBaseName + "." + resolvePrimaryExtension(outputFormat));
|
||||
sanitizedBaseName + "." + resolvePrimaryExtension(outputFormat));
|
||||
|
||||
// Save the uploaded file to a temporary location
|
||||
inputFile.transferTo(tempInputFile);
|
||||
|
||||
+6
-2
@@ -73,10 +73,14 @@ public class ConvertOfficeController {
|
||||
baseName = "input";
|
||||
}
|
||||
|
||||
// Sanitize baseName to ASCII-safe characters to prevent InvalidPathException
|
||||
// with non-ASCII characters (e.g., Polish, Chinese, etc.) when creating temp file paths
|
||||
String sanitizedBaseName = GeneralUtils.sanitizeFilenameForProcess(baseName);
|
||||
|
||||
// create temporary working directory
|
||||
Path workDir = Files.createTempDirectory("office2pdf_");
|
||||
Path inputPath = workDir.resolve(baseName + "." + extensionLower);
|
||||
Path outputPath = workDir.resolve(baseName + ".pdf");
|
||||
Path inputPath = workDir.resolve(sanitizedBaseName + "." + extensionLower);
|
||||
Path outputPath = workDir.resolve(sanitizedBaseName + ".pdf");
|
||||
|
||||
// Check if the file is HTML and apply sanitization if needed
|
||||
if ("html".equals(extensionLower) || "htm".equals(extensionLower)) {
|
||||
|
||||
@@ -66,6 +66,8 @@ RUN apt-get update && apt-get install -y --no-install-recommends \
|
||||
xvfb x11-utils coreutils \
|
||||
# Temporary packages only needed for Calibre installer
|
||||
xz-utils gpgv curl xdg-utils \
|
||||
# UTF-8 locale support for handling international filenames
|
||||
locales \
|
||||
\
|
||||
# Install Calibre from official installer script
|
||||
&& curl -fsSL https://download.calibre-ebook.com/linux-installer.sh | sh /dev/stdin \
|
||||
@@ -79,6 +81,15 @@ RUN apt-get update && apt-get install -y --no-install-recommends \
|
||||
RUN ln -sf /opt/calibre/ebook-convert /usr/bin/ebook-convert \
|
||||
&& /opt/calibre/ebook-convert --version
|
||||
|
||||
# Configure UTF-8 locale to support international characters in filenames
|
||||
RUN sed -i '/en_US.UTF-8/s/^# //g' /etc/locale.gen \
|
||||
&& locale-gen en_US.UTF-8
|
||||
|
||||
# Set UTF-8 locale environment variables
|
||||
ENV LANG=en_US.UTF-8 \
|
||||
LC_ALL=en_US.UTF-8 \
|
||||
LANGUAGE=en_US:en
|
||||
|
||||
# ==============================================================================
|
||||
# Create non-root user (stirlingpdfuser) with configurable UID/GID
|
||||
# ==============================================================================
|
||||
|
||||
@@ -69,6 +69,8 @@ RUN apt-get update && apt-get install -y --no-install-recommends \
|
||||
xvfb x11-utils coreutils \
|
||||
# Temporary packages only needed for Calibre installer
|
||||
xz-utils gpgv curl xdg-utils \
|
||||
# UTF-8 locale support for handling international filenames
|
||||
locales \
|
||||
\
|
||||
# Install Calibre from official installer script
|
||||
&& curl -fsSL https://download.calibre-ebook.com/linux-installer.sh | sh /dev/stdin \
|
||||
@@ -82,6 +84,15 @@ RUN apt-get update && apt-get install -y --no-install-recommends \
|
||||
RUN ln -sf /opt/calibre/ebook-convert /usr/bin/ebook-convert \
|
||||
&& /opt/calibre/ebook-convert --version
|
||||
|
||||
# Configure UTF-8 locale to support international characters in filenames
|
||||
RUN sed -i '/en_US.UTF-8/s/^# //g' /etc/locale.gen \
|
||||
&& locale-gen en_US.UTF-8
|
||||
|
||||
# Set UTF-8 locale environment variables
|
||||
ENV LANG=en_US.UTF-8 \
|
||||
LC_ALL=en_US.UTF-8 \
|
||||
LANGUAGE=en_US:en
|
||||
|
||||
# ==============================================================================
|
||||
# Create non-root user (stirlingpdfuser) with configurable UID/GID
|
||||
# ==============================================================================
|
||||
|
||||
@@ -73,7 +73,10 @@ ENV VERSION_TAG=$VERSION_TAG \
|
||||
TMPDIR=/tmp/stirling-pdf \
|
||||
TEMP=/tmp/stirling-pdf \
|
||||
TMP=/tmp/stirling-pdf \
|
||||
ENDPOINTS_GROUPS_TO_REMOVE=CLI
|
||||
ENDPOINTS_GROUPS_TO_REMOVE=CLI \
|
||||
LANG=en_US.UTF-8 \
|
||||
LC_ALL=en_US.UTF-8 \
|
||||
LANGUAGE=en_US:en
|
||||
|
||||
# Install minimal dependencies
|
||||
RUN echo "@main https://dl-cdn.alpinelinux.org/alpine/edge/main" | tee -a /etc/apk/repositories && \
|
||||
@@ -88,7 +91,8 @@ RUN echo "@main https://dl-cdn.alpinelinux.org/alpine/edge/main" | tee -a /etc/a
|
||||
curl \
|
||||
shadow \
|
||||
su-exec \
|
||||
openjdk21-jre && \
|
||||
openjdk21-jre \
|
||||
musl-locales musl-locales-lang && \
|
||||
mkdir -p $HOME /configs /configs/heap_dumps /logs /customFiles /pipeline/watchedFolders /pipeline/finishedFolders /tmp/stirling-pdf && \
|
||||
mkdir -p /usr/share/fonts/opentype/noto && \
|
||||
chmod +x /scripts/*.sh && \
|
||||
|
||||
Reference in New Issue
Block a user