| OLD | NEW |
| 1 /* | 1 /* |
| 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 Copyright (C) 2010 Patrick Gansterer <paroga@paroga.com> |
| 6 | 6 |
| 7 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 |
| 8 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) |
| 9 version 2 as published by the Free Software Foundation. | 9 version 2 as published by the Free Software Foundation. |
| 10 | 10 |
| (...skipping 110 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 121 out[didx++] = base64EncMap[(data[sidx] << 4) & 077]; | 121 out[didx++] = base64EncMap[(data[sidx] << 4) & 077]; |
| 122 } | 122 } |
| 123 | 123 |
| 124 // Add padding | 124 // Add padding |
| 125 while (didx < out.size()) { | 125 while (didx < out.size()) { |
| 126 out[didx] = '='; | 126 out[didx] = '='; |
| 127 ++didx; | 127 ++didx; |
| 128 } | 128 } |
| 129 } | 129 } |
| 130 | 130 |
| 131 bool base64Decode(const Vector<char>& in, Vector<char>& out, Base64DecodePolicy
policy) | 131 bool base64Decode(const Vector<char>& in, Vector<char>& out, CharacterMatchFunct
ionPtr shouldIgnoreCharacter, Base64DecodePolicy policy) |
| 132 { | 132 { |
| 133 out.clear(); | 133 out.clear(); |
| 134 | 134 |
| 135 // If the input string is pathologically large, just return nothing. | 135 // If the input string is pathologically large, just return nothing. |
| 136 if (in.size() > UINT_MAX) | 136 if (in.size() > UINT_MAX) |
| 137 return false; | 137 return false; |
| 138 | 138 |
| 139 return base64Decode(in.data(), in.size(), out, policy); | 139 return base64Decode(in.data(), in.size(), out, shouldIgnoreCharacter, policy
); |
| 140 } | 140 } |
| 141 | 141 |
| 142 template<typename T> | 142 template<typename T> |
| 143 static inline bool base64DecodeInternal(const T* data, unsigned length, Vector<c
har>& out, Base64DecodePolicy policy) | 143 static inline bool base64DecodeInternal(const T* data, unsigned length, Vector<c
har>& out, CharacterMatchFunctionPtr shouldIgnoreCharacter, Base64DecodePolicy p
olicy) |
| 144 { | 144 { |
| 145 out.clear(); | 145 out.clear(); |
| 146 if (!length) | 146 if (!length) |
| 147 return true; | 147 return true; |
| 148 | 148 |
| 149 out.grow(length); | 149 out.grow(length); |
| 150 | 150 |
| 151 unsigned equalsSignCount = 0; | 151 unsigned equalsSignCount = 0; |
| 152 unsigned outLength = 0; | 152 unsigned outLength = 0; |
| 153 for (unsigned idx = 0; idx < length; ++idx) { | 153 for (unsigned idx = 0; idx < length; ++idx) { |
| 154 unsigned ch = data[idx]; | 154 unsigned ch = data[idx]; |
| 155 if (ch == '=') { | 155 if (ch == '=') { |
| 156 ++equalsSignCount; | 156 ++equalsSignCount; |
| 157 // There should be no padding if length is a multiple of 4, and ther
e | 157 // There should never be more than 2 padding characters. |
| 158 // should never be more than 2 padding characters. | 158 if (policy == Base64ValidatePadding && equalsSignCount > 2) |
| 159 if (policy == Base64FailOnInvalidCharacterOrExcessPadding && (length
% 4 || equalsSignCount > 2)) | |
| 160 return false; | 159 return false; |
| 161 } else if (('0' <= ch && ch <= '9') || ('A' <= ch && ch <= 'Z') || ('a'
<= ch && ch <= 'z') || ch == '+' || ch == '/') { | 160 } else if (('0' <= ch && ch <= '9') || ('A' <= ch && ch <= 'Z') || ('a'
<= ch && ch <= 'z') || ch == '+' || ch == '/') { |
| 162 if (equalsSignCount) | 161 if (equalsSignCount) |
| 163 return false; | 162 return false; |
| 164 out[outLength] = base64DecMap[ch]; | 163 out[outLength++] = base64DecMap[ch]; |
| 165 ++outLength; | 164 } else if (!shouldIgnoreCharacter || !shouldIgnoreCharacter(ch)) { |
| 166 } else if (policy == Base64FailOnInvalidCharacterOrExcessPadding || poli
cy == Base64FailOnInvalidCharacter || (policy == Base64IgnoreWhitespace && !isSp
aceOrNewline(ch))) { | |
| 167 return false; | 165 return false; |
| 168 } | 166 } |
| 169 } | 167 } |
| 170 | 168 |
| 171 if (!outLength) | 169 if (!outLength) |
| 172 return !equalsSignCount; | 170 return !equalsSignCount; |
| 173 | 171 |
| 172 // There should be no padding if length is a multiple of 4. |
| 173 // We use (outLength + equalsSignCount) instead of length because we don't w
ant to account for ignored characters. |
| 174 if (policy == Base64ValidatePadding && equalsSignCount && (outLength + equal
sSignCount) % 4) |
| 175 return false; |
| 176 |
| 174 // Valid data is (n * 4 + [0,2,3]) characters long. | 177 // Valid data is (n * 4 + [0,2,3]) characters long. |
| 175 if ((outLength % 4) == 1) | 178 if ((outLength % 4) == 1) |
| 176 return false; | 179 return false; |
| 177 | 180 |
| 178 // 4-byte to 3-byte conversion | 181 // 4-byte to 3-byte conversion |
| 179 outLength -= (outLength + 3) / 4; | 182 outLength -= (outLength + 3) / 4; |
| 180 if (!outLength) | 183 if (!outLength) |
| 181 return false; | 184 return false; |
| 182 | 185 |
| 183 unsigned sidx = 0; | 186 unsigned sidx = 0; |
| (...skipping 13 matching lines...) Expand all Loading... |
| 197 | 200 |
| 198 if (++didx < outLength) | 201 if (++didx < outLength) |
| 199 out[didx] = (((out[sidx + 1] << 4) & 255) | ((out[sidx + 2] >> 2) & 017)
); | 202 out[didx] = (((out[sidx + 1] << 4) & 255) | ((out[sidx + 2] >> 2) & 017)
); |
| 200 | 203 |
| 201 if (outLength < out.size()) | 204 if (outLength < out.size()) |
| 202 out.shrink(outLength); | 205 out.shrink(outLength); |
| 203 | 206 |
| 204 return true; | 207 return true; |
| 205 } | 208 } |
| 206 | 209 |
| 207 bool base64Decode(const char* data, unsigned length, Vector<char>& out, Base64De
codePolicy policy) | 210 bool base64Decode(const char* data, unsigned length, Vector<char>& out, Characte
rMatchFunctionPtr shouldIgnoreCharacter, Base64DecodePolicy policy) |
| 208 { | 211 { |
| 209 return base64DecodeInternal<LChar>(reinterpret_cast<const LChar*>(data), len
gth, out, policy); | 212 return base64DecodeInternal<LChar>(reinterpret_cast<const LChar*>(data), len
gth, out, shouldIgnoreCharacter, policy); |
| 210 } | 213 } |
| 211 | 214 |
| 212 bool base64Decode(const UChar* data, unsigned length, Vector<char>& out, Base64D
ecodePolicy policy) | 215 bool base64Decode(const UChar* data, unsigned length, Vector<char>& out, Charact
erMatchFunctionPtr shouldIgnoreCharacter, Base64DecodePolicy policy) |
| 213 { | 216 { |
| 214 return base64DecodeInternal<UChar>(data, length, out, policy); | 217 return base64DecodeInternal<UChar>(data, length, out, shouldIgnoreCharacter,
policy); |
| 215 } | 218 } |
| 216 | 219 |
| 217 bool base64Decode(const String& in, Vector<char>& out, Base64DecodePolicy policy
) | 220 bool base64Decode(const String& in, Vector<char>& out, CharacterMatchFunctionPtr
shouldIgnoreCharacter, Base64DecodePolicy policy) |
| 218 { | 221 { |
| 219 if (in.isEmpty()) | 222 if (in.isEmpty()) |
| 220 return base64DecodeInternal<LChar>(0, 0, out, policy); | 223 return base64DecodeInternal<LChar>(0, 0, out, shouldIgnoreCharacter, pol
icy); |
| 221 if (in.is8Bit()) | 224 if (in.is8Bit()) |
| 222 return base64DecodeInternal<LChar>(in.characters8(), in.length(), out, p
olicy); | 225 return base64DecodeInternal<LChar>(in.characters8(), in.length(), out, s
houldIgnoreCharacter, policy); |
| 223 return base64DecodeInternal<UChar>(in.characters16(), in.length(), out, poli
cy); | 226 return base64DecodeInternal<UChar>(in.characters16(), in.length(), out, shou
ldIgnoreCharacter, policy); |
| 224 } | 227 } |
| 225 | 228 |
| 226 } // namespace WTF | 229 } // namespace WTF |
| OLD | NEW |