aboutsummaryrefslogtreecommitdiff
path: root/src/main
diff options
context:
space:
mode:
Diffstat (limited to 'src/main')
-rw-r--r--src/main/java/org/zwobble/mammoth/DocumentConverter.java9
-rw-r--r--src/main/java/org/zwobble/mammoth/internal/InternalDocumentConverter.java4
-rw-r--r--src/main/java/org/zwobble/mammoth/internal/conversion/DocumentToHtmlOptions.java88
-rw-r--r--src/main/java/org/zwobble/mammoth/internal/docx/DisabledFileReader.java11
-rw-r--r--src/main/java/org/zwobble/mammoth/internal/docx/DocumentReader.java12
5 files changed, 114 insertions, 10 deletions
diff --git a/src/main/java/org/zwobble/mammoth/DocumentConverter.java b/src/main/java/org/zwobble/mammoth/DocumentConverter.java
index 2dea8e8..c7dca20 100644
--- a/src/main/java/org/zwobble/mammoth/DocumentConverter.java
+++ b/src/main/java/org/zwobble/mammoth/DocumentConverter.java
@@ -61,6 +61,15 @@ public class DocumentConverter {
}
/**
+ * Source documents may reference files outside of the source document.
+ * Call this to disable access to any such external files during the conversion process.
+ * This is highly recommended when converting untrusted user input.
+ */
+ public DocumentConverter disableExternalFileAccess() {
+ return new DocumentConverter(options.disableExternalFileAccess());
+ }
+
+ /**
* By default, images are converted to {@code <img>} elements with the source included inline in the {@code src} attribute.
* Call this to change how images are converted.
*/
diff --git a/src/main/java/org/zwobble/mammoth/internal/InternalDocumentConverter.java b/src/main/java/org/zwobble/mammoth/internal/InternalDocumentConverter.java
index 8ff1e95..3e01181 100644
--- a/src/main/java/org/zwobble/mammoth/internal/InternalDocumentConverter.java
+++ b/src/main/java/org/zwobble/mammoth/internal/InternalDocumentConverter.java
@@ -45,7 +45,7 @@ public class InternalDocumentConverter {
Optional<StyleMap> styleMap = readEmbeddedStyleMap(zipFile).map(StyleMapParser::parse);
DocumentToHtmlOptions conversionOptions = styleMap.map(options::addEmbeddedStyleMap).orElse(options);
- return readDocument(path, zipFile)
+ return readDocument(path, zipFile, conversionOptions.externalFileAccess())
.flatMap(nodes -> DocumentToHtml.convertToHtml(nodes, conversionOptions))
.map(Html::stripEmpty)
.map(Html::collapse)
@@ -69,7 +69,7 @@ public class InternalDocumentConverter {
}
private InternalResult<String> extractRawText(Optional<Path> path, Archive zipFile) {
- return readDocument(path, zipFile)
+ return readDocument(path, zipFile, options.externalFileAccess())
.map(RawText::extractRawText);
}
diff --git a/src/main/java/org/zwobble/mammoth/internal/conversion/DocumentToHtmlOptions.java b/src/main/java/org/zwobble/mammoth/internal/conversion/DocumentToHtmlOptions.java
index 2c455e2..d12bbd4 100644
--- a/src/main/java/org/zwobble/mammoth/internal/conversion/DocumentToHtmlOptions.java
+++ b/src/main/java/org/zwobble/mammoth/internal/conversion/DocumentToHtmlOptions.java
@@ -16,6 +16,7 @@ public class DocumentToHtmlOptions {
StyleMap.EMPTY,
false,
false,
+ false,
InternalImageConverter.imgElement(image -> {
String base64 = Base64Encoding.streamToBase64(image::getInputStream);
String src = "data:" + image.getContentType() + ";base64," + base64;
@@ -30,6 +31,7 @@ public class DocumentToHtmlOptions {
private final StyleMap embeddedStyleMap;
private final boolean disableDefaultStyleMap;
private final boolean disableEmbeddedStyleMap;
+ private final boolean disableExternalFileAccess;
private final InternalImageConverter imageConverter;
public DocumentToHtmlOptions(
@@ -39,6 +41,7 @@ public class DocumentToHtmlOptions {
StyleMap embeddedStyleMap,
boolean disableDefaultStyleMap,
boolean disableEmbeddedStyleMap,
+ boolean disableExternalFileAccess,
InternalImageConverter imageConverter
) {
this.idPrefix = idPrefix;
@@ -47,15 +50,34 @@ public class DocumentToHtmlOptions {
this.embeddedStyleMap = embeddedStyleMap;
this.disableDefaultStyleMap = disableDefaultStyleMap;
this.disableEmbeddedStyleMap = disableEmbeddedStyleMap;
+ this.disableExternalFileAccess = disableExternalFileAccess;
this.imageConverter = imageConverter;
}
public DocumentToHtmlOptions idPrefix(String prefix) {
- return new DocumentToHtmlOptions(prefix, preserveEmptyParagraphs, styleMap, embeddedStyleMap, disableDefaultStyleMap, disableEmbeddedStyleMap, imageConverter);
+ return new DocumentToHtmlOptions(
+ prefix,
+ preserveEmptyParagraphs,
+ styleMap,
+ embeddedStyleMap,
+ disableDefaultStyleMap,
+ disableEmbeddedStyleMap,
+ disableExternalFileAccess,
+ imageConverter
+ );
}
public DocumentToHtmlOptions preserveEmptyParagraphs() {
- return new DocumentToHtmlOptions(idPrefix, true, styleMap, embeddedStyleMap, disableDefaultStyleMap, disableEmbeddedStyleMap, imageConverter);
+ return new DocumentToHtmlOptions(
+ idPrefix,
+ true,
+ styleMap,
+ embeddedStyleMap,
+ disableDefaultStyleMap,
+ disableEmbeddedStyleMap,
+ disableExternalFileAccess,
+ imageConverter
+ );
}
public DocumentToHtmlOptions addStyleMap(String styleMap) {
@@ -63,19 +85,68 @@ public class DocumentToHtmlOptions {
}
public DocumentToHtmlOptions addStyleMap(StyleMap styleMap) {
- return new DocumentToHtmlOptions(idPrefix, preserveEmptyParagraphs, this.styleMap.update(styleMap), embeddedStyleMap, disableDefaultStyleMap, disableEmbeddedStyleMap, imageConverter);
+ return new DocumentToHtmlOptions(
+ idPrefix,
+ preserveEmptyParagraphs,
+ this.styleMap.update(styleMap),
+ embeddedStyleMap,
+ disableDefaultStyleMap,
+ disableEmbeddedStyleMap,
+ disableExternalFileAccess,
+ imageConverter
+ );
}
public DocumentToHtmlOptions disableDefaultStyleMap() {
- return new DocumentToHtmlOptions(idPrefix, preserveEmptyParagraphs, styleMap, embeddedStyleMap, true, disableEmbeddedStyleMap, imageConverter);
+ return new DocumentToHtmlOptions(
+ idPrefix,
+ preserveEmptyParagraphs,
+ styleMap,
+ embeddedStyleMap,
+ true,
+ disableEmbeddedStyleMap,
+ disableExternalFileAccess,
+ imageConverter
+ );
}
public DocumentToHtmlOptions disableEmbeddedStyleMap() {
- return new DocumentToHtmlOptions(idPrefix, preserveEmptyParagraphs, styleMap, embeddedStyleMap, disableDefaultStyleMap, true, imageConverter);
+ return new DocumentToHtmlOptions(
+ idPrefix,
+ preserveEmptyParagraphs,
+ styleMap,
+ embeddedStyleMap,
+ disableDefaultStyleMap,
+ true,
+ disableExternalFileAccess,
+ imageConverter
+ );
+ }
+
+ public DocumentToHtmlOptions disableExternalFileAccess() {
+ return new DocumentToHtmlOptions(
+ idPrefix,
+ preserveEmptyParagraphs,
+ styleMap,
+ embeddedStyleMap,
+ disableDefaultStyleMap,
+ disableEmbeddedStyleMap,
+ true,
+ imageConverter
+ );
}
public DocumentToHtmlOptions addEmbeddedStyleMap(StyleMap embeddedStyleMap) {
- return new DocumentToHtmlOptions(idPrefix, preserveEmptyParagraphs, styleMap, embeddedStyleMap, disableDefaultStyleMap, disableEmbeddedStyleMap, imageConverter);
+ return new DocumentToHtmlOptions(
+ idPrefix,
+ preserveEmptyParagraphs,
+ styleMap,
+ embeddedStyleMap,
+ disableDefaultStyleMap,
+ disableEmbeddedStyleMap,
+ disableExternalFileAccess,
+ imageConverter
+ );
}
public DocumentToHtmlOptions imageConverter(ImageConverter.ImgElement imageConverter) {
@@ -86,6 +157,7 @@ public class DocumentToHtmlOptions {
embeddedStyleMap,
disableDefaultStyleMap,
disableEmbeddedStyleMap,
+ disableExternalFileAccess,
InternalImageConverter.imgElement(imageConverter)
);
}
@@ -110,6 +182,10 @@ public class DocumentToHtmlOptions {
return styleMap;
}
+ public boolean externalFileAccess() {
+ return !this.disableExternalFileAccess;
+ }
+
public InternalImageConverter imageConverter() {
return imageConverter;
}
diff --git a/src/main/java/org/zwobble/mammoth/internal/docx/DisabledFileReader.java b/src/main/java/org/zwobble/mammoth/internal/docx/DisabledFileReader.java
new file mode 100644
index 0000000..03386d4
--- /dev/null
+++ b/src/main/java/org/zwobble/mammoth/internal/docx/DisabledFileReader.java
@@ -0,0 +1,11 @@
+package org.zwobble.mammoth.internal.docx;
+
+import java.io.IOException;
+import java.io.InputStream;
+
+public class DisabledFileReader implements FileReader {
+ @Override
+ public InputStream getInputStream(String uri) throws IOException {
+ throw new IOException("could not open external image '" + uri + "': external file access is disabled");
+ }
+}
diff --git a/src/main/java/org/zwobble/mammoth/internal/docx/DocumentReader.java b/src/main/java/org/zwobble/mammoth/internal/docx/DocumentReader.java
index 1955e55..495646f 100644
--- a/src/main/java/org/zwobble/mammoth/internal/docx/DocumentReader.java
+++ b/src/main/java/org/zwobble/mammoth/internal/docx/DocumentReader.java
@@ -22,13 +22,21 @@ import static org.zwobble.mammoth.internal.util.Lists.*;
import static org.zwobble.mammoth.internal.util.Strings.trimLeft;
public class DocumentReader {
- public static InternalResult<Document> readDocument(Optional<Path> path, Archive zipFile) {
+ public static InternalResult<Document> readDocument(
+ Optional<Path> path,
+ Archive zipFile,
+ boolean externalFileAccess
+ ) {
PartPaths partPaths = findPartPaths(zipFile);
Styles styles = readStyles(zipFile, partPaths);
Numbering numbering = readNumbering(zipFile, partPaths, styles);
ContentTypes contentTypes = readContentTypes(zipFile);
- FileReader fileReader = new PathRelativeFileReader(path);
+
+ FileReader fileReader = externalFileAccess
+ ? new PathRelativeFileReader(path)
+ : new DisabledFileReader();
+
PartWithBodyReader partReader = new PartWithBodyReader(zipFile, contentTypes, fileReader, numbering, styles);
return InternalResult.flatMap(
readNotes(partReader, partPaths),