[Kde-pim] Hunting down #291171 and other filtering issues

Szymon Tomasz Stefanek pragma at kvirc.net
Sat Feb 25 05:47:32 GMT 2012


Hi all!

Tonight #291171 made me mad enough: I can no longer stand it.
I either fix it or throw the computer out of the window :D

The bug is related to filters that break the Content-Type header turning
multipart/mixed data into text/plain.

[ see https://bugs.kde.org/show_bug.cgi?id=291171 ]

I've hunted it and I need a hint.

In turns out that it's an issue related to how KMime::Message manages 
multipart data. The KMime::Content::parse() method decodes the body
of the message from its "body" member. If the message is a multipart one
then the "body" member will be cleared as the data is stored in a separate 
list of contents (and the documentation even states that).

Now the filter components (search patterns and actions) tend to call the
parse() method multiple times. The second time it's called on a multipart
message, however, it fails since it finds an empty body which clearly isn't
multipart. The method then assumes that the message is broken and
sets the Content-Type header to text/plain.

If a matching filter is expected to change the body of a message (like the
spam filters of any kind) then a payload store is issued and the message is
saved back to the storage, broken. Et voilĂ .

The KMime::Content::parse() behaviour also breaks filter matching rules that
operate on the message body...  and in fact I wouldn't be surprised if it 
broke some other code that naively operates on body() without proper
multipart data handling.

Now there may be different approaches to a fix for this.

1) Fix the filtering bug only: remove all the parse() calls from the filters as
	Akonadi seems to call parse() itself at the moment the message is fetched.
	KMime never tries to parse an empty body and it never updates the Content-
	Type header... maybe.

2) Change KMime::Content::parse() to NOT wipe out the body member.
	This will allow the method to be called multiple times. However there might
	be some code around that relies on the empty body after parse() ?

2.a) Change KMime::Content::parse() to store the message body in an auxiliary
	var and let the body member be cleared. When parse() is called again with
	the body member empty try to restore it from auxiliary.
	Possibly backward compatible but will make the multipart messages twice as
	big in RAM. I've actually tried this: it fixes the bug.

3) Fix KMime::Content::parse() by making it a null operation if it has already 
	been called and the contents weren't reset. Looks like having less side
	effects but I'm not really sure.

Which way would you suggest? 1? 2? 3? Something else?

-- 

Szymon Tomasz Stefanek

------------------------------------------------------------------------------
-
- Enter any 11-digit prime to continue
-
------------------------------------------------------------------------------


_______________________________________________
KDE PIM mailing list kde-pim at kde.org
https://mail.kde.org/mailman/listinfo/kde-pim
KDE PIM home page at http://pim.kde.org/



More information about the kde-pim mailing list