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, Base64InvalidCharac tersPolicy charactersPolicy, Base64PaddingValidationPolicy paddingPolicy) |
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, charactersPolicy, paddingPoli cy); |
140 } | 140 } |
141 | 141 |
142 template<typename T> | 142 template<typename T> |
143 static inline bool base64DecodeInternal(const T* data, unsigned len, Vector<char >& out, Base64DecodePolicy policy) | 143 static inline bool base64DecodeInternal(const T* data, unsigned length, Vector<c har>& out, Base64InvalidCharactersPolicy charactersPolicy, Base64PaddingValidati onPolicy paddingPolicy) |
144 { | 144 { |
145 out.clear(); | 145 out.clear(); |
146 if (!len) | 146 if (!length) |
147 return true; | 147 return true; |
148 | 148 |
149 out.grow(len); | 149 unsigned dataLength = length; |
150 if (paddingPolicy == Base64StrictPaddingValidation) { | |
151 if (!(dataLength % 4)) { | |
152 // There may be 2 = padding max. | |
153 while (data[dataLength - 1] == '=' && dataLength >= (length - 2)) | |
154 --dataLength; | |
155 } | |
156 if (dataLength % 4 == 1) | |
157 return false; | |
158 } | |
159 | |
160 out.grow(length); | |
150 | 161 |
151 bool sawEqualsSign = false; | 162 bool sawEqualsSign = false; |
152 unsigned outLength = 0; | 163 unsigned outLength = 0; |
153 for (unsigned idx = 0; idx < len; ++idx) { | 164 for (unsigned idx = 0; idx < length; ++idx) { |
154 unsigned ch = data[idx]; | 165 unsigned ch = data[idx]; |
155 if (ch == '=') | 166 if (ch == '=') { |
156 sawEqualsSign = true; | 167 sawEqualsSign = true; |
168 if (paddingPolicy == Base64StrictPaddingValidation && idx < dataLeng th) | |
169 return false; | |
170 } | |
arv (Not doing code reviews)
2013/07/17 17:49:06
} else if (...) {
| |
157 else if (('0' <= ch && ch <= '9') || ('A' <= ch && ch <= 'Z') || ('a' <= ch && ch <= 'z') || ch == '+' || ch == '/') { | 171 else if (('0' <= ch && ch <= '9') || ('A' <= ch && ch <= 'Z') || ('a' <= ch && ch <= 'z') || ch == '+' || ch == '/') { |
158 if (sawEqualsSign) | 172 if (sawEqualsSign) |
159 return false; | 173 return false; |
160 out[outLength] = base64DecMap[ch]; | 174 out[outLength] = base64DecMap[ch]; |
161 ++outLength; | 175 ++outLength; |
162 } else if (policy == Base64FailOnInvalidCharacter || (policy == Base64Ig noreWhitespace && !isSpaceOrNewline(ch))) | 176 } else if (charactersPolicy == Base64FailOnInvalidCharacter || (characte rsPolicy == Base64IgnoreWhitespace && !isSpaceOrNewline(ch))) |
163 return false; | 177 return false; |
164 } | 178 } |
165 | 179 |
166 if (!outLength) | 180 if (!outLength) |
167 return !sawEqualsSign; | 181 return !sawEqualsSign; |
168 | 182 |
169 // Valid data is (n * 4 + [0,2,3]) characters long. | 183 // Valid data is (n * 4 + [0,2,3]) characters long. |
170 if ((outLength % 4) == 1) | 184 if ((outLength % 4) == 1) |
171 return false; | 185 return false; |
172 | 186 |
(...skipping 19 matching lines...) Expand all Loading... | |
192 | 206 |
193 if (++didx < outLength) | 207 if (++didx < outLength) |
194 out[didx] = (((out[sidx + 1] << 4) & 255) | ((out[sidx + 2] >> 2) & 017) ); | 208 out[didx] = (((out[sidx + 1] << 4) & 255) | ((out[sidx + 2] >> 2) & 017) ); |
195 | 209 |
196 if (outLength < out.size()) | 210 if (outLength < out.size()) |
197 out.shrink(outLength); | 211 out.shrink(outLength); |
198 | 212 |
199 return true; | 213 return true; |
200 } | 214 } |
201 | 215 |
202 bool base64Decode(const char* data, unsigned length, Vector<char>& out, Base64De codePolicy policy) | 216 bool base64Decode(const char* data, unsigned length, Vector<char>& out, Base64In validCharactersPolicy charactersPolicy, Base64PaddingValidationPolicy paddingPol icy) |
203 { | 217 { |
204 return base64DecodeInternal<LChar>(reinterpret_cast<const LChar*>(data), len gth, out, policy); | 218 return base64DecodeInternal<LChar>(reinterpret_cast<const LChar*>(data), len gth, out, charactersPolicy, paddingPolicy); |
205 } | 219 } |
206 | 220 |
207 bool base64Decode(const String& in, Vector<char>& out, Base64DecodePolicy policy ) | 221 bool base64Decode(const String& in, Vector<char>& out, Base64InvalidCharactersPo licy charactersPolicy, Base64PaddingValidationPolicy paddingPolicy) |
208 { | 222 { |
209 if (in.isEmpty()) | 223 if (in.isEmpty()) |
210 return base64DecodeInternal<LChar>(0, 0, out, policy); | 224 return base64DecodeInternal<LChar>(0, 0, out, charactersPolicy, paddingP olicy); |
211 if (in.is8Bit()) | 225 if (in.is8Bit()) |
212 return base64DecodeInternal<LChar>(in.characters8(), in.length(), out, p olicy); | 226 return base64DecodeInternal<LChar>(in.characters8(), in.length(), out, c haractersPolicy, paddingPolicy); |
213 return base64DecodeInternal<UChar>(in.characters16(), in.length(), out, poli cy); | 227 return base64DecodeInternal<UChar>(in.characters16(), in.length(), out, char actersPolicy, paddingPolicy); |
214 } | 228 } |
215 | 229 |
216 } // namespace WTF | 230 } // namespace WTF |
OLD | NEW |