Kevin Doran created NIFI-4339:
---------------------------------

             Summary: Possible NPE in ExtractEmailHeaders if no recipients exist
                 Key: NIFI-4339
                 URL: https://issues.apache.org/jira/browse/NIFI-4339
             Project: Apache NiFi
          Issue Type: Bug
          Components: Extensions
            Reporter: Kevin Doran
            Assignee: Kevin Doran
            Priority: Minor
             Fix For: 1.4.0


A user uncovered a *NullPointerException* in the ExtractEmailHeaders processor 
and [asked about it on 
StackOverflow|https://stackoverflow.com/questions/45927852/nifi-email-consumeimap-filter-by-subject-from-to-and-date].

Here is the summary: If the TO, CC, and BCC are not present in the email 
message, a call to {{javax.mail.internet.MimeMessage getAllRecipients()}} will 
return {{null}}.

While this is a rare case, the reporter has a use case in which an email 
account is sending automated emails to the same address as the source, and 
whatever email program is being used appears to not set any address fields in 
this case:

{quote}It is an auto email from client to their own inbox and does not have 
"to", "cc"and "bcc"{quote}

The {{javax.mail.Message getAllRecipients()}} method, which is called from 
{{javax.mail.internet.MimeMessage getAllRecipients()}}, will return null in 
this case, as is documented and apparent from the source code:

{code:java}
    /**
     * Get all the recipient addresses for the message.
     * The default implementation extracts the TO, CC, and BCC
     * recipients using the <code>getRecipients</code> method. <p>
     *
     * This method returns <code>null</code> if none of the recipient
     * headers are present in this message.  It may Return an empty array
     * if any recipient header is present, but contains no addresses.
     *
     * @return          array of Address objects
     * @exception       MessagingException
     */
    public Address[] getAllRecipients() throws MessagingException {
        Address[] to = getRecipients(RecipientType.TO);
        Address[] cc = getRecipients(RecipientType.CC);
        Address[] bcc = getRecipients(RecipientType.BCC);

        if (cc == null && bcc == null)
            return to;          // a common case
        
        // ...
{code}

Here is a stack trace for the NPE:

{noformat}
2017-08-30 16:36:05,930 ERROR [Timer-Driven Process Thread-8] 
o.a.n.p.email.ExtractEmailHeaders ExtractEmailHeaders [...] Could not parse the 
flowfile StandardFlowFileRecord [...] as an email, treating as failure: 
java.lang.NullPointerException: null 
    at java.lang.reflect.Array.getLength(Native Method) 
    at 
org.apache.nifi.processors.email.ExtractEmailHeaders$1.proce‌​ss(ExtractEmailHeade‌​rs.java:171)
 
    at 
org.apache.nifi.controller.repository.StandardProcessSession‌​.read(StandardProces‌​sSession.java:2177)
 
    at 
org.apache.nifi.controller.repository.StandardProcessSession‌​.read(StandardProces‌​sSession.java:2147)
 
    at 
org.apache.nifi.processors.email.ExtractEmailHeaders.onTrigg‌​er(ExtractEmailHeade‌​rs.java:146)
 
    at 
org.apache.nifi.processor.AbstractProcessor.onTrigger(Abstra‌​ctProcessor.java:27)
 
    at 
org.apache.nifi.controller.StandardProcessorNode.onTrigger(S‌​tandardProcessorNode‌​.java:1118)
 
    at 
org.apache.nifi.controller.tasks.ContinuallyRunProcessorTask‌​.call(ContinuallyRun‌​ProcessorTask.java:1‌​47)
 
    at 
org.apache.nifi.controller.tasks.ContinuallyRunProcessorTask‌​.call(ContinuallyRun‌​ProcessorTask.java:4‌​7)
 
    at 
org.apache.nifi.controller.scheduling.TimerDrivenSchedulingA‌​gent$1.run(TimerDriv‌​enSchedulingAgent.ja‌​va:132)
 
    at 
java.util.concurrent.Executors$RunnableAdapter.call(Executor‌​s.java:511) 
    at java.util.concurrent.FutureTask.runAndReset(FutureTask.java:‌​308)
{noformat}

The NPE occurs as ExtractEmailHeaders:L171:

{code:java}
if (Array.getLength(originalMessage.getAllRecipients()) > 0) {
{code}

{{Array.getLength(Array array)}} expects a non-null argument, but 
{{originalMessage.getAllRecipients()}} is returning {{null}}.

One proposed solution is to check if {{originalMessage.getAllRecipients()}} is 
{{null}}, and if so, treat it as an empty array. That is, the condition would 
be:

{code:java}
Address[] allRecipients = originalMessage.getAllRecipients();
if (allRecipients != null && Array.getLength(allRecipients) > 0) {
{code}

A test case for ExtractEmailHeaders that reproduces this NPE should also be 
added.



--
This message was sent by Atlassian JIRA
(v6.4.14#64029)

Reply via email to