[gmime: 5/8] Simplified base64 decoding logic for handling '=' padding
- From: Jeffrey Stedfast <fejj src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gmime: 5/8] Simplified base64 decoding logic for handling '=' padding
- Date: Fri, 3 Nov 2017 14:35:46 +0000 (UTC)
commit 9407e6347ace3300e34c40dd81f6ee5b705a092e
Author: Jeffrey Stedfast <jestedfa microsoft com>
Date: Tue Oct 31 17:19:30 2017 -0400
Simplified base64 decoding logic for handling '=' padding
This also fixes decoding base64 blobs that contain
'=' padding characters in the middle of the blob.
The old logic could output a nul-byte into the output.
gmime/gmime-encodings.c | 61 ++++++++++++++++++----------------------------
1 files changed, 24 insertions(+), 37 deletions(-)
---
diff --git a/gmime/gmime-encodings.c b/gmime/gmime-encodings.c
index 0d24353..0138253 100644
--- a/gmime/gmime-encodings.c
+++ b/gmime/gmime-encodings.c
@@ -511,60 +511,47 @@ g_mime_encoding_base64_decode_step (const unsigned char *inbuf, size_t inlen, un
register unsigned char *outptr;
const unsigned char *inend;
register guint32 saved;
- unsigned char c;
- int npad, n, i;
+ unsigned char last[2];
+ unsigned char c, rank;
+ int n;
inend = inbuf + inlen;
outptr = outbuf;
inptr = inbuf;
- npad = (*state >> 8) & 0xff;
- n = *state & 0xff;
saved = *save;
+ n = *state;
+
+ if (n < 0) {
+ last[0] = '=';
+ n = -n;
+ } else {
+ last[0] = '\0';
+ }
+
+ last[1] = '\0';
/* convert 4 base64 bytes to 3 normal bytes */
while (inptr < inend) {
- c = gmime_base64_rank[*inptr++];
- if (c != 0xff) {
- saved = (saved << 6) | c;
+ rank = gmime_base64_rank[(c = *inptr++)];
+ if (rank != 0xff) {
+ saved = (saved << 6) | rank;
+ last[1] = last[0];
+ last[0] = c;
n++;
if (n == 4) {
*outptr++ = saved >> 16;
- *outptr++ = saved >> 8;
- *outptr++ = saved;
+ if (last[1] != '=')
+ *outptr++ = saved >> 8;
+ if (last[0] != '=')
+ *outptr++ = saved;
n = 0;
-
- if (npad > 0) {
- outptr -= npad;
- npad = 0;
- }
}
}
}
- /* 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) {
- 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--;
- }
- }
-
- *state = (npad << 8) | n;
- *save = n ? saved : 0;
+ *state = last[0] == '=' ? -n : n;
+ *save = saved;
return (outptr - outbuf);
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]