Fix parsing of pop3 server replies.
Use mu_umaxtostr to format size_t and off_t values
Showing
1 changed file
with
52 additions
and
13 deletions
... | @@ -32,6 +32,7 @@ | ... | @@ -32,6 +32,7 @@ |
32 | #include <unistd.h> | 32 | #include <unistd.h> |
33 | #include <fcntl.h> | 33 | #include <fcntl.h> |
34 | #include <stdarg.h> | 34 | #include <stdarg.h> |
35 | #include <ctype.h> | ||
35 | 36 | ||
36 | #ifdef HAVE_ALLOCA_H | 37 | #ifdef HAVE_ALLOCA_H |
37 | # include <alloca.h> | 38 | # include <alloca.h> |
... | @@ -43,6 +44,7 @@ | ... | @@ -43,6 +44,7 @@ |
43 | 44 | ||
44 | #include <md5.h> | 45 | #include <md5.h> |
45 | 46 | ||
47 | #include <mu_umaxtostr.h> | ||
46 | #include <mailutils/attribute.h> | 48 | #include <mailutils/attribute.h> |
47 | #include <mailutils/auth.h> | 49 | #include <mailutils/auth.h> |
48 | #include <mailutils/body.h> | 50 | #include <mailutils/body.h> |
... | @@ -1022,6 +1024,40 @@ pop_get_message (mu_mailbox_t mbox, size_t msgno, mu_message_t *pmsg) | ... | @@ -1022,6 +1024,40 @@ pop_get_message (mu_mailbox_t mbox, size_t msgno, mu_message_t *pmsg) |
1022 | return 0; | 1024 | return 0; |
1023 | } | 1025 | } |
1024 | 1026 | ||
1027 | static int | ||
1028 | parse_answer0 (const char *buffer, size_t *n1, size_t *n2) | ||
1029 | { | ||
1030 | char *p; | ||
1031 | uintmax_t m; | ||
1032 | if (strlen (buffer) < 3 || memcmp (buffer, "+OK", 3)) | ||
1033 | return 1; | ||
1034 | m = *n1 = strtoumax (buffer + 3, &p, 10); | ||
1035 | if (!isspace (*p) || m != *n1) | ||
1036 | return 1; | ||
1037 | m = *n2 = strtoumax (p, &p, 10); | ||
1038 | if (!(*p == 0 || isspace (*p)) || m != *n2) | ||
1039 | return 1; | ||
1040 | return 0; | ||
1041 | } | ||
1042 | |||
1043 | static int | ||
1044 | parse_answer1 (const char *buffer, size_t *n1, char *buf, size_t bufsize) | ||
1045 | { | ||
1046 | char *p; | ||
1047 | uintmax_t m; | ||
1048 | if (strlen (buffer) < 3 || memcmp (buffer, "+OK", 3)) | ||
1049 | return 1; | ||
1050 | m = *n1 = strtoumax (buffer + 3, &p, 0); | ||
1051 | if (!isspace (*p) || m != *n1) | ||
1052 | return 1; | ||
1053 | while (*p && isspace (*p)) | ||
1054 | p++; | ||
1055 | if (strlen (p) >= bufsize) | ||
1056 | return 1; | ||
1057 | strcpy (buf, p); | ||
1058 | return 0; | ||
1059 | } | ||
1060 | |||
1025 | /* There is no such thing in pop all messages should be consider recent. | 1061 | /* There is no such thing in pop all messages should be consider recent. |
1026 | FIXME: We could cheat and peek at the status if it was not strip | 1062 | FIXME: We could cheat and peek at the status if it was not strip |
1027 | by the server ... */ | 1063 | by the server ... */ |
... | @@ -1099,14 +1135,13 @@ pop_messages_count (mu_mailbox_t mbox, size_t *pcount) | ... | @@ -1099,14 +1135,13 @@ pop_messages_count (mu_mailbox_t mbox, size_t *pcount) |
1099 | 1135 | ||
1100 | 1136 | ||
1101 | /* Parse the answer. */ | 1137 | /* Parse the answer. */ |
1102 | status = sscanf (mpd->buffer, "+OK %d %d", &(mpd->messages_count), | ||
1103 | &(mpd->size)); | ||
1104 | 1138 | ||
1139 | status = parse_answer0 (mpd->buffer, &mpd->messages_count, &mpd->size); | ||
1105 | /* Clear the state _after_ the scanf, since another thread could | 1140 | /* Clear the state _after_ the scanf, since another thread could |
1106 | start writing over mpd->buffer. */ | 1141 | start writing over mpd->buffer. */ |
1107 | CLEAR_STATE (mpd); | 1142 | CLEAR_STATE (mpd); |
1108 | 1143 | ||
1109 | if (status == EOF || status != 2) | 1144 | if (status) |
1110 | return EIO; | 1145 | return EIO; |
1111 | 1146 | ||
1112 | if (pcount) | 1147 | if (pcount) |
... | @@ -1182,8 +1217,9 @@ pop_expunge (mu_mailbox_t mbox) | ... | @@ -1182,8 +1217,9 @@ pop_expunge (mu_mailbox_t mbox) |
1182 | switch (mpd->state) | 1217 | switch (mpd->state) |
1183 | { | 1218 | { |
1184 | case POP_NO_STATE: | 1219 | case POP_NO_STATE: |
1185 | status = pop_writeline (mpd, "DELE %d\r\n", | 1220 | status = pop_writeline (mpd, "DELE %s\r\n", |
1186 | mpd->pmessages[i]->num); | 1221 | mu_umaxtostr (0, |
1222 | mpd->pmessages[i]->num)); | ||
1187 | CHECK_ERROR (mpd, status); | 1223 | CHECK_ERROR (mpd, status); |
1188 | MAILBOX_DEBUG0 (mbox, MU_DEBUG_PROT, mpd->buffer); | 1224 | MAILBOX_DEBUG0 (mbox, MU_DEBUG_PROT, mpd->buffer); |
1189 | mpd->state = POP_DELE; | 1225 | mpd->state = POP_DELE; |
... | @@ -1277,7 +1313,7 @@ pop_message_size (mu_message_t msg, size_t *psize) | ... | @@ -1277,7 +1313,7 @@ pop_message_size (mu_message_t msg, size_t *psize) |
1277 | switch (mpd->state) | 1313 | switch (mpd->state) |
1278 | { | 1314 | { |
1279 | case POP_NO_STATE: | 1315 | case POP_NO_STATE: |
1280 | status = pop_writeline (mpd, "LIST %d\r\n", mpm->num); | 1316 | status = pop_writeline (mpd, "LIST %s\r\n", mu_umaxtostr (0, mpm->num)); |
1281 | CHECK_ERROR (mpd, status); | 1317 | CHECK_ERROR (mpd, status); |
1282 | MAILBOX_DEBUG0 (mpd->mbox, MU_DEBUG_PROT, mpd->buffer); | 1318 | MAILBOX_DEBUG0 (mpd->mbox, MU_DEBUG_PROT, mpd->buffer); |
1283 | mpd->state = POP_LIST; | 1319 | mpd->state = POP_LIST; |
... | @@ -1302,10 +1338,11 @@ pop_message_size (mu_message_t msg, size_t *psize) | ... | @@ -1302,10 +1338,11 @@ pop_message_size (mu_message_t msg, size_t *psize) |
1302 | break; | 1338 | break; |
1303 | } | 1339 | } |
1304 | 1340 | ||
1305 | status = sscanf (mpd->buffer, "+OK %d %d\n", &num, &mpm->mu_message_size); | 1341 | /* FIXME */ |
1342 | status = parse_answer0 (mpd->buffer, &num, &mpm->mu_message_size); | ||
1306 | CLEAR_STATE (mpd); | 1343 | CLEAR_STATE (mpd); |
1307 | 1344 | ||
1308 | if (status != 2) | 1345 | if (status != 0) |
1309 | status = MU_ERR_PARSE; | 1346 | status = MU_ERR_PARSE; |
1310 | 1347 | ||
1311 | /* The size of the message is with the extra '\r' octet for everyline. | 1348 | /* The size of the message is with the extra '\r' octet for everyline. |
... | @@ -1495,7 +1532,7 @@ pop_uidl (mu_message_t msg, char *buffer, size_t buflen, size_t *pnwriten) | ... | @@ -1495,7 +1532,7 @@ pop_uidl (mu_message_t msg, char *buffer, size_t buflen, size_t *pnwriten) |
1495 | switch (mpd->state) | 1532 | switch (mpd->state) |
1496 | { | 1533 | { |
1497 | case POP_NO_STATE: | 1534 | case POP_NO_STATE: |
1498 | status = pop_writeline (mpd, "UIDL %d\r\n", mpm->num); | 1535 | status = pop_writeline (mpd, "UIDL %s\r\n", mu_umaxtostr (0, mpm->num)); |
1499 | CHECK_ERROR (mpd, status); | 1536 | CHECK_ERROR (mpd, status); |
1500 | MAILBOX_DEBUG0 (mpd->mbox, MU_DEBUG_PROT, mpd->buffer); | 1537 | MAILBOX_DEBUG0 (mpd->mbox, MU_DEBUG_PROT, mpd->buffer); |
1501 | mpd->state = POP_UIDL; | 1538 | mpd->state = POP_UIDL; |
... | @@ -1522,8 +1559,8 @@ pop_uidl (mu_message_t msg, char *buffer, size_t buflen, size_t *pnwriten) | ... | @@ -1522,8 +1559,8 @@ pop_uidl (mu_message_t msg, char *buffer, size_t buflen, size_t *pnwriten) |
1522 | 1559 | ||
1523 | /* FIXME: I should cache the result. */ | 1560 | /* FIXME: I should cache the result. */ |
1524 | *uniq = '\0'; | 1561 | *uniq = '\0'; |
1525 | status = sscanf (mpd->buffer, "+OK %d %127s\n", &num, uniq); | 1562 | status = parse_answer1 (mpd->buffer, &num, uniq, sizeof uniq); |
1526 | if (status != 2) | 1563 | if (status) |
1527 | { | 1564 | { |
1528 | status = MU_ERR_PARSE; | 1565 | status = MU_ERR_PARSE; |
1529 | buflen = 0; | 1566 | buflen = 0; |
... | @@ -1590,7 +1627,8 @@ pop_top (mu_header_t header, char *buffer, size_t buflen, | ... | @@ -1590,7 +1627,8 @@ pop_top (mu_header_t header, char *buffer, size_t buflen, |
1590 | case POP_NO_STATE: | 1627 | case POP_NO_STATE: |
1591 | if (mpd->capa & CAPA_TOP) | 1628 | if (mpd->capa & CAPA_TOP) |
1592 | { | 1629 | { |
1593 | status = pop_writeline (mpd, "TOP %d 0\r\n", mpm->num); | 1630 | status = pop_writeline (mpd, "TOP %s 0\r\n", |
1631 | mu_umaxtostr (0, mpm->num)); | ||
1594 | CHECK_ERROR (mpd, status); | 1632 | CHECK_ERROR (mpd, status); |
1595 | MAILBOX_DEBUG0 (mpd->mbox, MU_DEBUG_PROT, mpd->buffer); | 1633 | MAILBOX_DEBUG0 (mpd->mbox, MU_DEBUG_PROT, mpd->buffer); |
1596 | mpd->state = POP_TOP; | 1634 | mpd->state = POP_TOP; |
... | @@ -1815,7 +1853,8 @@ pop_retr (pop_message_t mpm, char *buffer, size_t buflen, | ... | @@ -1815,7 +1853,8 @@ pop_retr (pop_message_t mpm, char *buffer, size_t buflen, |
1815 | { | 1853 | { |
1816 | case POP_NO_STATE: | 1854 | case POP_NO_STATE: |
1817 | mpm->body_lines = mpm->body_size = 0; | 1855 | mpm->body_lines = mpm->body_size = 0; |
1818 | status = pop_writeline (mpd, "RETR %d\r\n", mpm->num); | 1856 | status = pop_writeline (mpd, "RETR %s\r\n", |
1857 | mu_umaxtostr (0, mpm->num)); | ||
1819 | MAILBOX_DEBUG0 (mpd->mbox, MU_DEBUG_PROT, mpd->buffer); | 1858 | MAILBOX_DEBUG0 (mpd->mbox, MU_DEBUG_PROT, mpd->buffer); |
1820 | CHECK_ERROR (mpd, status); | 1859 | CHECK_ERROR (mpd, status); |
1821 | mpd->state = POP_RETR; | 1860 | mpd->state = POP_RETR; | ... | ... |
-
Please register or sign in to post a comment