[gmime] Fix for base64 decoder
- From: Jeffrey Stedfast <fejj src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gmime] Fix for base64 decoder
- Date: Thu, 2 Sep 2010 02:12:29 +0000 (UTC)
commit 30ddec4da69590fdeb15efbb833ce0dbb2b70b45
Author: Jeffrey Stedfast <fejj gnome org>
Date: Wed Sep 1 22:12:05 2010 -0400
Fix for base64 decoder
2010-09-01 Jeffrey Stedfast <fejj novell com>
* gmime/gmime-encodings.c (g_mime_encoding_base64_decode_step):
Need to keep state to keep track of the number of ='s we've
backed
out over in case it crosses buffer boundaries.
ChangeLog | 6 +++++
gmime/gmime-encodings.c | 49 ++++++++++++++++++++++++++++++----------------
2 files changed, 38 insertions(+), 17 deletions(-)
---
diff --git a/ChangeLog b/ChangeLog
index eb4e88e..80c5ac5 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,9 @@
+2010-09-01 Jeffrey Stedfast <fejj novell com>
+
+ * gmime/gmime-encodings.c (g_mime_encoding_base64_decode_step):
+ Need to keep state to keep track of the number of ='s we've backed
+ out over in case it crosses buffer boundaries.
+
2010-08-30 Jeffrey Stedfast <fejj novell com>
* gmime/gmime-param.c (decode_token): Make less strict in order to
diff --git a/gmime/gmime-encodings.c b/gmime/gmime-encodings.c
index 4aabbe7..df8b9d9 100644
--- a/gmime/gmime-encodings.c
+++ b/gmime/gmime-encodings.c
@@ -506,45 +506,60 @@ g_mime_encoding_base64_decode_step (const unsigned char *inbuf, size_t inlen, un
const unsigned char *inend;
register guint32 saved;
unsigned char c;
- int i;
+ int npad, n, i;
inend = inbuf + inlen;
outptr = outbuf;
+ inptr = inbuf;
- /* convert 4 base64 bytes to 3 normal bytes */
+ npad = (*state >> 8) & 0xff;
+ n = *state & 0xff;
saved = *save;
- i = *state;
- inptr = inbuf;
+
+ /* convert 4 base64 bytes to 3 normal bytes */
while (inptr < inend) {
c = gmime_base64_rank[*inptr++];
if (c != 0xff) {
saved = (saved << 6) | c;
- i++;
- if (i == 4) {
+ n++;
+ if (n == 4) {
*outptr++ = saved >> 16;
*outptr++ = saved >> 8;
*outptr++ = saved;
- i = 0;
+ n = 0;
+
+ if (npad > 0) {
+ outptr -= npad;
+ npad = 0;
+ }
}
}
}
- *save = saved;
- *state = i;
-
- /* quick scan back for '=' on the end somewhere */
- /* fortunately we can drop 1 output char for each trailing = (upto 2) */
- i = 2;
- while (inptr > inbuf && i) {
+ /* quickly scan back for '=' on the end somewhere */
+ /* fortunately we can drop 1 output char for each trailing '=' (up to 2) */
+ for (i = 2; inptr > inbuf && i; ) {
inptr--;
if (gmime_base64_rank[*inptr] != 0xff) {
- if (*inptr == '=' && outptr > outbuf)
- outptr--;
+ if (*inptr == '=' && outptr > outbuf) {
+ if (n == 0) {
+ /* we've got a complete quartet so it's
+ safe to drop an output character. */
+ outptr--;
+ } else if (npad < 2) {
+ /* keep a record of the number of ='s at
+ the end of the input stream, up to 2 */
+ npad++;
+ }
+ }
+
i--;
}
}
- /* if i != 0 then there is a truncation error! */
+ *state = (npad << 8) | n;
+ *save = saved;
+
return (outptr - outbuf);
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]