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

Side by Side Diff: Source/core/page/ContentSecurityPolicy.cpp

Issue 23861003: Enable srcset support in HTMLImageElement (Closed) Base URL: https://chromium.googlesource.com/chromium/blink.git@master
Patch Set: Rewrote HTMLSrcsetParser, making it more efficient and readable. Addressed abarth's review comments. Created 7 years, 3 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) 2011 Google, Inc. All rights reserved. 2 * Copyright (C) 2011 Google, Inc. All rights reserved.
3 * 3 *
4 * Redistribution and use in source and binary forms, with or without 4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions 5 * modification, are permitted provided that the following conditions
6 * are met: 6 * are met:
7 * 1. Redistributions of source code must retain the above copyright 7 * 1. Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer. 8 * notice, this list of conditions and the following disclaimer.
9 * 2. Redistributions in binary form must reproduce the above copyright 9 * 2. Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the 10 * notice, this list of conditions and the following disclaimer in the
(...skipping 23 matching lines...) Expand all
34 #include "core/dom/Document.h" 34 #include "core/dom/Document.h"
35 #include "core/dom/SecurityPolicyViolationEvent.h" 35 #include "core/dom/SecurityPolicyViolationEvent.h"
36 #include "core/inspector/InspectorInstrumentation.h" 36 #include "core/inspector/InspectorInstrumentation.h"
37 #include "core/inspector/ScriptCallStack.h" 37 #include "core/inspector/ScriptCallStack.h"
38 #include "core/loader/DocumentLoader.h" 38 #include "core/loader/DocumentLoader.h"
39 #include "core/loader/PingLoader.h" 39 #include "core/loader/PingLoader.h"
40 #include "core/page/ContentSecurityPolicyResponseHeaders.h" 40 #include "core/page/ContentSecurityPolicyResponseHeaders.h"
41 #include "core/page/Frame.h" 41 #include "core/page/Frame.h"
42 #include "core/page/UseCounter.h" 42 #include "core/page/UseCounter.h"
43 #include "core/platform/JSONValues.h" 43 #include "core/platform/JSONValues.h"
44 #include "core/platform/ParsingUtilities.h"
44 #include "core/platform/network/FormData.h" 45 #include "core/platform/network/FormData.h"
45 #include "core/platform/network/ResourceResponse.h" 46 #include "core/platform/network/ResourceResponse.h"
46 #include "weborigin/KURL.h" 47 #include "weborigin/KURL.h"
47 #include "weborigin/KnownPorts.h" 48 #include "weborigin/KnownPorts.h"
48 #include "weborigin/SchemeRegistry.h" 49 #include "weborigin/SchemeRegistry.h"
49 #include "weborigin/SecurityOrigin.h" 50 #include "weborigin/SecurityOrigin.h"
50 #include "wtf/HashSet.h" 51 #include "wtf/HashSet.h"
51 #include "wtf/text/TextPosition.h" 52 #include "wtf/text/TextPosition.h"
52 #include "wtf/text/WTFString.h" 53 #include "wtf/text/WTFString.h"
53 54
(...skipping 104 matching lines...) Expand 10 before | Expand all | Expand 10 after
158 return UseCounter::PrefixedContentSecurityPolicyReportOnly; 159 return UseCounter::PrefixedContentSecurityPolicyReportOnly;
159 case ContentSecurityPolicy::Report: 160 case ContentSecurityPolicy::Report:
160 return UseCounter::ContentSecurityPolicyReportOnly; 161 return UseCounter::ContentSecurityPolicyReportOnly;
161 } 162 }
162 ASSERT_NOT_REACHED(); 163 ASSERT_NOT_REACHED();
163 return UseCounter::NumberOfFeatures; 164 return UseCounter::NumberOfFeatures;
164 } 165 }
165 166
166 } // namespace 167 } // namespace
167 168
168 static bool skipExactly(const UChar*& position, const UChar* end, UChar delimite r)
169 {
170 if (position < end && *position == delimiter) {
171 ++position;
172 return true;
173 }
174 return false;
175 }
176
177 template<bool characterPredicate(UChar)>
178 static bool skipExactly(const UChar*& position, const UChar* end)
179 {
180 if (position < end && characterPredicate(*position)) {
181 ++position;
182 return true;
183 }
184 return false;
185 }
186
187 static void skipUntil(const UChar*& position, const UChar* end, UChar delimiter)
188 {
189 while (position < end && *position != delimiter)
190 ++position;
191 }
192
193 template<bool characterPredicate(UChar)>
194 static void skipWhile(const UChar*& position, const UChar* end)
195 {
196 while (position < end && characterPredicate(*position))
197 ++position;
198 }
199
200 static bool isSourceListNone(const UChar* begin, const UChar* end) 169 static bool isSourceListNone(const UChar* begin, const UChar* end)
201 { 170 {
202 skipWhile<isASCIISpace>(begin, end); 171 skipWhile<UChar, isASCIISpace>(begin, end);
203 172
204 const UChar* position = begin; 173 const UChar* position = begin;
205 skipWhile<isSourceCharacter>(position, end); 174 skipWhile<UChar, isSourceCharacter>(position, end);
206 if (!equalIgnoringCase("'none'", begin, position - begin)) 175 if (!equalIgnoringCase("'none'", begin, position - begin))
207 return false; 176 return false;
208 177
209 skipWhile<isASCIISpace>(position, end); 178 skipWhile<UChar, isASCIISpace>(position, end);
210 if (position != end) 179 if (position != end)
211 return false; 180 return false;
212 181
213 return true; 182 return true;
214 } 183 }
215 184
216 class CSPSource { 185 class CSPSource {
217 public: 186 public:
218 CSPSource(ContentSecurityPolicy* policy, const String& scheme, const String& host, int port, const String& path, bool hostHasWildcard, bool portHasWildcard) 187 CSPSource(ContentSecurityPolicy* policy, const String& scheme, const String& host, int port, const String& path, bool hostHasWildcard, bool portHasWildcard)
219 : m_policy(policy) 188 : m_policy(policy)
(...skipping 142 matching lines...) Expand 10 before | Expand all | Expand 10 after
362 // / *WSP "'none'" *WSP 331 // / *WSP "'none'" *WSP
363 // 332 //
364 void CSPSourceList::parse(const UChar* begin, const UChar* end) 333 void CSPSourceList::parse(const UChar* begin, const UChar* end)
365 { 334 {
366 // We represent 'none' as an empty m_list. 335 // We represent 'none' as an empty m_list.
367 if (isSourceListNone(begin, end)) 336 if (isSourceListNone(begin, end))
368 return; 337 return;
369 338
370 const UChar* position = begin; 339 const UChar* position = begin;
371 while (position < end) { 340 while (position < end) {
372 skipWhile<isASCIISpace>(position, end); 341 skipWhile<UChar, isASCIISpace>(position, end);
373 if (position == end) 342 if (position == end)
374 return; 343 return;
375 344
376 const UChar* beginSource = position; 345 const UChar* beginSource = position;
377 skipWhile<isSourceCharacter>(position, end); 346 skipWhile<UChar, isSourceCharacter>(position, end);
378 347
379 String scheme, host, path; 348 String scheme, host, path;
380 int port = 0; 349 int port = 0;
381 bool hostHasWildcard = false; 350 bool hostHasWildcard = false;
382 bool portHasWildcard = false; 351 bool portHasWildcard = false;
383 352
384 if (parseSource(beginSource, position, scheme, host, port, path, hostHas Wildcard, portHasWildcard)) { 353 if (parseSource(beginSource, position, scheme, host, port, path, hostHas Wildcard, portHasWildcard)) {
385 // Wildcard hosts and keyword sources ('self', 'unsafe-inline', 354 // Wildcard hosts and keyword sources ('self', 'unsafe-inline',
386 // etc.) aren't stored in m_list, but as attributes on the source 355 // etc.) aren't stored in m_list, but as attributes on the source
387 // list itself. 356 // list itself.
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after
440 addSourceNonce(nonce); 409 addSourceNonce(nonce);
441 return true; 410 return true;
442 } 411 }
443 } 412 }
444 413
445 const UChar* position = begin; 414 const UChar* position = begin;
446 const UChar* beginHost = begin; 415 const UChar* beginHost = begin;
447 const UChar* beginPath = end; 416 const UChar* beginPath = end;
448 const UChar* beginPort = 0; 417 const UChar* beginPort = 0;
449 418
450 skipWhile<isNotColonOrSlash>(position, end); 419 skipWhile<UChar, isNotColonOrSlash>(position, end);
451 420
452 if (position == end) { 421 if (position == end) {
453 // host 422 // host
454 // ^ 423 // ^
455 return parseHost(beginHost, position, host, hostHasWildcard); 424 return parseHost(beginHost, position, host, hostHasWildcard);
456 } 425 }
457 426
458 if (position < end && *position == '/') { 427 if (position < end && *position == '/') {
459 // host/path || host/ || / 428 // host/path || host/ || /
460 // ^ ^ ^ 429 // ^ ^ ^
461 return parseHost(beginHost, position, host, hostHasWildcard) && parsePat h(position, end, path); 430 return parseHost(beginHost, position, host, hostHasWildcard) && parsePat h(position, end, path);
462 } 431 }
463 432
464 if (position < end && *position == ':') { 433 if (position < end && *position == ':') {
465 if (end - position == 1) { 434 if (end - position == 1) {
466 // scheme: 435 // scheme:
467 // ^ 436 // ^
468 return parseScheme(begin, position, scheme); 437 return parseScheme(begin, position, scheme);
469 } 438 }
470 439
471 if (position[1] == '/') { 440 if (position[1] == '/') {
472 // scheme://host || scheme:// 441 // scheme://host || scheme://
473 // ^ ^ 442 // ^ ^
474 if (!parseScheme(begin, position, scheme) 443 if (!parseScheme(begin, position, scheme)
475 || !skipExactly(position, end, ':') 444 || !skipExactly<UChar>(position, end, ':')
476 || !skipExactly(position, end, '/') 445 || !skipExactly<UChar>(position, end, '/')
477 || !skipExactly(position, end, '/')) 446 || !skipExactly<UChar>(position, end, '/'))
478 return false; 447 return false;
479 if (position == end) 448 if (position == end)
480 return true; 449 return true;
481 beginHost = position; 450 beginHost = position;
482 skipWhile<isNotColonOrSlash>(position, end); 451 skipWhile<UChar, isNotColonOrSlash>(position, end);
483 } 452 }
484 453
485 if (position < end && *position == ':') { 454 if (position < end && *position == ':') {
486 // host:port || scheme://host:port 455 // host:port || scheme://host:port
487 // ^ ^ 456 // ^ ^
488 beginPort = position; 457 beginPort = position;
489 skipUntil(position, end, '/'); 458 skipUntil<UChar>(position, end, '/');
490 } 459 }
491 } 460 }
492 461
493 if (position < end && *position == '/') { 462 if (position < end && *position == '/') {
494 // scheme://host/path || scheme://host:port/path 463 // scheme://host/path || scheme://host:port/path
495 // ^ ^ 464 // ^ ^
496 if (position == beginHost) 465 if (position == beginHost)
497 return false; 466 return false;
498 beginPath = position; 467 beginPath = position;
499 } 468 }
(...skipping 22 matching lines...) Expand all
522 bool CSPSourceList::parseNonce(const UChar* begin, const UChar* end, String& non ce) 491 bool CSPSourceList::parseNonce(const UChar* begin, const UChar* end, String& non ce)
523 { 492 {
524 DEFINE_STATIC_LOCAL(const String, noncePrefix, ("'nonce-")); 493 DEFINE_STATIC_LOCAL(const String, noncePrefix, ("'nonce-"));
525 494
526 if (!equalIgnoringCase(noncePrefix.characters8(), begin, noncePrefix.length( ))) 495 if (!equalIgnoringCase(noncePrefix.characters8(), begin, noncePrefix.length( )))
527 return true; 496 return true;
528 497
529 const UChar* position = begin + noncePrefix.length(); 498 const UChar* position = begin + noncePrefix.length();
530 const UChar* nonceBegin = position; 499 const UChar* nonceBegin = position;
531 500
532 skipWhile<isNonceCharacter>(position, end); 501 skipWhile<UChar, isNonceCharacter>(position, end);
533 ASSERT(nonceBegin <= position); 502 ASSERT(nonceBegin <= position);
534 503
535 if (((position + 1) != end && *position != '\'') || !(position - nonceBegin )) 504 if (((position + 1) != end && *position != '\'') || !(position - nonceBegin ))
536 return false; 505 return false;
537 506
538 nonce = String(nonceBegin, position - nonceBegin); 507 nonce = String(nonceBegin, position - nonceBegin);
539 return true; 508 return true;
540 } 509 }
541 510
542 // ; <scheme> production from RFC 3986 511 // ; <scheme> production from RFC 3986
543 // scheme = ALPHA *( ALPHA / DIGIT / "+" / "-" / "." ) 512 // scheme = ALPHA *( ALPHA / DIGIT / "+" / "-" / "." )
544 // 513 //
545 bool CSPSourceList::parseScheme(const UChar* begin, const UChar* end, String& sc heme) 514 bool CSPSourceList::parseScheme(const UChar* begin, const UChar* end, String& sc heme)
546 { 515 {
547 ASSERT(begin <= end); 516 ASSERT(begin <= end);
548 ASSERT(scheme.isEmpty()); 517 ASSERT(scheme.isEmpty());
549 518
550 if (begin == end) 519 if (begin == end)
551 return false; 520 return false;
552 521
553 const UChar* position = begin; 522 const UChar* position = begin;
554 523
555 if (!skipExactly<isASCIIAlpha>(position, end)) 524 if (!skipExactly<UChar, isASCIIAlpha>(position, end))
556 return false; 525 return false;
557 526
558 skipWhile<isSchemeContinuationCharacter>(position, end); 527 skipWhile<UChar, isSchemeContinuationCharacter>(position, end);
559 528
560 if (position != end) 529 if (position != end)
561 return false; 530 return false;
562 531
563 scheme = String(begin, end - begin); 532 scheme = String(begin, end - begin);
564 return true; 533 return true;
565 } 534 }
566 535
567 // host = [ "*." ] 1*host-char *( "." 1*host-char ) 536 // host = [ "*." ] 1*host-char *( "." 1*host-char )
568 // / "*" 537 // / "*"
569 // host-char = ALPHA / DIGIT / "-" 538 // host-char = ALPHA / DIGIT / "-"
570 // 539 //
571 bool CSPSourceList::parseHost(const UChar* begin, const UChar* end, String& host , bool& hostHasWildcard) 540 bool CSPSourceList::parseHost(const UChar* begin, const UChar* end, String& host , bool& hostHasWildcard)
572 { 541 {
573 ASSERT(begin <= end); 542 ASSERT(begin <= end);
574 ASSERT(host.isEmpty()); 543 ASSERT(host.isEmpty());
575 ASSERT(!hostHasWildcard); 544 ASSERT(!hostHasWildcard);
576 545
577 if (begin == end) 546 if (begin == end)
578 return false; 547 return false;
579 548
580 const UChar* position = begin; 549 const UChar* position = begin;
581 550
582 if (skipExactly(position, end, '*')) { 551 if (skipExactly<UChar>(position, end, '*')) {
583 hostHasWildcard = true; 552 hostHasWildcard = true;
584 553
585 if (position == end) 554 if (position == end)
586 return true; 555 return true;
587 556
588 if (!skipExactly(position, end, '.')) 557 if (!skipExactly<UChar>(position, end, '.'))
589 return false; 558 return false;
590 } 559 }
591 560
592 const UChar* hostBegin = position; 561 const UChar* hostBegin = position;
593 562
594 while (position < end) { 563 while (position < end) {
595 if (!skipExactly<isHostCharacter>(position, end)) 564 if (!skipExactly<UChar, isHostCharacter>(position, end))
596 return false; 565 return false;
597 566
598 skipWhile<isHostCharacter>(position, end); 567 skipWhile<UChar, isHostCharacter>(position, end);
599 568
600 if (position < end && !skipExactly(position, end, '.')) 569 if (position < end && !skipExactly<UChar>(position, end, '.'))
601 return false; 570 return false;
602 } 571 }
603 572
604 ASSERT(position == end); 573 ASSERT(position == end);
605 host = String(hostBegin, end - hostBegin); 574 host = String(hostBegin, end - hostBegin);
606 return true; 575 return true;
607 } 576 }
608 577
609 bool CSPSourceList::parsePath(const UChar* begin, const UChar* end, String& path ) 578 bool CSPSourceList::parsePath(const UChar* begin, const UChar* end, String& path )
610 { 579 {
611 ASSERT(begin <= end); 580 ASSERT(begin <= end);
612 ASSERT(path.isEmpty()); 581 ASSERT(path.isEmpty());
613 582
614 const UChar* position = begin; 583 const UChar* position = begin;
615 skipWhile<isPathComponentCharacter>(position, end); 584 skipWhile<UChar, isPathComponentCharacter>(position, end);
616 // path/to/file.js?query=string || path/to/file.js#anchor 585 // path/to/file.js?query=string || path/to/file.js#anchor
617 // ^ ^ 586 // ^ ^
618 if (position < end) 587 if (position < end)
619 m_policy->reportInvalidPathCharacter(m_directiveName, String(begin, end - begin), *position); 588 m_policy->reportInvalidPathCharacter(m_directiveName, String(begin, end - begin), *position);
620 589
621 path = decodeURLEscapeSequences(String(begin, position - begin)); 590 path = decodeURLEscapeSequences(String(begin, position - begin));
622 591
623 ASSERT(position <= end); 592 ASSERT(position <= end);
624 ASSERT(position == end || (*position == '#' || *position == '?')); 593 ASSERT(position == end || (*position == '#' || *position == '?'));
625 return true; 594 return true;
626 } 595 }
627 596
628 // port = ":" ( 1*DIGIT / "*" ) 597 // port = ":" ( 1*DIGIT / "*" )
629 // 598 //
630 bool CSPSourceList::parsePort(const UChar* begin, const UChar* end, int& port, b ool& portHasWildcard) 599 bool CSPSourceList::parsePort(const UChar* begin, const UChar* end, int& port, b ool& portHasWildcard)
631 { 600 {
632 ASSERT(begin <= end); 601 ASSERT(begin <= end);
633 ASSERT(!port); 602 ASSERT(!port);
634 ASSERT(!portHasWildcard); 603 ASSERT(!portHasWildcard);
635 604
636 if (!skipExactly(begin, end, ':')) 605 if (!skipExactly<UChar>(begin, end, ':'))
637 ASSERT_NOT_REACHED(); 606 ASSERT_NOT_REACHED();
638 607
639 if (begin == end) 608 if (begin == end)
640 return false; 609 return false;
641 610
642 if (end - begin == 1 && *begin == '*') { 611 if (end - begin == 1 && *begin == '*') {
643 port = 0; 612 port = 0;
644 portHasWildcard = true; 613 portHasWildcard = true;
645 return true; 614 return true;
646 } 615 }
647 616
648 const UChar* position = begin; 617 const UChar* position = begin;
649 skipWhile<isASCIIDigit>(position, end); 618 skipWhile<UChar, isASCIIDigit>(position, end);
650 619
651 if (position != end) 620 if (position != end)
652 return false; 621 return false;
653 622
654 bool ok; 623 bool ok;
655 port = charactersToIntStrict(begin, end - begin, &ok); 624 port = charactersToIntStrict(begin, end - begin, &ok);
656 return ok; 625 return ok;
657 } 626 }
658 627
659 void CSPSourceList::addSourceSelf() 628 void CSPSourceList::addSourceSelf()
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after
723 692
724 // 'plugin-types ____;' OR 'plugin-types;' 693 // 'plugin-types ____;' OR 'plugin-types;'
725 if (position == end) { 694 if (position == end) {
726 policy()->reportInvalidPluginTypes(String()); 695 policy()->reportInvalidPluginTypes(String());
727 return; 696 return;
728 } 697 }
729 698
730 while (position < end) { 699 while (position < end) {
731 // _____ OR _____mime1/mime1 700 // _____ OR _____mime1/mime1
732 // ^ ^ 701 // ^ ^
733 skipWhile<isASCIISpace>(position, end); 702 skipWhile<UChar, isASCIISpace>(position, end);
734 if (position == end) 703 if (position == end)
735 return; 704 return;
736 705
737 // mime1/mime1 mime2/mime2 706 // mime1/mime1 mime2/mime2
738 // ^ 707 // ^
739 begin = position; 708 begin = position;
740 if (!skipExactly<isMediaTypeCharacter>(position, end)) { 709 if (!skipExactly<UChar, isMediaTypeCharacter>(position, end)) {
741 skipWhile<isNotASCIISpace>(position, end); 710 skipWhile<UChar, isNotASCIISpace>(position, end);
742 policy()->reportInvalidPluginTypes(String(begin, position - begi n)); 711 policy()->reportInvalidPluginTypes(String(begin, position - begi n));
743 continue; 712 continue;
744 } 713 }
745 skipWhile<isMediaTypeCharacter>(position, end); 714 skipWhile<UChar, isMediaTypeCharacter>(position, end);
746 715
747 // mime1/mime1 mime2/mime2 716 // mime1/mime1 mime2/mime2
748 // ^ 717 // ^
749 if (!skipExactly(position, end, '/')) { 718 if (!skipExactly<UChar>(position, end, '/')) {
750 skipWhile<isNotASCIISpace>(position, end); 719 skipWhile<UChar, isNotASCIISpace>(position, end);
751 policy()->reportInvalidPluginTypes(String(begin, position - begi n)); 720 policy()->reportInvalidPluginTypes(String(begin, position - begi n));
752 continue; 721 continue;
753 } 722 }
754 723
755 // mime1/mime1 mime2/mime2 724 // mime1/mime1 mime2/mime2
756 // ^ 725 // ^
757 if (!skipExactly<isMediaTypeCharacter>(position, end)) { 726 if (!skipExactly<UChar, isMediaTypeCharacter>(position, end)) {
758 skipWhile<isNotASCIISpace>(position, end); 727 skipWhile<UChar, isNotASCIISpace>(position, end);
759 policy()->reportInvalidPluginTypes(String(begin, position - begi n)); 728 policy()->reportInvalidPluginTypes(String(begin, position - begi n));
760 continue; 729 continue;
761 } 730 }
762 skipWhile<isMediaTypeCharacter>(position, end); 731 skipWhile<UChar, isMediaTypeCharacter>(position, end);
763 732
764 // mime1/mime1 mime2/mime2 OR mime1/mime1 OR mime1/mime1/error 733 // mime1/mime1 mime2/mime2 OR mime1/mime1 OR mime1/mime1/error
765 // ^ ^ ^ 734 // ^ ^ ^
766 if (position < end && isNotASCIISpace(*position)) { 735 if (position < end && isNotASCIISpace(*position)) {
767 skipWhile<isNotASCIISpace>(position, end); 736 skipWhile<UChar, isNotASCIISpace>(position, end);
768 policy()->reportInvalidPluginTypes(String(begin, position - begi n)); 737 policy()->reportInvalidPluginTypes(String(begin, position - begi n));
769 continue; 738 continue;
770 } 739 }
771 m_pluginTypes.add(String(begin, position - begin)); 740 m_pluginTypes.add(String(begin, position - begin));
772 741
773 ASSERT(position == end || isASCIISpace(*position)); 742 ASSERT(position == end || isASCIISpace(*position));
774 } 743 }
775 } 744 }
776 745
777 HashSet<String> m_pluginTypes; 746 HashSet<String> m_pluginTypes;
(...skipping 428 matching lines...) Expand 10 before | Expand all | Expand 10 after
1206 void CSPDirectiveList::parse(const UChar* begin, const UChar* end) 1175 void CSPDirectiveList::parse(const UChar* begin, const UChar* end)
1207 { 1176 {
1208 m_header = String(begin, end - begin); 1177 m_header = String(begin, end - begin);
1209 1178
1210 if (begin == end) 1179 if (begin == end)
1211 return; 1180 return;
1212 1181
1213 const UChar* position = begin; 1182 const UChar* position = begin;
1214 while (position < end) { 1183 while (position < end) {
1215 const UChar* directiveBegin = position; 1184 const UChar* directiveBegin = position;
1216 skipUntil(position, end, ';'); 1185 skipUntil<UChar>(position, end, ';');
1217 1186
1218 String name, value; 1187 String name, value;
1219 if (parseDirective(directiveBegin, position, name, value)) { 1188 if (parseDirective(directiveBegin, position, name, value)) {
1220 ASSERT(!name.isEmpty()); 1189 ASSERT(!name.isEmpty());
1221 addDirective(name, value); 1190 addDirective(name, value);
1222 } 1191 }
1223 1192
1224 ASSERT(position == end || *position == ';'); 1193 ASSERT(position == end || *position == ';');
1225 skipExactly(position, end, ';'); 1194 skipExactly<UChar>(position, end, ';');
1226 } 1195 }
1227 } 1196 }
1228 1197
1229 // directive = *WSP [ directive-name [ WSP directive-value ] ] 1198 // directive = *WSP [ directive-name [ WSP directive-value ] ]
1230 // directive-name = 1*( ALPHA / DIGIT / "-" ) 1199 // directive-name = 1*( ALPHA / DIGIT / "-" )
1231 // directive-value = *( WSP / <VCHAR except ";"> ) 1200 // directive-value = *( WSP / <VCHAR except ";"> )
1232 // 1201 //
1233 bool CSPDirectiveList::parseDirective(const UChar* begin, const UChar* end, Stri ng& name, String& value) 1202 bool CSPDirectiveList::parseDirective(const UChar* begin, const UChar* end, Stri ng& name, String& value)
1234 { 1203 {
1235 ASSERT(name.isEmpty()); 1204 ASSERT(name.isEmpty());
1236 ASSERT(value.isEmpty()); 1205 ASSERT(value.isEmpty());
1237 1206
1238 const UChar* position = begin; 1207 const UChar* position = begin;
1239 skipWhile<isASCIISpace>(position, end); 1208 skipWhile<UChar, isASCIISpace>(position, end);
1240 1209
1241 // Empty directive (e.g. ";;;"). Exit early. 1210 // Empty directive (e.g. ";;;"). Exit early.
1242 if (position == end) 1211 if (position == end)
1243 return false; 1212 return false;
1244 1213
1245 const UChar* nameBegin = position; 1214 const UChar* nameBegin = position;
1246 skipWhile<isDirectiveNameCharacter>(position, end); 1215 skipWhile<UChar, isDirectiveNameCharacter>(position, end);
1247 1216
1248 // The directive-name must be non-empty. 1217 // The directive-name must be non-empty.
1249 if (nameBegin == position) { 1218 if (nameBegin == position) {
1250 skipWhile<isNotASCIISpace>(position, end); 1219 skipWhile<UChar, isNotASCIISpace>(position, end);
1251 m_policy->reportUnsupportedDirective(String(nameBegin, position - nameBe gin)); 1220 m_policy->reportUnsupportedDirective(String(nameBegin, position - nameBe gin));
1252 return false; 1221 return false;
1253 } 1222 }
1254 1223
1255 name = String(nameBegin, position - nameBegin); 1224 name = String(nameBegin, position - nameBegin);
1256 1225
1257 if (position == end) 1226 if (position == end)
1258 return true; 1227 return true;
1259 1228
1260 if (!skipExactly<isASCIISpace>(position, end)) { 1229 if (!skipExactly<UChar, isASCIISpace>(position, end)) {
1261 skipWhile<isNotASCIISpace>(position, end); 1230 skipWhile<UChar, isNotASCIISpace>(position, end);
1262 m_policy->reportUnsupportedDirective(String(nameBegin, position - nameBe gin)); 1231 m_policy->reportUnsupportedDirective(String(nameBegin, position - nameBe gin));
1263 return false; 1232 return false;
1264 } 1233 }
1265 1234
1266 skipWhile<isASCIISpace>(position, end); 1235 skipWhile<UChar, isASCIISpace>(position, end);
1267 1236
1268 const UChar* valueBegin = position; 1237 const UChar* valueBegin = position;
1269 skipWhile<isDirectiveValueCharacter>(position, end); 1238 skipWhile<UChar, isDirectiveValueCharacter>(position, end);
1270 1239
1271 if (position != end) { 1240 if (position != end) {
1272 m_policy->reportInvalidDirectiveValueCharacter(name, String(valueBegin, end - valueBegin)); 1241 m_policy->reportInvalidDirectiveValueCharacter(name, String(valueBegin, end - valueBegin));
1273 return false; 1242 return false;
1274 } 1243 }
1275 1244
1276 // The directive-value may be empty. 1245 // The directive-value may be empty.
1277 if (valueBegin == position) 1246 if (valueBegin == position)
1278 return true; 1247 return true;
1279 1248
1280 value = String(valueBegin, position - valueBegin); 1249 value = String(valueBegin, position - valueBegin);
1281 return true; 1250 return true;
1282 } 1251 }
1283 1252
1284 void CSPDirectiveList::parseReportURI(const String& name, const String& value) 1253 void CSPDirectiveList::parseReportURI(const String& name, const String& value)
1285 { 1254 {
1286 if (!m_reportURIs.isEmpty()) { 1255 if (!m_reportURIs.isEmpty()) {
1287 m_policy->reportDuplicateDirective(name); 1256 m_policy->reportDuplicateDirective(name);
1288 return; 1257 return;
1289 } 1258 }
1290 1259
1291 Vector<UChar> characters; 1260 Vector<UChar> characters;
1292 value.appendTo(characters); 1261 value.appendTo(characters);
1293 1262
1294 const UChar* position = characters.data(); 1263 const UChar* position = characters.data();
1295 const UChar* end = position + characters.size(); 1264 const UChar* end = position + characters.size();
1296 1265
1297 while (position < end) { 1266 while (position < end) {
1298 skipWhile<isASCIISpace>(position, end); 1267 skipWhile<UChar, isASCIISpace>(position, end);
1299 1268
1300 const UChar* urlBegin = position; 1269 const UChar* urlBegin = position;
1301 skipWhile<isNotASCIISpace>(position, end); 1270 skipWhile<UChar, isNotASCIISpace>(position, end);
1302 1271
1303 if (urlBegin < position) { 1272 if (urlBegin < position) {
1304 String url = String(urlBegin, position - urlBegin); 1273 String url = String(urlBegin, position - urlBegin);
1305 m_reportURIs.append(m_policy->completeURL(url)); 1274 m_reportURIs.append(m_policy->completeURL(url));
1306 } 1275 }
1307 } 1276 }
1308 } 1277 }
1309 1278
1310 1279
1311 template<class CSPDirectiveType> 1280 template<class CSPDirectiveType>
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
1344 m_policy->reportInvalidReflectedXSS(value); 1313 m_policy->reportInvalidReflectedXSS(value);
1345 return; 1314 return;
1346 } 1315 }
1347 1316
1348 Vector<UChar> characters; 1317 Vector<UChar> characters;
1349 value.appendTo(characters); 1318 value.appendTo(characters);
1350 1319
1351 const UChar* position = characters.data(); 1320 const UChar* position = characters.data();
1352 const UChar* end = position + characters.size(); 1321 const UChar* end = position + characters.size();
1353 1322
1354 skipWhile<isASCIISpace>(position, end); 1323 skipWhile<UChar, isASCIISpace>(position, end);
1355 const UChar* begin = position; 1324 const UChar* begin = position;
1356 skipWhile<isNotASCIISpace>(position, end); 1325 skipWhile<UChar, isNotASCIISpace>(position, end);
1357 1326
1358 // value1 1327 // value1
1359 // ^ 1328 // ^
1360 if (equalIgnoringCase("allow", begin, position - begin)) 1329 if (equalIgnoringCase("allow", begin, position - begin))
1361 m_reflectedXSSDisposition = ContentSecurityPolicy::AllowReflectedXSS; 1330 m_reflectedXSSDisposition = ContentSecurityPolicy::AllowReflectedXSS;
1362 else if (equalIgnoringCase("filter", begin, position - begin)) 1331 else if (equalIgnoringCase("filter", begin, position - begin))
1363 m_reflectedXSSDisposition = ContentSecurityPolicy::FilterReflectedXSS; 1332 m_reflectedXSSDisposition = ContentSecurityPolicy::FilterReflectedXSS;
1364 else if (equalIgnoringCase("block", begin, position - begin)) 1333 else if (equalIgnoringCase("block", begin, position - begin))
1365 m_reflectedXSSDisposition = ContentSecurityPolicy::BlockReflectedXSS; 1334 m_reflectedXSSDisposition = ContentSecurityPolicy::BlockReflectedXSS;
1366 else { 1335 else {
1367 m_reflectedXSSDisposition = ContentSecurityPolicy::ReflectedXSSInvalid; 1336 m_reflectedXSSDisposition = ContentSecurityPolicy::ReflectedXSSInvalid;
1368 m_policy->reportInvalidReflectedXSS(value); 1337 m_policy->reportInvalidReflectedXSS(value);
1369 return; 1338 return;
1370 } 1339 }
1371 1340
1372 skipWhile<isASCIISpace>(position, end); 1341 skipWhile<UChar, isASCIISpace>(position, end);
1373 if (position == end && m_reflectedXSSDisposition != ContentSecurityPolicy::R eflectedXSSUnset) 1342 if (position == end && m_reflectedXSSDisposition != ContentSecurityPolicy::R eflectedXSSUnset)
1374 return; 1343 return;
1375 1344
1376 // value1 value2 1345 // value1 value2
1377 // ^ 1346 // ^
1378 m_reflectedXSSDisposition = ContentSecurityPolicy::ReflectedXSSInvalid; 1347 m_reflectedXSSDisposition = ContentSecurityPolicy::ReflectedXSSInvalid;
1379 m_policy->reportInvalidReflectedXSS(value); 1348 m_policy->reportInvalidReflectedXSS(value);
1380 } 1349 }
1381 1350
1382 void CSPDirectiveList::addDirective(const String& name, const String& value) 1351 void CSPDirectiveList::addDirective(const String& name, const String& value)
(...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after
1469 header.appendTo(characters); 1438 header.appendTo(characters);
1470 1439
1471 const UChar* begin = characters.data(); 1440 const UChar* begin = characters.data();
1472 const UChar* end = begin + characters.size(); 1441 const UChar* end = begin + characters.size();
1473 1442
1474 // RFC2616, section 4.2 specifies that headers appearing multiple times can 1443 // RFC2616, section 4.2 specifies that headers appearing multiple times can
1475 // be combined with a comma. Walk the header string, and parse each comma 1444 // be combined with a comma. Walk the header string, and parse each comma
1476 // separated chunk as a separate header. 1445 // separated chunk as a separate header.
1477 const UChar* position = begin; 1446 const UChar* position = begin;
1478 while (position < end) { 1447 while (position < end) {
1479 skipUntil(position, end, ','); 1448 skipUntil<UChar>(position, end, ',');
1480 1449
1481 // header1,header2 OR header1 1450 // header1,header2 OR header1
1482 // ^ ^ 1451 // ^ ^
1483 OwnPtr<CSPDirectiveList> policy = CSPDirectiveList::create(this, begin, position, type); 1452 OwnPtr<CSPDirectiveList> policy = CSPDirectiveList::create(this, begin, position, type);
1484 1453
1485 // We disable 'eval()' even in the case of report-only policies, and rel y on the check in the V8Initializer::codeGenerationCheckCallbackInMainThread cal lback to determine whether the call should execute or not. 1454 // We disable 'eval()' even in the case of report-only policies, and rel y on the check in the V8Initializer::codeGenerationCheckCallbackInMainThread cal lback to determine whether the call should execute or not.
1486 if (!policy->allowEval(0, SuppressReport)) 1455 if (!policy->allowEval(0, SuppressReport))
1487 m_scriptExecutionContext->disableEval(policy->evalDisabledErrorMessa ge()); 1456 m_scriptExecutionContext->disableEval(policy->evalDisabledErrorMessa ge());
1488 1457
1489 m_policies.append(policy.release()); 1458 m_policies.append(policy.release());
1490 1459
1491 // Skip the comma, and begin the next header from the current position. 1460 // Skip the comma, and begin the next header from the current position.
1492 ASSERT(position == end || *position == ','); 1461 ASSERT(position == end || *position == ',');
1493 skipExactly(position, end, ','); 1462 skipExactly<UChar>(position, end, ',');
1494 begin = position; 1463 begin = position;
1495 } 1464 }
1496 } 1465 }
1497 1466
1498 void ContentSecurityPolicy::setOverrideAllowInlineStyle(bool value) 1467 void ContentSecurityPolicy::setOverrideAllowInlineStyle(bool value)
1499 { 1468 {
1500 m_overrideInlineStyleAllowed = value; 1469 m_overrideInlineStyleAllowed = value;
1501 } 1470 }
1502 1471
1503 const String& ContentSecurityPolicy::deprecatedHeader() const 1472 const String& ContentSecurityPolicy::deprecatedHeader() const
(...skipping 416 matching lines...) Expand 10 before | Expand all | Expand 10 after
1920 // Collisions have no security impact, so we can save space by storing only the string's hash rather than the whole report. 1889 // Collisions have no security impact, so we can save space by storing only the string's hash rather than the whole report.
1921 return !m_violationReportsSent.contains(report.impl()->hash()); 1890 return !m_violationReportsSent.contains(report.impl()->hash());
1922 } 1891 }
1923 1892
1924 void ContentSecurityPolicy::didSendViolationReport(const String& report) 1893 void ContentSecurityPolicy::didSendViolationReport(const String& report)
1925 { 1894 {
1926 m_violationReportsSent.add(report.impl()->hash()); 1895 m_violationReportsSent.add(report.impl()->hash());
1927 } 1896 }
1928 1897
1929 } // namespace WebCore 1898 } // namespace WebCore
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698