Benoit Tellier created JAMES-4112:
-------------------------------------

             Summary: Invalid quoted body part causes processing failure
                 Key: JAMES-4112
                 URL: https://issues.apache.org/jira/browse/JAMES-4112
             Project: James Server
          Issue Type: Improvement
          Components: MailStore & MailRepository
    Affects Versions: master
            Reporter: Benoit Tellier
             Fix For: master


Given an email with the following header in a body part:

{code:java}
Content-Type: image/png;
        x-unix-mode=0666;
        name="Outlook-Icon
{code}

And the mail processor tries to modifies header (eg RSPAMD scoring)

Then the mail split duplicates the email. The header change causes a full on 
disk update that fails on the invalid part.


{code:java}
jakarta.mail.internet.ParseException: Unbalanced quoted string
        at 
jakarta.mail.internet.HeaderTokenizer.collectString(HeaderTokenizer.java:390)
        at 
jakarta.mail.internet.HeaderTokenizer.getNext(HeaderTokenizer.java:322)
        at jakarta.mail.internet.HeaderTokenizer.next(HeaderTokenizer.java:222)
        at jakarta.mail.internet.HeaderTokenizer.next(HeaderTokenizer.java:183)
        at jakarta.mail.internet.ParameterList.<init>(ParameterList.java:262)
        at jakarta.mail.internet.ContentType.<init>(ContentType.java:90)
        at 
jakarta.mail.internet.MimeBodyPart.updateHeaders(MimeBodyPart.java:1497)
        at 
jakarta.mail.internet.MimeBodyPart.updateHeaders(MimeBodyPart.java:1156)
        at 
jakarta.mail.internet.MimeMultipart.updateHeaders(MimeMultipart.java:509)
        at 
jakarta.mail.internet.MimeBodyPart.updateHeaders(MimeBodyPart.java:1520)
        at 
jakarta.mail.internet.MimeBodyPart.updateHeaders(MimeBodyPart.java:1156)
        at 
jakarta.mail.internet.MimeMultipart.updateHeaders(MimeMultipart.java:509)
        at 
jakarta.mail.internet.MimeBodyPart.updateHeaders(MimeBodyPart.java:1520)
        at 
jakarta.mail.internet.MimeMessage.updateHeaders(MimeMessage.java:2270)
        at jakarta.mail.internet.MimeMessage.saveChanges(MimeMessage.java:2230)
        at 
org.apache.james.server.core.MimeMessageWrapper.writeTo(MimeMessageWrapper.java:323)
        at 
org.apache.james.server.core.MimeMessageWrapper.writeTo(MimeMessageWrapper.java:301)
        at 
org.apache.james.server.core.MimeMessageWrapper.writeTo(MimeMessageWrapper.java:297)
        at 
org.apache.james.server.core.MimeMessageWrapper.writeTo(MimeMessageWrapper.java:281)
        at 
org.apache.james.server.core.MimeMessageWrapper.<init>(MimeMessageWrapper.java:163)
        at org.apache.james.server.core.MailImpl.setMessage(MailImpl.java:505)
        at 
com.github.fge.lambdas.consumers.ConsumerChainer.lambda$sneakyThrow$9(ConsumerChainer.java:73)
        at java.base/java.util.Optional.ifPresent(Unknown Source)
        at 
org.apache.james.server.core.MailImpl$Builder.build(MailImpl.java:279)
        at org.apache.james.server.core.MailImpl.duplicate(MailImpl.java:99)
        at 
org.apache.james.mailetcontainer.impl.MatcherSplitter.split(MatcherSplitter.java:149)
        at 
org.apache.james.mailetcontainer.impl.MailetProcessorImpl.lambda$executeProcessingStep$3(MailetProcessorImpl.java:161)
        at 
com.github.fge.lambdas.functions.FunctionChainer.lambda$sneakyThrow$49(FunctionChainer.java:74)
        at 
java.base/java.util.stream.ReferencePipeline$7$1FlatMap.accept(Unknown Source)
        at java.base/java.util.Collections$2.tryAdvance(Unknown Source)
        at java.base/java.util.Collections$2.forEachRemaining(Unknown Source)
        at java.base/java.util.stream.AbstractPipeline.copyInto(Unknown Source)
        at java.base/java.util.stream.AbstractPipeline.wrapAndCopyInto(Unknown 
Source)
        at 
java.base/java.util.stream.ReduceOps$ReduceOp.evaluateSequential(Unknown Source)
        at java.base/java.util.stream.AbstractPipeline.evaluate(Unknown Source)
        at java.base/java.util.stream.ReferencePipeline.collect(Unknown Source)
        at 
org.apache.james.mailetcontainer.impl.MailetProcessorImpl.executeProcessingStep(MailetProcessorImpl.java:162)
        at 
org.apache.james.mailetcontainer.impl.MailetProcessorImpl.lambda$service$0(MailetProcessorImpl.java:133)
        at java.base/java.util.stream.ReduceOps$1ReducingSink.accept(Unknown 
Source)
        at 
java.base/java.util.Spliterators$ArraySpliterator.forEachRemaining(Unknown 
Source)
        at java.base/java.util.stream.AbstractPipeline.copyInto(Unknown Source)
        at java.base/java.util.stream.AbstractPipeline.wrapAndCopyInto(Unknown 
Source)
        at 
java.base/java.util.stream.ReduceOps$ReduceOp.evaluateSequential(Unknown Source)
        at java.base/java.util.stream.AbstractPipeline.evaluate(Unknown Source)
        at java.base/java.util.stream.ReferencePipeline.reduce(Unknown Source)
        at 
org.apache.james.mailetcontainer.impl.MailetProcessorImpl.service(MailetProcessorImpl.java:131)
        at 
org.apache.james.mailetcontainer.lib.AbstractStateCompositeProcessor.handleWithProcessor(AbstractStateCompositeProcessor.java:98)
        at 
org.apache.james.mailetcontainer.lib.AbstractStateCompositeProcessor.service(AbstractStateCompositeProcessor.java:80)
        at 
org.apache.james.mailetcontainer.impl.JamesMailSpooler$Runner.performProcessMail(JamesMailSpooler.java:135)
        at 
org.apache.james.mailetcontainer.impl.JamesMailSpooler$Runner.lambda$processMail$4(JamesMailSpooler.java:127)
        at reactor.core.publisher.MonoRunnable.subscribe(MonoRunnable.java:49)
        at reactor.core.publisher.MonoUsing.subscribe(MonoUsing.java:109)
        at reactor.core.publisher.Mono.subscribe(Mono.java:4568)
        at 
reactor.core.publisher.FluxFlatMap.trySubscribeScalarMap(FluxFlatMap.java:202)
        at 
reactor.core.publisher.MonoFlatMap.subscribeOrReturn(MonoFlatMap.java:53)
        at reactor.core.publisher.Mono.subscribe(Mono.java:4552)
        at 
reactor.core.publisher.MonoSubscribeOn$SubscribeOnSubscriber.run(MonoSubscribeOn.java:126)
        at reactor.core.scheduler.WorkerTask.call(WorkerTask.java:84)
        at reactor.core.scheduler.WorkerTask.call(WorkerTask.java:37)
        at java.base/java.util.concurrent.FutureTask.run(Unknown Source)
        at 
java.base/java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(Unknown
 Source)
        at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown 
Source)
        at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown 
Source)
        at java.base/java.lang.Thread.run(Unknown Source)
{code}

I had a look: no way to make the parsing more lenient. And also sanitizing 
things would be pretty bad (DKIM violation and very verbose)

To be fairly honest I do not understand why a header update would cause body 
part changes. Header changes are already handled off-band so no on-disk update 
seems mandated. By avoid updating content that did not change we would solve 
this issue in addition of potentially nice performance benefits!




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

---------------------------------------------------------------------
To unsubscribe, e-mail: server-dev-unsubscr...@james.apache.org
For additional commands, e-mail: server-dev-h...@james.apache.org

Reply via email to