Android Question Any means of selecting the type of base64 attachment extracted?

William Hunter

Active Member
Licensed User
Longtime User
Email messages in Mime format can contain base64 encoded attachments such as mp4 video files etc. The code below is from the MailParser, and is used to extract (download) attachments. Is there any way to modify this code so that attachments that are appended to the message, such as mp4, pdf etc files, are not extracted? Other attachments, that are inserted into the message, rather than appended, should continue to be extracted.

Every once in a while receiving a message with a very large appended attachment will freeze the Android device. I would like to have a means of rejecting these attachment types so that they are not extracted. Any help is greatly appreciated.

Regards
B4X:
Sub ParseMultipartBody (Mail As String, msg As Message)
    'find first boundary
    index = Mail.IndexOf2("--" & boundary, index)
    ReadNextLine(Mail)
    Dim headers As StringBuilder
    headers.Initialize
    Do While index < Mail.Length
        Dim line As String
        line = ReadNextLine(Mail)
        If line.Length > 0 Then
            headers.Append(line).Append(" ")
        Else If index < Mail.Length Then
            Dim nextPart As Int
            nextPart = Mail.IndexOf2("--" & boundary, index)
            If nextPart-4 > index Then
                HandlePart(headers.ToString, Mail.SubString2(index, nextPart-4), msg)
            End If
            If nextPart = -1 Then Return
            index = nextPart
            ReadNextLine(Mail)
            headers.Initialize
        End If
    Loop
End Sub

Sub HandlePart(Headers As String, Body As String, Msg As Message)
    If Regex.Matcher2("Content-Transfer-Encoding:\s*base64", _
        Regex.CASE_INSENSITIVE, Headers).Find Then
        'we are dealing with an attachment
        Dim filename As String
        Dim m As Matcher
        m = Regex.Matcher2("filename=\s*q([^q]+)q".Replace("q", QUOTE), Regex.CASE_INSENSITIVE, Headers)
        If m.Find Then filename = m.Group(1) Else filename = "attachment" & (Msg.Attachments.Size + 1)
        Dim su As StringUtils
        Dim out As OutputStream
        out = File.OpenOutput(dir, filename, False)
        Dim data() As Byte
        data = su.DecodeBase64(Body)
        Log("file saved: "  & filename & " (" & data.Length & " bytes)")
        out.WriteBytes(data, 0, data.Length)
        out.Close
        Msg.Attachments.Add(filename)
    Else If Regex.Matcher2("Content-Type:\s*text/", _
        Regex.CASE_INSENSITIVE, Headers).Find Then
        Msg.Body = Body
    End If
End Sub
 

Erel

B4X founder
Staff member
Licensed User
Longtime User
Make sure to test performance in release mode.

You cannot simply skip over a "part" as the parts length is unknown. So you must read the string one line after another until you find the next boundary.

The question is which step is the slow step. Finding the next boundary or decoding base 64 string. If you are lucky and it is the decoding part that is slow then you can check the Body length in HandlePart and don't do anything if it is too large.
 
Upvote 0
Top