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 dc9885ce44 TIKA-5002: parse PEM-armored CMS/PKCS7 like DER (#3437)
dc9885ce44 is described below

commit dc9885ce44e0b97e9fde6ac6c9da46671a50ba6b
Author: Tim Allison <[email protected]>
AuthorDate: Tue Oct 27 12:08:19 2026 -0400

    TIKA-5002: parse PEM-armored CMS/PKCS7 like DER (#3437)
---
 CHANGES.txt                                        |   8 ++
 .../org/apache/tika/mime/tika-mimetypes.xml        |   3 +-
 .../apache/tika/parser/crypto/CmsClassifier.java   | 118 +++++++++++++++++++++
 .../org/apache/tika/parser/crypto/Pkcs7Parser.java |  41 +++----
 .../tika/detect/crypto/Pkcs7DetectorTest.java      |  19 +++-
 .../org/apache/tika/parser/crypto/PemFixtures.java |  43 ++++++++
 .../tika/parser/crypto/Pkcs7DetectionTest.java     |   3 +
 .../apache/tika/parser/crypto/Pkcs7ParserTest.java |  85 ++++++++++++++-
 8 files changed, 296 insertions(+), 24 deletions(-)

diff --git a/CHANGES.txt b/CHANGES.txt
index c5b945e6de..e36c8e43b2 100644
--- a/CHANGES.txt
+++ b/CHANGES.txt
@@ -1,3 +1,11 @@
+Release 4.2.1 - ???
+
+  OTHER CHANGES
+
+   * PEM-armored CMS/PKCS7 (-----BEGIN PKCS7----- or -----BEGIN CMS-----) is 
parsed like
+     DER: Pkcs7Parser and the opt-in pkcs-7-detector report the smime-type and 
extract
+     signed content; -----BEGIN CMS----- is now detected (TIKA-5002).
+
 Release 4.2.0 - 10/25/2026
 
   BREAKING CHANGES AND DEPRECATIONS
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 dda5383b43..37be9a47b7 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
@@ -921,8 +921,9 @@
   <mime-type type="application/pkcs7-signature">
     <glob pattern="*.p7s"/>
     <magic priority="50">
-      <!-- PEM encoded -->
+      <!-- PEM encoded; Pkcs7Parser decodes the armor and refines as for DER 
-->
       <match value="-----BEGIN PKCS7" type="string" offset="0"/>
+      <match value="-----BEGIN CMS-----" type="string" offset="0"/>
       <!-- DER encoded: SEQUENCE then a CMS ContentInfo whose contentType is 
in the pkcs7 arc
            1.2.840.113549.1.7.x (signedData .2, envelopedData .3, digestedData 
.5, encryptedData .6,
            ... last OID byte masked) followed by the [0] content tag (a0). 
offset 2:6 spans the DER
diff --git 
a/tika-parsers/tika-parsers-standard/tika-parsers-standard-modules/tika-parser-crypto-module/src/main/java/org/apache/tika/parser/crypto/CmsClassifier.java
 
b/tika-parsers/tika-parsers-standard/tika-parsers-standard-modules/tika-parser-crypto-module/src/main/java/org/apache/tika/parser/crypto/CmsClassifier.java
index 069fee76ae..dd5d16d5c8 100644
--- 
a/tika-parsers/tika-parsers-standard/tika-parsers-standard-modules/tika-parser-crypto-module/src/main/java/org/apache/tika/parser/crypto/CmsClassifier.java
+++ 
b/tika-parsers/tika-parsers-standard/tika-parsers-standard-modules/tika-parser-crypto-module/src/main/java/org/apache/tika/parser/crypto/CmsClassifier.java
@@ -16,10 +16,15 @@
  */
 package org.apache.tika.parser.crypto;
 
+import java.io.BufferedInputStream;
+import java.io.FilterInputStream;
 import java.io.IOException;
 import java.io.InputStream;
+import java.nio.charset.StandardCharsets;
 import java.nio.file.Files;
 import java.nio.file.Path;
+import java.util.Arrays;
+import java.util.Base64;
 import java.util.Map;
 
 import org.bouncycastle.asn1.ASN1Encodable;
@@ -48,6 +53,10 @@ public final class CmsClassifier {
     // cap the first primitive read when peeking the content-type OID (an OID 
is a few bytes)
     private static final int OID_PEEK_LIMIT = 1 << 16;
 
+    private static final byte[][] PEM_PREFIXES = {
+            "-----BEGIN PKCS7".getBytes(StandardCharsets.US_ASCII),
+            "-----BEGIN CMS".getBytes(StandardCharsets.US_ASCII)};
+
     static final MediaType PKCS7_MIME = MediaType.application("pkcs7-mime");
     static final MediaType PKCS7_SIGNATURE = 
MediaType.application("pkcs7-signature");
     static final MediaType SIGNED = smime("signed-data");
@@ -70,6 +79,12 @@ public final class CmsClassifier {
      *         {@code null}), so a real I/O error is not silently masked as a 
non-crypto stream.
      */
     public static MediaType classify(TikaInputStream tis) throws IOException {
+        try (TikaInputStream der = decodePem(tis)) {
+            return classifyDer(der != null ? der : tis);
+        }
+    }
+
+    private static MediaType classifyDer(TikaInputStream tis) throws 
IOException {
         ASN1ObjectIdentifier oid = contentType(tis);
         if (oid == null) {
             return null;
@@ -113,6 +128,43 @@ public final class CmsClassifier {
         return null;
     }
 
+    /**
+     * A PEM-armored ({@code -----BEGIN PKCS7} / {@code -----BEGIN CMS}) 
stream decoded to DER, or
+     * {@code null} if the stream is not PEM CMS or its body does not decode. 
The caller closes the
+     * result; {@code tis} itself is spooled, not consumed.
+     *
+     * @throws IOException on a genuine spool failure of {@code tis}.
+     */
+    static TikaInputStream decodePem(TikaInputStream tis) throws IOException {
+        if (tis == null || !startsWithPemPrefix(tis)) {
+            return null;
+        }
+        Path path = tis.getPath();
+        if (path == null) {
+            return null;
+        }
+        TikaInputStream der = TikaInputStream.get(
+                Base64.getMimeDecoder().wrap(new PemBody(new 
BufferedInputStream(Files.newInputStream(path)))));
+        try {
+            der.getPath();   // decode eagerly so malformed base64 reads as 
"not CMS", not an I/O error
+            return der;
+        } catch (IOException | IllegalArgumentException e) {
+            der.close();
+            return null;
+        }
+    }
+
+    private static boolean startsWithPemPrefix(TikaInputStream tis) throws 
IOException {
+        byte[] head = new byte[PEM_PREFIXES[0].length];
+        int n = tis.peek(head);
+        for (byte[] prefix : PEM_PREFIXES) {
+            if (n >= prefix.length && Arrays.equals(head, 0, prefix.length, 
prefix, 0, prefix.length)) {
+                return true;
+            }
+        }
+        return false;
+    }
+
     /** Cheap DER-{@code SEQUENCE} gate: peek one byte (mark/reset, no spool). 
*/
     private static boolean looksLikeDerSequence(TikaInputStream tis) throws 
IOException {
         byte[] head = new byte[1];
@@ -172,4 +224,70 @@ public final class CmsClassifier {
         boolean hasCerts = 
!parser.getCertificates().getMatches(null).isEmpty();
         return (hasCerts && !hasSigners) ? CERTS_ONLY : PKCS7_SIGNATURE;
     }
+
+    /** The base64 body of a PEM block: skips the BEGIN line, ends at the 
{@code -----END} line. */
+    private static final class PemBody extends FilterInputStream {
+
+        private boolean inBody;
+        private boolean done;
+
+        PemBody(InputStream in) {
+            super(in);
+        }
+
+        @Override
+        public int read() throws IOException {
+            if (done) {
+                return -1;
+            }
+            int c;
+            while (!inBody) {
+                c = in.read();
+                if (c == -1) {
+                    done = true;
+                    return -1;
+                }
+                inBody = c == '\n';
+            }
+            c = in.read();
+            // '-' is outside the base64 alphabet, so it can only start the 
END line
+            if (c == -1 || c == '-') {
+                done = true;
+                return -1;
+            }
+            return c;
+        }
+
+        @Override
+        public int read(byte[] b, int off, int len) throws IOException {
+            int i = 0;
+            for (; i < len; i++) {
+                int c = read();
+                if (c == -1) {
+                    break;
+                }
+                b[off + i] = (byte) c;
+            }
+            return i == 0 && len > 0 ? -1 : i;
+        }
+
+        @Override
+        public long skip(long n) throws IOException {
+            long i = 0;
+            while (i < n && read() != -1) {
+                i++;
+            }
+            return i;
+        }
+
+        @Override
+        public int available() {
+            return 0;
+        }
+
+        @Override
+        public boolean markSupported() {
+            return false;
+        }
+    }
 }
diff --git 
a/tika-parsers/tika-parsers-standard/tika-parsers-standard-modules/tika-parser-crypto-module/src/main/java/org/apache/tika/parser/crypto/Pkcs7Parser.java
 
b/tika-parsers/tika-parsers-standard/tika-parsers-standard-modules/tika-parser-crypto-module/src/main/java/org/apache/tika/parser/crypto/Pkcs7Parser.java
index a901bc347a..a54119b7bc 100644
--- 
a/tika-parsers/tika-parsers-standard/tika-parsers-standard-modules/tika-parser-crypto-module/src/main/java/org/apache/tika/parser/crypto/Pkcs7Parser.java
+++ 
b/tika-parsers/tika-parsers-standard/tika-parsers-standard-modules/tika-parser-crypto-module/src/main/java/org/apache/tika/parser/crypto/Pkcs7Parser.java
@@ -74,29 +74,34 @@ public class Pkcs7Parser implements Parser {
     public void parse(TikaInputStream tis, ContentHandler handler, Metadata 
metadata,
                       ParseContext context) throws IOException, SAXException, 
TikaException {
         tis.setCloseShield();
-        try {
-            // route on the cheap ContentInfo OID; signedData is then parsed 
exactly once (in
-            // parseSignedData), which both labels the subtype and extracts 
the payload
-            ASN1ObjectIdentifier oid = CmsClassifier.contentType(tis);
-            if (PKCSObjectIdentifiers.signedData.equals(oid)) {
-                parseSignedData(tis, handler, metadata, context);
-            } else if (PKCSObjectIdentifiers.id_ct_compressedData.equals(oid)) 
{
-                metadata.set(HttpHeaders.CONTENT_TYPE, 
CmsClassifier.COMPRESSED.toString());
-                extractCompressedContent(tis, handler, metadata, context);
-            } else {
-                // enveloped / digested / encrypted (labelled; payload absent, 
encrypted, or
-                // unsupported) or unknown / non-CMS -> empty doc, no throw
-                MediaType type = CmsClassifier.nonSignedType(oid);
-                if (type != null) {
-                    metadata.set(HttpHeaders.CONTENT_TYPE, type.toString());
-                }
-                emptyDocument(handler, metadata);
-            }
+        try (TikaInputStream der = CmsClassifier.decodePem(tis)) {
+            parseDer(der != null ? der : tis, handler, metadata, context);
         } finally {
             tis.removeCloseShield();
         }
     }
 
+    private void parseDer(TikaInputStream tis, ContentHandler handler, 
Metadata metadata,
+                          ParseContext context) throws IOException, 
SAXException, TikaException {
+        // route on the cheap ContentInfo OID; signedData is then parsed 
exactly once (in
+        // parseSignedData), which both labels the subtype and extracts the 
payload
+        ASN1ObjectIdentifier oid = CmsClassifier.contentType(tis);
+        if (PKCSObjectIdentifiers.signedData.equals(oid)) {
+            parseSignedData(tis, handler, metadata, context);
+        } else if (PKCSObjectIdentifiers.id_ct_compressedData.equals(oid)) {
+            metadata.set(HttpHeaders.CONTENT_TYPE, 
CmsClassifier.COMPRESSED.toString());
+            extractCompressedContent(tis, handler, metadata, context);
+        } else {
+            // enveloped / digested / encrypted (labelled; payload absent, 
encrypted, or
+            // unsupported) or unknown / non-CMS -> empty doc, no throw
+            MediaType type = CmsClassifier.nonSignedType(oid);
+            if (type != null) {
+                metadata.set(HttpHeaders.CONTENT_TYPE, type.toString());
+            }
+            emptyDocument(handler, metadata);
+        }
+    }
+
     /** Parse a signedData message once: set the refined subtype and extract 
the embedded payload if present. */
     private void parseSignedData(TikaInputStream tis, ContentHandler handler, 
Metadata metadata,
                                  ParseContext context)
diff --git 
a/tika-parsers/tika-parsers-standard/tika-parsers-standard-modules/tika-parser-crypto-module/src/test/java/org/apache/tika/detect/crypto/Pkcs7DetectorTest.java
 
b/tika-parsers/tika-parsers-standard/tika-parsers-standard-modules/tika-parser-crypto-module/src/test/java/org/apache/tika/detect/crypto/Pkcs7DetectorTest.java
index 220e73410b..9750206196 100644
--- 
a/tika-parsers/tika-parsers-standard/tika-parsers-standard-modules/tika-parser-crypto-module/src/test/java/org/apache/tika/detect/crypto/Pkcs7DetectorTest.java
+++ 
b/tika-parsers/tika-parsers-standard/tika-parsers-standard-modules/tika-parser-crypto-module/src/test/java/org/apache/tika/detect/crypto/Pkcs7DetectorTest.java
@@ -16,6 +16,8 @@
  */
 package org.apache.tika.detect.crypto;
 
+import static org.apache.tika.parser.crypto.PemFixtures.pem;
+import static org.apache.tika.parser.crypto.PemFixtures.resource;
 import static org.junit.jupiter.api.Assertions.assertEquals;
 
 import org.junit.jupiter.api.Test;
@@ -31,12 +33,25 @@ public class Pkcs7DetectorTest {
     private final Pkcs7Detector detector = new Pkcs7Detector();
 
     private MediaType detect(String resource) throws Exception {
-        try (TikaInputStream tis = TikaInputStream.get(
-                Pkcs7DetectorTest.class.getResourceAsStream("/test-documents/" 
+ resource))) {
+        return detect(resource(resource));
+    }
+
+    private MediaType detect(byte[] bytes) throws Exception {
+        try (TikaInputStream tis = TikaInputStream.get(bytes)) {
             return detector.detect(tis, new Metadata(), new ParseContext());
         }
     }
 
+    @Test
+    public void testPemSubtypeAtDetectTime() throws Exception {
+        assertEquals(MediaType.parse("application/pkcs7-mime; 
smime-type=certs-only"),
+                detect(pem(resource("testPKCS7_certs_only_def.p7c"), "PKCS7", 
"\n")));
+        assertEquals(MediaType.parse("application/pkcs7-mime; 
smime-type=signed-data"),
+                detect(pem(resource("testPKCS7_signed_data_def.p7m"), "CMS", 
"\r\n")));
+        assertEquals(MediaType.parse("application/pkcs7-mime; 
smime-type=signed-data"),
+                detect("testPKCS7_signed_data_def.pem"));
+    }
+
     @Test
     public void testSubtypeAtDetectTime() throws Exception {
         assertEquals(MediaType.parse("application/pkcs7-mime; 
smime-type=signed-data"),
diff --git 
a/tika-parsers/tika-parsers-standard/tika-parsers-standard-modules/tika-parser-crypto-module/src/test/java/org/apache/tika/parser/crypto/PemFixtures.java
 
b/tika-parsers/tika-parsers-standard/tika-parsers-standard-modules/tika-parser-crypto-module/src/test/java/org/apache/tika/parser/crypto/PemFixtures.java
new file mode 100644
index 0000000000..4fc97bce84
--- /dev/null
+++ 
b/tika-parsers/tika-parsers-standard/tika-parsers-standard-modules/tika-parser-crypto-module/src/test/java/org/apache/tika/parser/crypto/PemFixtures.java
@@ -0,0 +1,43 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.tika.parser.crypto;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.nio.charset.StandardCharsets;
+import java.util.Base64;
+
+/** Builds PEM-armored test inputs from the DER fixtures. */
+public final class PemFixtures {
+
+    private PemFixtures() {
+    }
+
+    public static byte[] resource(String name) throws IOException {
+        try (InputStream is = 
PemFixtures.class.getResourceAsStream("/test-documents/" + name)) {
+            return is.readAllBytes();
+        }
+    }
+
+    /** {@code der} armored as {@code -----BEGIN <label>-----} with 64-column 
lines ending in {@code eol}. */
+    public static byte[] pem(byte[] der, String label, String eol) {
+        String body = Base64.getMimeEncoder(64, 
eol.getBytes(StandardCharsets.US_ASCII))
+                .encodeToString(der);
+        return ("-----BEGIN " + label + "-----" + eol + body + eol + "-----END 
" + label + "-----" + eol)
+                .getBytes(StandardCharsets.US_ASCII);
+    }
+}
diff --git 
a/tika-parsers/tika-parsers-standard/tika-parsers-standard-modules/tika-parser-crypto-module/src/test/java/org/apache/tika/parser/crypto/Pkcs7DetectionTest.java
 
b/tika-parsers/tika-parsers-standard/tika-parsers-standard-modules/tika-parser-crypto-module/src/test/java/org/apache/tika/parser/crypto/Pkcs7DetectionTest.java
index 8e17722244..1c70765932 100644
--- 
a/tika-parsers/tika-parsers-standard/tika-parsers-standard-modules/tika-parser-crypto-module/src/test/java/org/apache/tika/parser/crypto/Pkcs7DetectionTest.java
+++ 
b/tika-parsers/tika-parsers-standard/tika-parsers-standard-modules/tika-parser-crypto-module/src/test/java/org/apache/tika/parser/crypto/Pkcs7DetectionTest.java
@@ -52,5 +52,8 @@ public class Pkcs7DetectionTest {
         assertEquals("application/pkcs7-signature", 
detect("testPKCS7_enveloped_def.p7m"));
         // TIKA-2856: a short-form-length digestedData is now caught coarsely 
(routes to Pkcs7Parser)
         assertEquals("application/pkcs7-signature", 
detect("testPKCS7_digested.p7"));
+        // TIKA-5002: `openssl cms -outform PEM` armor routes to Pkcs7Parser
+        assertEquals("application/pkcs7-signature", 
tika.detect(PemFixtures.pem(
+                PemFixtures.resource("testPKCS7_certs_only_def.p7c"), "CMS", 
"\n")));
     }
 }
diff --git 
a/tika-parsers/tika-parsers-standard/tika-parsers-standard-modules/tika-parser-crypto-module/src/test/java/org/apache/tika/parser/crypto/Pkcs7ParserTest.java
 
b/tika-parsers/tika-parsers-standard/tika-parsers-standard-modules/tika-parser-crypto-module/src/test/java/org/apache/tika/parser/crypto/Pkcs7ParserTest.java
index 6fac51ff64..3a75ef100c 100644
--- 
a/tika-parsers/tika-parsers-standard/tika-parsers-standard-modules/tika-parser-crypto-module/src/test/java/org/apache/tika/parser/crypto/Pkcs7ParserTest.java
+++ 
b/tika-parsers/tika-parsers-standard/tika-parsers-standard-modules/tika-parser-crypto-module/src/test/java/org/apache/tika/parser/crypto/Pkcs7ParserTest.java
@@ -16,28 +16,107 @@
  */
 package org.apache.tika.parser.crypto;
 
+import static org.apache.tika.parser.crypto.PemFixtures.pem;
+import static org.apache.tika.parser.crypto.PemFixtures.resource;
+import static org.junit.jupiter.api.Assertions.assertArrayEquals;
 import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertNotNull;
+import static org.junit.jupiter.api.Assertions.assertNull;
+
+import java.io.IOException;
+import java.nio.charset.StandardCharsets;
+import java.util.Set;
+import java.util.stream.Stream;
 
 import org.junit.jupiter.api.Test;
+import org.junit.jupiter.params.ParameterizedTest;
+import org.junit.jupiter.params.provider.Arguments;
+import org.junit.jupiter.params.provider.MethodSource;
+import org.xml.sax.ContentHandler;
 import org.xml.sax.helpers.DefaultHandler;
 
 import org.apache.tika.io.TikaInputStream;
 import org.apache.tika.metadata.HttpHeaders;
 import org.apache.tika.metadata.Metadata;
+import org.apache.tika.mime.MediaType;
 import org.apache.tika.parser.ParseContext;
+import org.apache.tika.parser.Parser;
 
 public class Pkcs7ParserTest {
 
     /** Parse a fixture and return the content type the parser refined it to. 
*/
     private String parsedType(String resource) throws Exception {
+        return parsedType(resource(resource), new ParseContext());
+    }
+
+    private String parsedType(byte[] bytes, ParseContext context) throws 
Exception {
         Metadata metadata = new Metadata();
-        try (TikaInputStream tis = TikaInputStream.get(
-                Pkcs7ParserTest.class.getResourceAsStream("/test-documents/" + 
resource))) {
-            new Pkcs7Parser().parse(tis, new DefaultHandler(), metadata, new 
ParseContext());
+        try (TikaInputStream tis = TikaInputStream.get(bytes)) {
+            new Pkcs7Parser().parse(tis, new DefaultHandler(), metadata, 
context);
         }
         return metadata.get(HttpHeaders.CONTENT_TYPE);
     }
 
+    static Stream<Arguments> pemCases() {
+        return Stream.of("testPKCS7_signed_data_def.p7m", 
"testPKCS7_signed_data_ind.p7m",
+                        "testPKCS7_enveloped_def.p7m", 
"testPKCS7_certs_only_def.p7c",
+                        "testPKCS7_certs_only_ind.p7c", 
"testPKCS7_compressed_def_long.p7z",
+                        "testPKCS7_digested.p7", "testPKCS7_signature_def.p7s")
+                .flatMap(r -> Stream.of(Arguments.of(r, "PKCS7", "\n"),
+                        Arguments.of(r, "CMS", "\r\n")));
+    }
+
+    /** TIKA-5002: PEM armor refines exactly like the DER it wraps. */
+    @ParameterizedTest
+    @MethodSource("pemCases")
+    public void testPemRefinesLikeDer(String resource, String label, String 
eol) throws Exception {
+        byte[] der = resource(resource);
+        String expected = parsedType(der, new ParseContext());
+        assertNotNull(expected);
+        assertEquals(expected, parsedType(pem(der, label, eol), new 
ParseContext()));
+    }
+
+    @Test
+    public void testPemFixture() throws Exception {
+        assertEquals("application/pkcs7-mime; smime-type=signed-data",
+                parsedType("testPKCS7_signed_data_def.pem"));
+    }
+
+    @Test
+    public void testPemPayloadExtracted() throws Exception {
+        byte[] der = resource("test.xml.p7m");
+        assertArrayEquals(extractedPayload(der), extractedPayload(pem(der, 
"PKCS7", "\n")));
+    }
+
+    @Test
+    public void testMalformedPemDoesNotThrow() throws Exception {
+        byte[] junk = "-----BEGIN PKCS7-----\nA===\n-----END PKCS7-----\n"
+                .getBytes(StandardCharsets.US_ASCII);
+        assertNull(parsedType(junk, new ParseContext()));
+        byte[] notCms = pem("not cms".getBytes(StandardCharsets.US_ASCII), 
"CMS", "\n");
+        assertNull(parsedType(notCms, new ParseContext()));
+    }
+
+    private byte[] extractedPayload(byte[] input) throws Exception {
+        byte[][] payload = new byte[1][];
+        ParseContext context = new ParseContext();
+        context.set(Parser.class, new Parser() {
+            @Override
+            public Set<MediaType> getSupportedTypes(ParseContext ctx) {
+                return Set.of();
+            }
+
+            @Override
+            public void parse(TikaInputStream tis, ContentHandler handler, 
Metadata metadata,
+                              ParseContext ctx) throws IOException {
+                payload[0] = tis.readAllBytes();
+            }
+        });
+        parsedType(input, context);
+        assertNotNull(payload[0]);
+        return payload[0];
+    }
+
     @Test
     public void testSubtypeRefinement() throws Exception {
         assertEquals("application/pkcs7-mime; smime-type=signed-data",

Reply via email to