This is an automated email from the ASF dual-hosted git repository.
tballison pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/tika.git
The following commit(s) were added to refs/heads/main by this push:
new e88a4077eb TIKA-4973: slightly improve detection of rfc822 vs mhtml
(#3349)
e88a4077eb is described below
commit e88a4077ebc6644cb80c68e6880020f5aeaeac76
Author: Tim Allison <[email protected]>
AuthorDate: Mon Oct 19 17:37:27 2026 -0400
TIKA-4973: slightly improve detection of rfc822 vs mhtml (#3349)
---
CHANGES.txt | 4 +++
.../org/apache/tika/mime/tika-mimetypes.xml | 6 ++--
.../java/org/apache/tika/mime/TestMimeTypes.java | 39 ++++++++++++++++++++++
3 files changed, 46 insertions(+), 3 deletions(-)
diff --git a/CHANGES.txt b/CHANGES.txt
index 2f47a3e631..669e2e1c7d 100644
--- a/CHANGES.txt
+++ b/CHANGES.txt
@@ -1,5 +1,9 @@
Release 4.2.0 - unreleased
+ * An email that starts with MIME-Version and nests a multipart/related part
(a Gmail
+ export, for one) is detected as message/rfc822, not as MHTML: the
+ multipart/related magic now reads only the message's own header block
(TIKA-4973).
+
* The docx parser wraps OMML equations (m:oMath) in <span class="omml">,
their
text flattened to plain characters; it was previously emitted as unmarked
body
text (TIKA-4968).
diff --git
a/tika-core/src/main/resources/org/apache/tika/mime/tika-mimetypes.xml
b/tika-core/src/main/resources/org/apache/tika/mime/tika-mimetypes.xml
index 7fa05d2920..d59422dbca 100644
--- a/tika-core/src/main/resources/org/apache/tika/mime/tika-mimetypes.xml
+++ b/tika-core/src/main/resources/org/apache/tika/mime/tika-mimetypes.xml
@@ -7622,9 +7622,9 @@
<magic priority="60">
<match value="From: \x3cSaved by Windows Internet Explorer 8\x3e"
type="stringignorecase" offset="0"/>
<match value="From: \x22Saved by Internet Explorer 11\x22"
type="stringignorecase" offset="0"/>
- <match value="MIME-Version: 1.0" type="string" offset="0">
- <match value="\nContent-Type: multipart/related" type="string"
offset="16:512"/>
- </match>
+ <!-- the message's own Content-Type: non-empty lines only, so the match
stops at the
+ blank line that ends the header block and never reaches a nested
part's header -->
+ <match value="MIME-Version: 1[.]0(?:
[^\r\n]{0,100})?\r?\n(?:[^\r\n]+\r?\n)*?Content-Type: multipart/related"
type="regex" offset="0"/>
</magic>
<glob pattern="*.mht"/>
<glob pattern="*.mhtml"/>
diff --git
a/tika-parsers/tika-parsers-standard/tika-parsers-standard-integration-tests/src/test/java/org/apache/tika/mime/TestMimeTypes.java
b/tika-parsers/tika-parsers-standard/tika-parsers-standard-integration-tests/src/test/java/org/apache/tika/mime/TestMimeTypes.java
index dd20419d8d..c00a913bfd 100644
---
a/tika-parsers/tika-parsers-standard/tika-parsers-standard-integration-tests/src/test/java/org/apache/tika/mime/TestMimeTypes.java
+++
b/tika-parsers/tika-parsers-standard/tika-parsers-standard-integration-tests/src/test/java/org/apache/tika/mime/TestMimeTypes.java
@@ -1081,6 +1081,45 @@ public class TestMimeTypes {
}
+ /**
+ * TIKA-4973: the MHTML magic keys on the message's own Content-Type, not
a nested part's.
+ * A Gmail export starts with MIME-Version and nests multipart/related in
multipart/mixed.
+ */
+ @Test
+ public void testNestedMultipartRelatedIsNotMhtml() throws Exception {
+ String gmail = "MIME-Version: 1.0\n" +
+ "Date: Fri, 11 Sep 2026 11:18:43 -0400\n" +
+ "Subject: a subject\n" +
+ "From: someone <[email protected]>\n" +
+ "Content-Type: multipart/mixed; boundary=\"outer\"\n" +
+ "\n" +
+ "--outer\n" +
+ "Content-Type: multipart/related; boundary=\"inner\"\n" +
+ "\n" +
+ "--inner\n" +
+ "Content-Type: text/plain; charset=\"UTF-8\"\n" +
+ "\n" +
+ "body\n";
+ String mhtml = "MIME-Version: 1.0\n" +
+ "Subject: a saved page\n" +
+ "\tfolded onto a second line\n" +
+ "Content-Type: multipart/related;\n" +
+ "\tboundary=\"page\";\n" +
+ "\ttype=\"text/html\"\n" +
+ "\n" +
+ "--page\n" +
+ "Content-Type: text/html\n" +
+ "\n" +
+ "<html></html>\n";
+ for (String eol : new String[]{"\n", "\r\n"}) {
+ assertTypeByData("message/rfc822", gmail.replace("\n",
eol).getBytes(US_ASCII));
+ assertTypeByData("multipart/related", mhtml.replace("\n",
eol).getBytes(US_ASCII));
+ // RFC 2045 allows a comment after the version
+ assertTypeByData("multipart/related", mhtml.replace("1.0", "1.0
(Produced by a tool)")
+ .replace("\n", eol).getBytes(US_ASCII));
+ }
+ }
+
@Test
public void testRobots() throws Exception {
assertTypeByData("text/x-robots", "testRobots.txt");