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

Side by Side Diff: net/base/mime_sniffer.cc

Issue 6124007: replace memcmp with MagicCmp that supports '.' for single character of anythi... (Closed) Base URL: svn://chrome-svn/chrome/trunk/src/
Patch Set: '' Created 9 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 | Annotate | Revision Log
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 // Detecting mime types is a tricky business because we need to balance 5 // Detecting mime types is a tricky business because we need to balance
6 // compatibility concerns with security issues. Here is a survey of how other 6 // compatibility concerns with security issues. Here is a survey of how other
7 // browsers behave and then a description of how we intend to behave. 7 // browsers behave and then a description of how we intend to behave.
8 // 8 //
9 // HTML payload, no Content-Type header: 9 // HTML payload, no Content-Type header:
10 // * IE 7: Render as HTML 10 // * IE 7: Render as HTML
11 // * Firefox 2: Render as HTML 11 // * Firefox 2: Render as HTML
(...skipping 127 matching lines...) Expand 10 before | Expand all | Expand 10 after
139 MAGIC_NUMBER("text/plain", ">From") 139 MAGIC_NUMBER("text/plain", ">From")
140 // Chrome specific 140 // Chrome specific
141 MAGIC_NUMBER("application/x-gzip", "\x1F\x8B\x08") 141 MAGIC_NUMBER("application/x-gzip", "\x1F\x8B\x08")
142 MAGIC_NUMBER("audio/x-pn-realaudio", "\x2E\x52\x4D\x46") 142 MAGIC_NUMBER("audio/x-pn-realaudio", "\x2E\x52\x4D\x46")
143 MAGIC_NUMBER("video/x-ms-asf", 143 MAGIC_NUMBER("video/x-ms-asf",
144 "\x30\x26\xB2\x75\x8E\x66\xCF\x11\xA6\xD9\x00\xAA\x00\x62\xCE\x6C") 144 "\x30\x26\xB2\x75\x8E\x66\xCF\x11\xA6\xD9\x00\xAA\x00\x62\xCE\x6C")
145 MAGIC_NUMBER("image/tiff", "I I") 145 MAGIC_NUMBER("image/tiff", "I I")
146 MAGIC_NUMBER("image/tiff", "II*") 146 MAGIC_NUMBER("image/tiff", "II*")
147 MAGIC_NUMBER("image/tiff", "MM\x00*") 147 MAGIC_NUMBER("image/tiff", "MM\x00*")
148 MAGIC_NUMBER("audio/mpeg", "ID3") 148 MAGIC_NUMBER("audio/mpeg", "ID3")
149 MAGIC_NUMBER("image/webp", "RIFF....WEBPVP8 ")
150 MAGIC_NUMBER("video/webm", "\x1A\x45\xDF\xA3")
149 // TODO(abarth): we don't handle partial byte matches yet 151 // TODO(abarth): we don't handle partial byte matches yet
150 // MAGIC_NUMBER("video/mpeg", "\x00\x00\x01\xB") 152 // MAGIC_NUMBER("video/mpeg", "\x00\x00\x01\xB")
151 // MAGIC_NUMBER("audio/mpeg", "\xFF\xE") 153 // MAGIC_NUMBER("audio/mpeg", "\xFF\xE")
152 // MAGIC_NUMBER("audio/mpeg", "\xFF\xF") 154 // MAGIC_NUMBER("audio/mpeg", "\xFF\xF")
153 MAGIC_NUMBER("application/zip", "PK\x03\x04") 155 MAGIC_NUMBER("application/zip", "PK\x03\x04")
154 MAGIC_NUMBER("application/x-rar-compressed", "Rar!\x1A\x07\x00") 156 MAGIC_NUMBER("application/x-rar-compressed", "Rar!\x1A\x07\x00")
155 MAGIC_NUMBER("application/x-msmetafile", "\xD7\xCD\xC6\x9A") 157 MAGIC_NUMBER("application/x-msmetafile", "\xD7\xCD\xC6\x9A")
156 MAGIC_NUMBER("application/octet-stream", "MZ") // EXE 158 MAGIC_NUMBER("application/octet-stream", "MZ") // EXE
157 // Sniffing for Flash: 159 // Sniffing for Flash:
158 // 160 //
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after
208 }; 210 };
209 211
210 static scoped_refptr<base::Histogram> UMASnifferHistogramGet(const char* name, 212 static scoped_refptr<base::Histogram> UMASnifferHistogramGet(const char* name,
211 int array_size) { 213 int array_size) {
212 scoped_refptr<base::Histogram> counter = 214 scoped_refptr<base::Histogram> counter =
213 base::LinearHistogram::FactoryGet(name, 1, array_size - 1, array_size, 215 base::LinearHistogram::FactoryGet(name, 1, array_size - 1, array_size,
214 base::Histogram::kUmaTargetedHistogramFlag); 216 base::Histogram::kUmaTargetedHistogramFlag);
215 return counter; 217 return counter;
216 } 218 }
217 219
220 static bool MagicCmp(const char* magic_entry, const char* content, size_t len) {
221 bool same = true;
222 while (len && same) {
223 if (!*content && !magic_entry)
224 break;
abarth-chromium 2011/01/11 19:50:46 We don't want to start at null bytes, right? Also
fbarchard1 2011/01/11 20:01:47 This was a typo... fixed.
225 same = (*magic_entry == *content) || (*magic_entry == '.' && *content);
abarth-chromium 2011/01/11 19:50:46 So "." matches everything that's not zero? Why wo
fbarchard1 2011/01/11 20:01:47 Good point. I was thinking strings, but this is a
226 if (!*content || !magic_entry)
227 break;
228 ++magic_entry;
229 ++content;
230 --len;
231 }
232 return same;
abarth-chromium 2011/01/11 19:50:46 We should just early return from the loop rather t
fbarchard1 2011/01/11 20:01:47 ok, will refactor.
233 }
234
218 static bool MatchMagicNumber(const char* content, size_t size, 235 static bool MatchMagicNumber(const char* content, size_t size,
219 const MagicNumber* magic_entry, 236 const MagicNumber* magic_entry,
220 std::string* result) { 237 std::string* result) {
221 const size_t len = magic_entry->magic_len; 238 const size_t len = magic_entry->magic_len;
222 239
223 // Keep kBytesRequiredForMagic honest. 240 // Keep kBytesRequiredForMagic honest.
224 DCHECK_LE(len, kBytesRequiredForMagic); 241 DCHECK_LE(len, kBytesRequiredForMagic);
225 242
226 // To compare with magic strings, we need to compute strlen(content), but 243 // To compare with magic strings, we need to compute strlen(content), but
227 // content might not actually have a null terminator. In that case, we 244 // content might not actually have a null terminator. In that case, we
228 // pretend the length is content_size. 245 // pretend the length is content_size.
229 const char* end = 246 const char* end =
230 static_cast<const char*>(memchr(content, '\0', size)); 247 static_cast<const char*>(memchr(content, '\0', size));
231 const size_t content_strlen = 248 const size_t content_strlen =
232 (end != NULL) ? static_cast<size_t>(end - content) : size; 249 (end != NULL) ? static_cast<size_t>(end - content) : size;
233 250
234 bool match = false; 251 bool match = false;
235 if (magic_entry->is_string) { 252 if (magic_entry->is_string) {
236 if (content_strlen >= len) { 253 if (content_strlen >= len) {
237 // String comparisons are case-insensitive 254 // String comparisons are case-insensitive
238 match = (base::strncasecmp(magic_entry->magic, content, len) == 0); 255 match = (base::strncasecmp(magic_entry->magic, content, len) == 0);
239 } 256 }
240 } else { 257 } else {
241 if (size >= len) 258 if (size >= len)
242 match = (memcmp(magic_entry->magic, content, len) == 0); 259 match = MagicCmp(magic_entry->magic, content, len);
243 } 260 }
244 261
245 if (match) { 262 if (match) {
246 result->assign(magic_entry->mime_type); 263 result->assign(magic_entry->mime_type);
247 return true; 264 return true;
248 } 265 }
249 return false; 266 return false;
250 } 267 }
251 268
252 static bool CheckForMagicNumbers(const char* content, size_t size, 269 static bool CheckForMagicNumbers(const char* content, size_t size,
253 const MagicNumber* magic, size_t magic_len, 270 const MagicNumber* magic, size_t magic_len,
254 base::Histogram* counter, std::string* result) { 271 base::Histogram* counter,
272 std::string* result) {
255 for (size_t i = 0; i < magic_len; ++i) { 273 for (size_t i = 0; i < magic_len; ++i) {
256 if (MatchMagicNumber(content, size, &(magic[i]), result)) { 274 if (MatchMagicNumber(content, size, &(magic[i]), result)) {
257 if (counter) counter->Add(static_cast<int>(i)); 275 if (counter) counter->Add(static_cast<int>(i));
258 return true; 276 return true;
259 } 277 }
260 } 278 }
261 return false; 279 return false;
262 } 280 }
263 281
264 // Truncates |size| to |max_size| and returns true if |size| is at least 282 // Truncates |size| to |max_size| and returns true if |size| is at least
(...skipping 390 matching lines...) Expand 10 before | Expand all | Expand 10 after
655 // Now we look in our large table of magic numbers to see if we can find 673 // Now we look in our large table of magic numbers to see if we can find
656 // anything that matches the content. 674 // anything that matches the content.
657 if (SniffForMagicNumbers(content, content_size, 675 if (SniffForMagicNumbers(content, content_size,
658 &have_enough_content, result)) 676 &have_enough_content, result))
659 return true; // We've matched a magic number. No more content needed. 677 return true; // We've matched a magic number. No more content needed.
660 678
661 return have_enough_content; 679 return have_enough_content;
662 } 680 }
663 681
664 } // namespace net 682 } // namespace net
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698