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

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

Issue 1611343002: wtf reformat test Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: pydent Created 4 years, 11 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
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 11 matching lines...) Expand all
22 */ 22 */
23 23
24 #include "wtf/text/Base64.h" 24 #include "wtf/text/Base64.h"
25 25
26 #include "wtf/StringExtras.h" 26 #include "wtf/StringExtras.h"
27 #include <limits.h> 27 #include <limits.h>
28 28
29 namespace WTF { 29 namespace WTF {
30 30
31 static const char base64EncMap[64] = { 31 static const char base64EncMap[64] = {
32 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 32 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4A, 0x4B,
33 0x49, 0x4A, 0x4B, 0x4C, 0x4D, 0x4E, 0x4F, 0x50, 33 0x4C, 0x4D, 0x4E, 0x4F, 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56,
34 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 34 0x57, 0x58, 0x59, 0x5A, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67,
35 0x59, 0x5A, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 35 0x68, 0x69, 0x6A, 0x6B, 0x6C, 0x6D, 0x6E, 0x6F, 0x70, 0x71, 0x72,
36 0x67, 0x68, 0x69, 0x6A, 0x6B, 0x6C, 0x6D, 0x6E, 36 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7A, 0x30, 0x31, 0x32,
37 0x6F, 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 37 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x2B, 0x2F};
38 0x77, 0x78, 0x79, 0x7A, 0x30, 0x31, 0x32, 0x33,
39 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x2B, 0x2F
40 };
41 38
42 static const char base64DecMap[128] = { 39 static const char base64DecMap[128] = {
43 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 40 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
44 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 41 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
45 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 42 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
46 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 43 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3E, 0x00, 0x00, 0x00, 0x3F,
47 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 44 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3A, 0x3B, 0x3C, 0x3D, 0x00, 0x00,
48 0x00, 0x00, 0x00, 0x3E, 0x00, 0x00, 0x00, 0x3F, 45 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06,
49 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3A, 0x3B, 46 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x10, 0x11, 0x12,
50 0x3C, 0x3D, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 47 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x00, 0x00, 0x00, 0x00, 0x00,
51 0x00, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 48 0x00, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F, 0x20, 0x21, 0x22, 0x23, 0x24,
52 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 49 0x25, 0x26, 0x27, 0x28, 0x29, 0x2A, 0x2B, 0x2C, 0x2D, 0x2E, 0x2F, 0x30,
53 0x0F, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 50 0x31, 0x32, 0x33, 0x00, 0x00, 0x00, 0x00, 0x00};
54 0x17, 0x18, 0x19, 0x00, 0x00, 0x00, 0x00, 0x00, 51
55 0x00, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F, 0x20, 52 String base64Encode(const char* data,
56 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 53 unsigned length,
57 0x29, 0x2A, 0x2B, 0x2C, 0x2D, 0x2E, 0x2F, 0x30, 54 Base64EncodePolicy policy) {
58 0x31, 0x32, 0x33, 0x00, 0x00, 0x00, 0x00, 0x00 55 Vector<char> result;
59 }; 56 base64Encode(data, length, result, policy);
60 57 return String(result.data(), result.size());
61 String base64Encode(const char* data, unsigned length, Base64EncodePolicy policy ) 58 }
62 { 59
63 Vector<char> result; 60 void base64Encode(const char* data,
64 base64Encode(data, length, result, policy); 61 unsigned len,
65 return String(result.data(), result.size()); 62 Vector<char>& out,
66 } 63 Base64EncodePolicy policy) {
67 64 out.clear();
68 void base64Encode(const char* data, unsigned len, Vector<char>& out, Base64Encod ePolicy policy) 65 if (!len)
69 { 66 return;
70 out.clear(); 67
71 if (!len) 68 // If the input string is pathologically large, just return nothing.
72 return; 69 // Note: Keep this in sync with the "outLength" computation below.
73 70 // Rather than being perfectly precise, this is a bit conservative.
74 // If the input string is pathologically large, just return nothing. 71 const unsigned maxInputBufferSize = UINT_MAX / 77 * 76 / 4 * 3 - 2;
75 // Note: Keep this in sync with the "outLength" computation below. 72 if (len > maxInputBufferSize)
76 // Rather than being perfectly precise, this is a bit conservative. 73 return;
77 const unsigned maxInputBufferSize = UINT_MAX / 77 * 76 / 4 * 3 - 2; 74
78 if (len > maxInputBufferSize) 75 unsigned sidx = 0;
79 return; 76 unsigned didx = 0;
80 77
81 unsigned sidx = 0; 78 unsigned outLength = ((len + 2) / 3) * 4;
82 unsigned didx = 0; 79
83 80 // Deal with the 76 character per line limit specified in RFC 2045.
84 unsigned outLength = ((len + 2) / 3) * 4; 81 bool insertLFs = (policy == Base64InsertLFs && outLength > 76);
85 82 if (insertLFs)
86 // Deal with the 76 character per line limit specified in RFC 2045. 83 outLength += ((outLength - 1) / 76);
87 bool insertLFs = (policy == Base64InsertLFs && outLength > 76); 84
88 if (insertLFs) 85 int count = 0;
89 outLength += ((outLength - 1) / 76); 86 out.grow(outLength);
90 87
91 int count = 0; 88 // 3-byte to 4-byte conversion + 0-63 to ascii printable conversion
92 out.grow(outLength); 89 if (len > 1) {
93 90 while (sidx < len - 2) {
94 // 3-byte to 4-byte conversion + 0-63 to ascii printable conversion 91 if (insertLFs) {
95 if (len > 1) { 92 if (count && !(count % 76))
96 while (sidx < len - 2) { 93 out[didx++] = '\n';
97 if (insertLFs) { 94 count += 4;
98 if (count && !(count % 76)) 95 }
99 out[didx++] = '\n'; 96 out[didx++] = base64EncMap[(data[sidx] >> 2) & 077];
100 count += 4; 97 out[didx++] = base64EncMap[((data[sidx + 1] >> 4) & 017) |
101 } 98 ((data[sidx] << 4) & 077)];
102 out[didx++] = base64EncMap[(data[sidx] >> 2) & 077]; 99 out[didx++] = base64EncMap[((data[sidx + 2] >> 6) & 003) |
103 out[didx++] = base64EncMap[((data[sidx + 1] >> 4) & 017) | ((data[si dx] << 4) & 077)]; 100 ((data[sidx + 1] << 2) & 077)];
104 out[didx++] = base64EncMap[((data[sidx + 2] >> 6) & 003) | ((data[si dx + 1] << 2) & 077)]; 101 out[didx++] = base64EncMap[data[sidx + 2] & 077];
105 out[didx++] = base64EncMap[data[sidx + 2] & 077]; 102 sidx += 3;
106 sidx += 3; 103 }
107 } 104 }
108 } 105
109 106 if (sidx < len) {
110 if (sidx < len) { 107 if (insertLFs && (count > 0) && !(count % 76))
111 if (insertLFs && (count > 0) && !(count % 76)) 108 out[didx++] = '\n';
112 out[didx++] = '\n'; 109
113 110 out[didx++] = base64EncMap[(data[sidx] >> 2) & 077];
114 out[didx++] = base64EncMap[(data[sidx] >> 2) & 077]; 111 if (sidx < len - 1) {
115 if (sidx < len - 1) { 112 out[didx++] = base64EncMap[((data[sidx + 1] >> 4) & 017) |
116 out[didx++] = base64EncMap[((data[sidx + 1] >> 4) & 017) | ((data[si dx] << 4) & 077)]; 113 ((data[sidx] << 4) & 077)];
117 out[didx++] = base64EncMap[(data[sidx + 1] << 2) & 077]; 114 out[didx++] = base64EncMap[(data[sidx + 1] << 2) & 077];
118 } else { 115 } else {
119 out[didx++] = base64EncMap[(data[sidx] << 4) & 077]; 116 out[didx++] = base64EncMap[(data[sidx] << 4) & 077];
120 } 117 }
121 } 118 }
122 119
123 // Add padding 120 // Add padding
124 while (didx < out.size()) { 121 while (didx < out.size()) {
125 out[didx] = '='; 122 out[didx] = '=';
126 ++didx; 123 ++didx;
127 } 124 }
128 } 125 }
129 126
130 bool base64Decode(const Vector<char>& in, Vector<char>& out, CharacterMatchFunct ionPtr shouldIgnoreCharacter, Base64DecodePolicy policy) 127 bool base64Decode(const Vector<char>& in,
131 { 128 Vector<char>& out,
132 out.clear(); 129 CharacterMatchFunctionPtr shouldIgnoreCharacter,
133 130 Base64DecodePolicy policy) {
134 // If the input string is pathologically large, just return nothing. 131 out.clear();
135 if (in.size() > UINT_MAX) 132
136 return false; 133 // If the input string is pathologically large, just return nothing.
137 134 if (in.size() > UINT_MAX)
138 return base64Decode(in.data(), in.size(), out, shouldIgnoreCharacter, policy ); 135 return false;
139 } 136
140 137 return base64Decode(in.data(), in.size(), out, shouldIgnoreCharacter, policy);
141 template<typename T> 138 }
142 static inline bool base64DecodeInternal(const T* data, unsigned length, Vector<c har>& out, CharacterMatchFunctionPtr shouldIgnoreCharacter, Base64DecodePolicy p olicy) 139
143 { 140 template <typename T>
144 out.clear(); 141 static inline bool base64DecodeInternal(
145 if (!length) 142 const T* data,
146 return true; 143 unsigned length,
147 144 Vector<char>& out,
148 out.grow(length); 145 CharacterMatchFunctionPtr shouldIgnoreCharacter,
149 146 Base64DecodePolicy policy) {
150 unsigned equalsSignCount = 0; 147 out.clear();
151 unsigned outLength = 0; 148 if (!length)
152 bool hadError = false;
153 for (unsigned idx = 0; idx < length; ++idx) {
154 UChar ch = data[idx];
155 if (ch == '=') {
156 ++equalsSignCount;
157 // There should never be more than 2 padding characters.
158 if (policy == Base64ValidatePadding && equalsSignCount > 2) {
159 hadError = true;
160 break;
161 }
162 } else if (('0' <= ch && ch <= '9') || ('A' <= ch && ch <= 'Z') || ('a' <= ch && ch <= 'z') || ch == '+' || ch == '/') {
163 if (equalsSignCount) {
164 hadError = true;
165 break;
166 }
167 out[outLength++] = base64DecMap[ch];
168 } else if (!shouldIgnoreCharacter || !shouldIgnoreCharacter(ch)) {
169 hadError = true;
170 break;
171 }
172 }
173
174 if (outLength < out.size())
175 out.shrink(outLength);
176
177 if (hadError)
178 return false;
179
180 if (!outLength)
181 return !equalsSignCount;
182
183 // There should be no padding if length is a multiple of 4.
184 // We use (outLength + equalsSignCount) instead of length because we don't w ant to account for ignored characters.
185 if (policy == Base64ValidatePadding && equalsSignCount && (outLength + equal sSignCount) % 4)
186 return false;
187
188 // Valid data is (n * 4 + [0,2,3]) characters long.
189 if ((outLength % 4) == 1)
190 return false;
191
192 // 4-byte to 3-byte conversion
193 outLength -= (outLength + 3) / 4;
194 if (!outLength)
195 return false;
196
197 unsigned sidx = 0;
198 unsigned didx = 0;
199 if (outLength > 1) {
200 while (didx < outLength - 2) {
201 out[didx] = (((out[sidx] << 2) & 255) | ((out[sidx + 1] >> 4) & 003) );
202 out[didx + 1] = (((out[sidx + 1] << 4) & 255) | ((out[sidx + 2] >> 2 ) & 017));
203 out[didx + 2] = (((out[sidx + 2] << 6) & 255) | (out[sidx + 3] & 077 ));
204 sidx += 4;
205 didx += 3;
206 }
207 }
208
209 if (didx < outLength)
210 out[didx] = (((out[sidx] << 2) & 255) | ((out[sidx + 1] >> 4) & 003));
211
212 if (++didx < outLength)
213 out[didx] = (((out[sidx + 1] << 4) & 255) | ((out[sidx + 2] >> 2) & 017) );
214
215 if (outLength < out.size())
216 out.shrink(outLength);
217
218 return true; 149 return true;
219 } 150
220 151 out.grow(length);
221 bool base64Decode(const char* data, unsigned length, Vector<char>& out, Characte rMatchFunctionPtr shouldIgnoreCharacter, Base64DecodePolicy policy) 152
222 { 153 unsigned equalsSignCount = 0;
223 return base64DecodeInternal<LChar>(reinterpret_cast<const LChar*>(data), len gth, out, shouldIgnoreCharacter, policy); 154 unsigned outLength = 0;
224 } 155 bool hadError = false;
225 156 for (unsigned idx = 0; idx < length; ++idx) {
226 bool base64Decode(const UChar* data, unsigned length, Vector<char>& out, Charact erMatchFunctionPtr shouldIgnoreCharacter, Base64DecodePolicy policy) 157 UChar ch = data[idx];
227 { 158 if (ch == '=') {
228 return base64DecodeInternal<UChar>(data, length, out, shouldIgnoreCharacter, policy); 159 ++equalsSignCount;
229 } 160 // There should never be more than 2 padding characters.
230 161 if (policy == Base64ValidatePadding && equalsSignCount > 2) {
231 bool base64Decode(const String& in, Vector<char>& out, CharacterMatchFunctionPtr shouldIgnoreCharacter, Base64DecodePolicy policy) 162 hadError = true;
232 { 163 break;
233 if (in.isEmpty()) 164 }
234 return base64DecodeInternal<LChar>(0, 0, out, shouldIgnoreCharacter, pol icy); 165 } else if (('0' <= ch && ch <= '9') || ('A' <= ch && ch <= 'Z') ||
235 if (in.is8Bit()) 166 ('a' <= ch && ch <= 'z') || ch == '+' || ch == '/') {
236 return base64DecodeInternal<LChar>(in.characters8(), in.length(), out, s houldIgnoreCharacter, policy); 167 if (equalsSignCount) {
237 return base64DecodeInternal<UChar>(in.characters16(), in.length(), out, shou ldIgnoreCharacter, policy); 168 hadError = true;
238 } 169 break;
239 170 }
240 String base64URLEncode(const char* data, unsigned length, Base64EncodePolicy pol icy) 171 out[outLength++] = base64DecMap[ch];
241 { 172 } else if (!shouldIgnoreCharacter || !shouldIgnoreCharacter(ch)) {
242 return base64Encode(data, length, policy).replace('+', '-').replace('/', '_' ); 173 hadError = true;
243 } 174 break;
244 175 }
245 String normalizeToBase64(const String& encoding) 176 }
246 { 177
247 return String(encoding).replace('-', '+').replace('_', '/'); 178 if (outLength < out.size())
248 } 179 out.shrink(outLength);
249 180
250 } // namespace WTF 181 if (hadError)
182 return false;
183
184 if (!outLength)
185 return !equalsSignCount;
186
187 // There should be no padding if length is a multiple of 4.
188 // We use (outLength + equalsSignCount) instead of length because we don't wan t to account for ignored characters.
189 if (policy == Base64ValidatePadding && equalsSignCount &&
190 (outLength + equalsSignCount) % 4)
191 return false;
192
193 // Valid data is (n * 4 + [0,2,3]) characters long.
194 if ((outLength % 4) == 1)
195 return false;
196
197 // 4-byte to 3-byte conversion
198 outLength -= (outLength + 3) / 4;
199 if (!outLength)
200 return false;
201
202 unsigned sidx = 0;
203 unsigned didx = 0;
204 if (outLength > 1) {
205 while (didx < outLength - 2) {
206 out[didx] = (((out[sidx] << 2) & 255) | ((out[sidx + 1] >> 4) & 003));
207 out[didx + 1] =
208 (((out[sidx + 1] << 4) & 255) | ((out[sidx + 2] >> 2) & 017));
209 out[didx + 2] = (((out[sidx + 2] << 6) & 255) | (out[sidx + 3] & 077));
210 sidx += 4;
211 didx += 3;
212 }
213 }
214
215 if (didx < outLength)
216 out[didx] = (((out[sidx] << 2) & 255) | ((out[sidx + 1] >> 4) & 003));
217
218 if (++didx < outLength)
219 out[didx] = (((out[sidx + 1] << 4) & 255) | ((out[sidx + 2] >> 2) & 017));
220
221 if (outLength < out.size())
222 out.shrink(outLength);
223
224 return true;
225 }
226
227 bool base64Decode(const char* data,
228 unsigned length,
229 Vector<char>& out,
230 CharacterMatchFunctionPtr shouldIgnoreCharacter,
231 Base64DecodePolicy policy) {
232 return base64DecodeInternal<LChar>(reinterpret_cast<const LChar*>(data),
233 length, out, shouldIgnoreCharacter,
234 policy);
235 }
236
237 bool base64Decode(const UChar* data,
238 unsigned length,
239 Vector<char>& out,
240 CharacterMatchFunctionPtr shouldIgnoreCharacter,
241 Base64DecodePolicy policy) {
242 return base64DecodeInternal<UChar>(data, length, out, shouldIgnoreCharacter,
243 policy);
244 }
245
246 bool base64Decode(const String& in,
247 Vector<char>& out,
248 CharacterMatchFunctionPtr shouldIgnoreCharacter,
249 Base64DecodePolicy policy) {
250 if (in.isEmpty())
251 return base64DecodeInternal<LChar>(0, 0, out, shouldIgnoreCharacter,
252 policy);
253 if (in.is8Bit())
254 return base64DecodeInternal<LChar>(in.characters8(), in.length(), out,
255 shouldIgnoreCharacter, policy);
256 return base64DecodeInternal<UChar>(in.characters16(), in.length(), out,
257 shouldIgnoreCharacter, policy);
258 }
259
260 String base64URLEncode(const char* data,
261 unsigned length,
262 Base64EncodePolicy policy) {
263 return base64Encode(data, length, policy).replace('+', '-').replace('/', '_');
264 }
265
266 String normalizeToBase64(const String& encoding) {
267 return String(encoding).replace('-', '+').replace('_', '/');
268 }
269
270 } // namespace WTF
OLDNEW
« no previous file with comments | « third_party/WebKit/Source/wtf/text/Base64.h ('k') | third_party/WebKit/Source/wtf/text/CString.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698