Wednesday, January 5, 2011

Android Z-Push Issues

I've been testing Z-Push (r502/1.5) some more and ran into a frustrating bug when sending from an Android 2.2 emulator.

The problem was I was sending mail through the Android emulator and the body of all of these messages were getting garbled in Z-Push clients. I noticed this in an iPhone running 3.1.2 and the Android 2.2 emulator. The debug.txt file for Z-Push was saying things like "Detected an illegal character in input string" when attempting to read the copy of the message in my Sent folder or Inbox.


Basically, Android sends mail bodies as UTF-8, encoded in base64. When configured to send mail through Z-Push, the messages were being decoded from base64 and the decoded version of the body was being sent to the local sendmail binary. This was Very Bad because Z-Push was leaving the Content-Transfer-Encoding header as base64, meaning any attempt to MIME parse the body will treat the already-decoded base64 text as base64-encoded text. And when that happens, things look garbled.

It turns out Z-Push already had logic for dealing with base64-encoded bodies, but was not re-encoding the body before sending it to the sendmail binary. The problem was the following line in backend/imap.php:

255         // encode the body to base64 if it was sent originally in base64 by the pda
256         if ($body_base64 && !isset($forward)) $body = base64_encode($body);
For messages with base64 bodies, $body_base64 was being properly set to true. The problem was $forward. Forward will always be set, because it is a function parameter that defaults to false:

 123     function SendMail($rfc822, $forward = false, $reply = false, $parent = false) {
The result is the base64_encode will never run, regardless of the value of $body_base64. I changed the line to look like:
 255         // encode the body to base64 if it was sent originally in base64 by the pda
 256         if ($body_base64 && isset($forward) && !$forward) $body = base64_encode($body);
Which maybe wasn't the best fix since if $forward ever is not set as a default function parameter then this will fail again. But it did fix the problem and now I can send mail from an Android 2.2 emulator without a problem.

I should note that this flaw is present in r502/Z-Push 1.5 AND trunk. I should figure out how to let them know...

Hopefully this saves someone half the frustration I just experienced today tracking this down.

3 comments:

  1. Thank you very much for this.
    I noticed the bug with base64, but could not figure out how to correct it. So, as you said, it really saved me half the frustration!

    ReplyDelete
  2. Thanks! This also saved us a lot :-) Blogs like this are life-savers.

    ReplyDelete