[jira] [Closed] (JAMES-4214) Sieve MessageMatcher failed for simple Mime message

"Benoit Tellier (Jira)" <[email protected]> Mon, 6 Jul 2026 12:50:00 +0000 (UTC)
Newsgroups gmane.comp.jakarta.james.devel
Message-ID <[email protected]>
     [ https://issues.apache.org/jira/browse/JAMES-4214?page=3Dcom.atlassia=
n.jira.plugin.system.issuetabpanels:all-tabpanel ]

Benoit Tellier closed JAMES-4214.
---------------------------------
    Resolution: Fixed

Hello

I merged the fix as this is straightforward.

Thanks again for the report

> Sieve MessageMatcher failed for simple Mime message
> ---------------------------------------------------
>
>                 Key: JAMES-4214
>                 URL: https://issues.apache.org/jira/browse/JAMES-4214
>             Project: James Server
>          Issue Type: Bug
>          Components: Matchers/Mailets (bundled), sieve
>    Affects Versions: 3.9.0
>         Environment: apache james 3.9.0
>            Reporter: vincent royer
>            Priority: Critical
>         Attachments: bodyTextMatchBitcoin.script, titi-1.eml
>
>          Time Spent: 0.5h
>  Remaining Estimate: 0h
>
> When processing a simple text mail with the following SIEVE filter, it do=
es not match the content because the inputstream is already closed when sea=
rching for the keyword in the message body. With a multi-part message, ther=
e is no issue and the SIEVE filter match the keyword. Please find the raw m=
ail tit.eml in attachment to reproduce the issue.
> {quote}require "fileinto";
> require "body";
> if body :content "text/plain" :contains "bitcoin" {
> =C2=A0 =C2=A0 fileinto "INBOX.select";
> } else {
> =C2=A0 =C2=A0 fileinto "INBOX.not.selected";
> }
> {quote}
> =C2=A0
> The issue is not located in mime4j, the following unit test works well in=
 org.apache.james.mime4j.utils.search.MessageMatcherTest
> {quote}{{@Test}}
> {{public void isFoundInShouldBeAbleToLocateTextFragments2() throws Except=
ion {}}
> {{=C2=A0 =C2=A0 =C2=A0 =C2=A0 MessageMatcher messageMatcher =3D MessageMa=
tcher.builder()}}
> {{=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 .searchContents=
(Lists.<CharSequence>newArrayList("bitcoin"))}}
> {{=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 .caseInsensitiv=
e(false)}}
> {{=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 .includeHeaders=
(false)}}
> {{=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 .contentTypes(I=
mmutableList.of("text/plain"))}}
> {{=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 .build();}}
> {{=C2=A0 =C2=A0 =C2=A0 =C2=A0 assertThat(messageMatcher.messageMatches(ge=
tResourceStream("titi.eml"))).isTrue();}}{quote}
> {quote}{{}}}{quote}
> The issue really happens when reading a single-part text/plain message fr=
om a mailet, it seems the underlying input stream does not reset the read b=
ytes, so the isFound() does not read anything at all.
> =C2=A0
> You can add the following test in the SieveIntegrationTest class, it does=
 not work.
> {{@Test}}
> {{void bodyTextShouldMatchContentWithBitcoin() throws Exception {}}
> {{=C2=A0 =C2=A0 prepareTestUsingScript("org/apache/james/transport/mailet=
s/delivery/bodyTextMatchBitcoin.script");}}{{=C2=A0 =C2=A0 }}
> {{FakeMail mail =3D FakeMail.builder()}}
> {{=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 .name("name")}}
> {{=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 .mimeMessage(MimeMessageUtil.=
mimeMessageFromStream(}}
> {{=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 C=
lassLoader.getSystemResourceAsStream("eml/titi.eml")))}}
> {{=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 .state(Mail.DEFAULT)}}
> {{=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 .recipient(RECEIVER_DOMAIN_CO=
M)}}
> {{=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 .sender("[email protected]")}}
> {{=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 .build();}}
> {{=C2=A0 =C2=A0 testee.service(mail);}}{{=C2=A0 =C2=A0 assertThatAttribut=
e(mail.getAttribute(ATTRIBUTE_NAME)).isEqualTo(ATTRIBUTE_SELECTED_MAILBOX);=
}}
> {{}}}
> =C2=A0



--
This message was sent by Atlassian Jira
(v8.20.10#820010)