1 /*
2 Copyright (C) 2000-2001 Dawit Alemayehu <adawit@kde.org>
3 Copyright (C) 2006 Alexey Proskuryakov <ap@webkit.org>
4 Copyright (C) 2007, 2008 Apple Inc. All rights reserved.
5
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU Lesser General Public License (LGPL)
8 version 2 as published by the Free Software Foundation.
9
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
14
15 You should have received a copy of the GNU Library General Public
16 License along with this program; if not, write to the Free Software
17 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
18
19 This code is based on the java implementation in HTTPClient
20 package by Ronald Tschalär Copyright (C) 1996-1999.
21 */
22
23 #include "config.h"
24 #include "Base64.h"
25
26 #include <limits.h>
27
28 #include <wtf/Platform.h>
29 #include <wtf/StringExtras.h>
30
31 namespace WebCore {
32
33 static const char base64EncMap[64] = {
34 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48,
35 0x49, 0x4A, 0x4B, 0x4C, 0x4D, 0x4E, 0x4F, 0x50,
36 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58,
37 0x59, 0x5A, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66,
38 0x67, 0x68, 0x69, 0x6A, 0x6B, 0x6C, 0x6D, 0x6E,
39 0x6F, 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76,
40 0x77, 0x78, 0x79, 0x7A, 0x30, 0x31, 0x32, 0x33,
41 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x2B, 0x2F
42 };
43
44 static const char base64DecMap[128] = {
45 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
46 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
47 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
48 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
49 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
50 0x00, 0x00, 0x00, 0x3E, 0x00, 0x00, 0x00, 0x3F,
51 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3A, 0x3B,
52 0x3C, 0x3D, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
53 0x00, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06,
54 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E,
55 0x0F, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16,
56 0x17, 0x18, 0x19, 0x00, 0x00, 0x00, 0x00, 0x00,
57 0x00, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F, 0x20,
58 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28,
59 0x29, 0x2A, 0x2B, 0x2C, 0x2D, 0x2E, 0x2F, 0x30,
60 0x31, 0x32, 0x33, 0x00, 0x00, 0x00, 0x00, 0x00
61 };
62
base64Encode(const Vector<char> & in,Vector<char> & out,bool insertLFs)63 void base64Encode(const Vector<char>& in, Vector<char>& out, bool insertLFs)
64 {
65 out.clear();
66 if (in.isEmpty())
67 return;
68
69 // If the input string is pathologically large, just return nothing.
70 // Note: Keep this in sync with the "out_len" computation below.
71 // Rather than being perfectly precise, this is a bit conservative.
72 const unsigned maxInputBufferSize = UINT_MAX / 77 * 76 / 4 * 3 - 2;
73 if (in.size() > maxInputBufferSize)
74 return;
75
76 unsigned sidx = 0;
77 unsigned didx = 0;
78 const char* data = in.data();
79 const unsigned len = in.size();
80
81 unsigned out_len = ((len + 2) / 3) * 4;
82
83 // Deal with the 76 character per line limit specified in RFC 2045.
84 insertLFs = (insertLFs && out_len > 76);
85 if (insertLFs)
86 out_len += ((out_len - 1) / 76);
87
88 int count = 0;
89 out.grow(out_len);
90
91 // 3-byte to 4-byte conversion + 0-63 to ascii printable conversion
92 if (len > 1) {
93 while (sidx < len - 2) {
94 if (insertLFs) {
95 if (count && (count % 76) == 0)
96 out[didx++] = '\n';
97 count += 4;
98 }
99 out[didx++] = base64EncMap[(data[sidx] >> 2) & 077];
100 out[didx++] = base64EncMap[((data[sidx + 1] >> 4) & 017) | ((data[sidx] << 4) & 077)];
101 out[didx++] = base64EncMap[((data[sidx + 2] >> 6) & 003) | ((data[sidx + 1] << 2) & 077)];
102 out[didx++] = base64EncMap[data[sidx + 2] & 077];
103 sidx += 3;
104 }
105 }
106
107 if (sidx < len) {
108 if (insertLFs && (count > 0) && (count % 76) == 0)
109 out[didx++] = '\n';
110
111 out[didx++] = base64EncMap[(data[sidx] >> 2) & 077];
112 if (sidx < len - 1) {
113 out[didx++] = base64EncMap[((data[sidx + 1] >> 4) & 017) | ((data[sidx] << 4) & 077)];
114 out[didx++] = base64EncMap[(data[sidx + 1] << 2) & 077];
115 } else
116 out[didx++] = base64EncMap[(data[sidx] << 4) & 077];
117 }
118
119 // Add padding
120 while (didx < out.size()) {
121 out[didx] = '=';
122 didx++;
123 }
124 }
125
base64Decode(const Vector<char> & in,Vector<char> & out)126 bool base64Decode(const Vector<char>& in, Vector<char>& out)
127 {
128 out.clear();
129
130 // If the input string is pathologically large, just return nothing.
131 if (in.size() > UINT_MAX)
132 return false;
133
134 return base64Decode(in.data(), in.size(), out);
135 }
136
base64Decode(const char * data,unsigned len,Vector<char> & out)137 bool base64Decode(const char* data, unsigned len, Vector<char>& out)
138 {
139 out.clear();
140 if (len == 0)
141 return true;
142
143 while (len && data[len-1] == '=')
144 --len;
145
146 out.grow(len);
147 for (unsigned idx = 0; idx < len; idx++) {
148 unsigned char ch = data[idx];
149 if ((ch > 47 && ch < 58) || (ch > 64 && ch < 91) || (ch > 96 && ch < 123) || ch == '+' || ch == '/' || ch == '=')
150 out[idx] = base64DecMap[ch];
151 else
152 return false;
153 }
154
155 // 4-byte to 3-byte conversion
156 unsigned outLen = len - ((len + 3) / 4);
157 if (!outLen || ((outLen + 2) / 3) * 4 < len)
158 return false;
159
160 unsigned sidx = 0;
161 unsigned didx = 0;
162 if (outLen > 1) {
163 while (didx < outLen - 2) {
164 out[didx] = (((out[sidx] << 2) & 255) | ((out[sidx + 1] >> 4) & 003));
165 out[didx + 1] = (((out[sidx + 1] << 4) & 255) | ((out[sidx + 2] >> 2) & 017));
166 out[didx + 2] = (((out[sidx + 2] << 6) & 255) | (out[sidx + 3] & 077));
167 sidx += 4;
168 didx += 3;
169 }
170 }
171
172 if (didx < outLen)
173 out[didx] = (((out[sidx] << 2) & 255) | ((out[sidx + 1] >> 4) & 003));
174
175 if (++didx < outLen)
176 out[didx] = (((out[sidx + 1] << 4) & 255) | ((out[sidx + 2] >> 2) & 017));
177
178 if (outLen < out.size())
179 out.shrink(outLen);
180
181 return true;
182 }
183
184 }
185