Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(803)

Side by Side Diff: Source/wtf/text/Base64.cpp

Issue 19623002: Make atob() throw an InvalidCharacterError on excess padding characters (Closed) Base URL: svn://svn.chromium.org/blink/trunk
Patch Set: Created 7 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
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
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
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
OLDNEW
« LayoutTests/fast/dom/Window/atob-btoa-expected.txt ('K') | « Source/wtf/text/Base64.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698