andyedinborough/aenetmail — Issue #34: Unexpected tag ruins getResponse();
Author: piher
Created: 2012-02-19 15:33:09+00:00
State: open

Hi,

There is a mail in my mailbox that causes the getMessage(i,true); method to just stop.
After digging into it, it appears that the last lines of the stream are :

```)```
then
```xm0```
and finally
```76 OK Success```

whereas the last two lines expected are :
```)```
and then
```xm076 OK Success```

Since the code just tests if the last line contains
```xm076 OK Success```
by doing
```if (response.Contains(tag + "OK"))
break; ```
when the last line is ```76 OK Success``` the code just rolls back to GetResponse() wich causes the readLine() method to just sit there waiting for an imaginary end of the stream. (Eventually it will return null after a very long timeout)

I'm guessing that the the body length answered by the server is too much by one charachter.
Here's the size response :
```* 73 FETCH (UID 106 RFC822.SIZE 1765 FLAGS (\Seen) BODY[HEADER] {1372}```

If that is, I would suggest something like this :

```
public MailMessage[] GetMessages(string start, string end, bool uid, bool headersonly, bool setseen)
{
CheckMailboxSelected();
IdlePause();

string UID, HEADERS, SETSEEN;
UID = HEADERS = SETSEEN = String.Empty;
if (uid)
UID = "UID ";
if (headersonly)
HEADERS = "HEADER";
if (!setseen)
SETSEEN = ".PEEK";
string tag = GetTag();
string command = tag + UID + "FETCH " + start + ":" + end + " (UID RFC822.SIZE FLAGS BODY" + SETSEEN + "[" + HEADERS + "])";
string response;

string endOfStreamTmp = String.Empty;
string endOfStreamTag = tag + "OK";

var x = new List();
SendCommand(command);
while (true)
{
response = GetResponse();
// 3) We apend the latest response to the potential beginning
// if no potential beginning was found in 2) then endOfStreamTmp is empty which means
we are just comparing the response
endOfStreamTmp += response;
if (endOfStreamTmp.Contains(endOfStreamTag))
break;
endOfStreamTmp = String.Empty;
var m = rxGetBodyLength.Match(response);
if (!m.Success)
continue;
int length = m.Groups[1].Value.ToInt();
var mail = new MailMessage();
var body = new StringBuilder();
var buffer = new char[8192];
int read;

string bodyStr = string.Empty;

while (length > 0)
{
read = _Reader.Read(buffer, 0, Math.Min(length, buffer.Length));
body.Append(buffer, 0, read);
bodyStr = body.ToString();
length -= read;
}

// We are going to check if the body doesn't end with the beginning of the endOfStreamTag
bool tagSubStrNotFound = true;
for (int i = 1; i < endOfStreamTag.Length && tagSubStrNotFound; i++)
{
if (bodyStr.EndsWith(endOfStreamTag.Substring(0, i)))
{
// 2) if it does, we store the matching end wich is potentially the beginning of the endOfStreamTag
endOfStreamTmp = bodyStr.Substring(bodyStr.Length - 1 - i);
tagSubStrNotFound = false;
}
}
mail.Load(bodyStr, headersonly);
var m2 = rxUID.Match(response);
if (m2.Groups[1] != null)
mail.Uid = m2.Groups[1].ToString();
m2 = rxFlags.Match(response);
if (m2.Groups[1] != null)
mail.SetFlags(m2.Groups[1].ToString());
m2 = rxSize.Match(response);
if (m2.Groups[1] != null)
mail.Size = Convert.ToInt32(m2.Groups[1].ToString());

x.Add(mail);
}

IdleResume();
return x.ToArray();
}