|
Lines 2-7
WebCore/platform/text/Base64.cpp_sec1
|
| 2 |
Copyright (C) 2000-2001 Dawit Alemayehu <adawit@kde.org> |
2 |
Copyright (C) 2000-2001 Dawit Alemayehu <adawit@kde.org> |
| 3 |
Copyright (C) 2006 Alexey Proskuryakov <ap@webkit.org> |
3 |
Copyright (C) 2006 Alexey Proskuryakov <ap@webkit.org> |
| 4 |
Copyright (C) 2007, 2008 Apple Inc. All rights reserved. |
4 |
Copyright (C) 2007, 2008 Apple Inc. All rights reserved. |
|
|
5 |
Copyright (C) 2010 Patrick Gansterer <paroga@paroga.com> |
| 5 |
|
6 |
|
| 6 |
This program is free software; you can redistribute it and/or modify |
7 |
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 |
it under the terms of the GNU Lesser General Public License (LGPL) |
|
Lines 25-30
WebCore/platform/text/Base64.cpp_sec2
|
| 25 |
|
26 |
|
| 26 |
#include <limits.h> |
27 |
#include <limits.h> |
| 27 |
#include <wtf/StringExtras.h> |
28 |
#include <wtf/StringExtras.h> |
|
|
29 |
#include <wtf/text/WTFString.h> |
| 28 |
|
30 |
|
| 29 |
namespace WebCore { |
31 |
namespace WebCore { |
| 30 |
|
32 |
|
|
Lines 70-76
void base64Encode(const char* data, unsi
WebCore/platform/text/Base64.cpp_sec3
|
| 70 |
return; |
72 |
return; |
| 71 |
|
73 |
|
| 72 |
// If the input string is pathologically large, just return nothing. |
74 |
// If the input string is pathologically large, just return nothing. |
| 73 |
// Note: Keep this in sync with the "out_len" computation below. |
75 |
// Note: Keep this in sync with the "outLength" computation below. |
| 74 |
// Rather than being perfectly precise, this is a bit conservative. |
76 |
// Rather than being perfectly precise, this is a bit conservative. |
| 75 |
const unsigned maxInputBufferSize = UINT_MAX / 77 * 76 / 4 * 3 - 2; |
77 |
const unsigned maxInputBufferSize = UINT_MAX / 77 * 76 / 4 * 3 - 2; |
| 76 |
if (len > maxInputBufferSize) |
78 |
if (len > maxInputBufferSize) |
|
Lines 79-99
void base64Encode(const char* data, unsi
WebCore/platform/text/Base64.cpp_sec4
|
| 79 |
unsigned sidx = 0; |
81 |
unsigned sidx = 0; |
| 80 |
unsigned didx = 0; |
82 |
unsigned didx = 0; |
| 81 |
|
83 |
|
| 82 |
unsigned out_len = ((len + 2) / 3) * 4; |
84 |
unsigned outLength = ((len + 2) / 3) * 4; |
| 83 |
|
85 |
|
| 84 |
// Deal with the 76 character per line limit specified in RFC 2045. |
86 |
// Deal with the 76 character per line limit specified in RFC 2045. |
| 85 |
insertLFs = (insertLFs && out_len > 76); |
87 |
insertLFs = (insertLFs && outLength > 76); |
| 86 |
if (insertLFs) |
88 |
if (insertLFs) |
| 87 |
out_len += ((out_len - 1) / 76); |
89 |
outLength += ((outLength - 1) / 76); |
| 88 |
|
90 |
|
| 89 |
int count = 0; |
91 |
int count = 0; |
| 90 |
out.grow(out_len); |
92 |
out.grow(outLength); |
| 91 |
|
93 |
|
| 92 |
// 3-byte to 4-byte conversion + 0-63 to ascii printable conversion |
94 |
// 3-byte to 4-byte conversion + 0-63 to ascii printable conversion |
| 93 |
if (len > 1) { |
95 |
if (len > 1) { |
| 94 |
while (sidx < len - 2) { |
96 |
while (sidx < len - 2) { |
| 95 |
if (insertLFs) { |
97 |
if (insertLFs) { |
| 96 |
if (count && (count % 76) == 0) |
98 |
if (count && !(count % 76)) |
| 97 |
out[didx++] = '\n'; |
99 |
out[didx++] = '\n'; |
| 98 |
count += 4; |
100 |
count += 4; |
| 99 |
} |
101 |
} |
|
Lines 106-112
void base64Encode(const char* data, unsi
WebCore/platform/text/Base64.cpp_sec5
|
| 106 |
} |
108 |
} |
| 107 |
|
109 |
|
| 108 |
if (sidx < len) { |
110 |
if (sidx < len) { |
| 109 |
if (insertLFs && (count > 0) && (count % 76) == 0) |
111 |
if (insertLFs && (count > 0) && !(count % 76)) |
| 110 |
out[didx++] = '\n'; |
112 |
out[didx++] = '\n'; |
| 111 |
|
113 |
|
| 112 |
out[didx++] = base64EncMap[(data[sidx] >> 2) & 077]; |
114 |
out[didx++] = base64EncMap[(data[sidx] >> 2) & 077]; |
|
Lines 124-130
void base64Encode(const char* data, unsi
WebCore/platform/text/Base64.cpp_sec6
|
| 124 |
} |
126 |
} |
| 125 |
} |
127 |
} |
| 126 |
|
128 |
|
| 127 |
bool base64Decode(const Vector<char>& in, Vector<char>& out) |
129 |
bool base64Decode(const Vector<char>& in, Vector<char>& out, Base64DecodePolicy policy) |
| 128 |
{ |
130 |
{ |
| 129 |
out.clear(); |
131 |
out.clear(); |
| 130 |
|
132 |
|
|
Lines 132-167
bool base64Decode(const Vector<char>& in
WebCore/platform/text/Base64.cpp_sec7
|
| 132 |
if (in.size() > UINT_MAX) |
134 |
if (in.size() > UINT_MAX) |
| 133 |
return false; |
135 |
return false; |
| 134 |
|
136 |
|
| 135 |
return base64Decode(in.data(), in.size(), out); |
137 |
return base64Decode(in.data(), in.size(), out, policy); |
| 136 |
} |
138 |
} |
| 137 |
|
139 |
|
| 138 |
bool base64Decode(const char* data, unsigned len, Vector<char>& out) |
140 |
template<typename T> |
|
|
141 |
static inline bool base64DecodeInternal(const T* data, unsigned len, Vector<char>& out, Base64DecodePolicy policy) |
| 139 |
{ |
142 |
{ |
| 140 |
out.clear(); |
143 |
out.clear(); |
| 141 |
if (len == 0) |
144 |
if (!len) |
| 142 |
return true; |
145 |
return true; |
| 143 |
|
146 |
|
| 144 |
while (len && data[len-1] == '=') |
|
|
| 145 |
--len; |
| 146 |
|
| 147 |
out.grow(len); |
147 |
out.grow(len); |
|
|
148 |
|
| 149 |
bool sawEqualsSign = false; |
| 150 |
unsigned outLength = 0; |
| 148 |
for (unsigned idx = 0; idx < len; idx++) { |
151 |
for (unsigned idx = 0; idx < len; idx++) { |
| 149 |
unsigned char ch = data[idx]; |
152 |
unsigned ch = data[idx]; |
| 150 |
if ((ch > 47 && ch < 58) || (ch > 64 && ch < 91) || (ch > 96 && ch < 123) || ch == '+' || ch == '/' || ch == '=') |
153 |
if (ch == '=') |
| 151 |
out[idx] = base64DecMap[ch]; |
154 |
sawEqualsSign = true; |
| 152 |
else |
155 |
else if (('0' <= ch && ch <= '9') || ('A' <= ch && ch <= 'Z') || ('a' <= ch && ch <= 'z') || ch == '+' || ch == '/') { |
|
|
156 |
if (sawEqualsSign) |
| 157 |
return false; |
| 158 |
out[outLength] = base64DecMap[ch]; |
| 159 |
outLength++; |
| 160 |
} else if (policy == FailOnInvalidCharacter || (policy == IgnoreWhitespace && !isSpaceOrNewline(ch))) |
| 153 |
return false; |
161 |
return false; |
| 154 |
} |
162 |
} |
| 155 |
|
163 |
|
|
|
164 |
if (!outLength) |
| 165 |
return !sawEqualsSign; |
| 166 |
|
| 167 |
// Valid data is (n * 4 + [0,2,3]) characters long. |
| 168 |
if ((outLength % 4) == 1) |
| 169 |
return false; |
| 170 |
|
| 156 |
// 4-byte to 3-byte conversion |
171 |
// 4-byte to 3-byte conversion |
| 157 |
unsigned outLen = len - ((len + 3) / 4); |
172 |
outLength -= (outLength + 3) / 4; |
| 158 |
if (!outLen || ((outLen + 2) / 3) * 4 < len) |
173 |
if (!outLength) |
| 159 |
return false; |
174 |
return false; |
| 160 |
|
175 |
|
| 161 |
unsigned sidx = 0; |
176 |
unsigned sidx = 0; |
| 162 |
unsigned didx = 0; |
177 |
unsigned didx = 0; |
| 163 |
if (outLen > 1) { |
178 |
if (outLength > 1) { |
| 164 |
while (didx < outLen - 2) { |
179 |
while (didx < outLength - 2) { |
| 165 |
out[didx] = (((out[sidx] << 2) & 255) | ((out[sidx + 1] >> 4) & 003)); |
180 |
out[didx] = (((out[sidx] << 2) & 255) | ((out[sidx + 1] >> 4) & 003)); |
| 166 |
out[didx + 1] = (((out[sidx + 1] << 4) & 255) | ((out[sidx + 2] >> 2) & 017)); |
181 |
out[didx + 1] = (((out[sidx + 1] << 4) & 255) | ((out[sidx + 2] >> 2) & 017)); |
| 167 |
out[didx + 2] = (((out[sidx + 2] << 6) & 255) | (out[sidx + 3] & 077)); |
182 |
out[didx + 2] = (((out[sidx + 2] << 6) & 255) | (out[sidx + 3] & 077)); |
|
Lines 170-185
bool base64Decode(const char* data, unsi
WebCore/platform/text/Base64.cpp_sec8
|
| 170 |
} |
185 |
} |
| 171 |
} |
186 |
} |
| 172 |
|
187 |
|
| 173 |
if (didx < outLen) |
188 |
if (didx < outLength) |
| 174 |
out[didx] = (((out[sidx] << 2) & 255) | ((out[sidx + 1] >> 4) & 003)); |
189 |
out[didx] = (((out[sidx] << 2) & 255) | ((out[sidx + 1] >> 4) & 003)); |
| 175 |
|
190 |
|
| 176 |
if (++didx < outLen) |
191 |
if (++didx < outLength) |
| 177 |
out[didx] = (((out[sidx + 1] << 4) & 255) | ((out[sidx + 2] >> 2) & 017)); |
192 |
out[didx] = (((out[sidx + 1] << 4) & 255) | ((out[sidx + 2] >> 2) & 017)); |
| 178 |
|
193 |
|
| 179 |
if (outLen < out.size()) |
194 |
if (outLength < out.size()) |
| 180 |
out.shrink(outLen); |
195 |
out.shrink(outLength); |
| 181 |
|
196 |
|
| 182 |
return true; |
197 |
return true; |
| 183 |
} |
198 |
} |
| 184 |
|
199 |
|
|
|
200 |
bool base64Decode(const char* data, unsigned len, Vector<char>& out, Base64DecodePolicy policy) |
| 201 |
{ |
| 202 |
return base64DecodeInternal<char>(data, len, out, policy); |
| 185 |
} |
203 |
} |
|
|
204 |
|
| 205 |
bool base64Decode(const String& in, Vector<char>& out, Base64DecodePolicy policy) |
| 206 |
{ |
| 207 |
return base64DecodeInternal<UChar>(in.characters(), in.length(), out, policy); |
| 208 |
} |
| 209 |
|
| 210 |
} // namespace WebCore |