OLD | NEW |
1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 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 #import "ios/web/net/clients/crw_js_injection_network_client.h" | 5 #import "ios/web/net/clients/crw_js_injection_network_client.h" |
6 | 6 |
| 7 #include <stddef.h> |
| 8 #include <stdint.h> |
| 9 |
7 #include "base/logging.h" | 10 #include "base/logging.h" |
8 #include "base/mac/objc_property_releaser.h" | 11 #include "base/mac/objc_property_releaser.h" |
9 #include "base/mac/scoped_nsobject.h" | 12 #include "base/mac/scoped_nsobject.h" |
10 #include "base/metrics/histogram.h" | 13 #include "base/metrics/histogram.h" |
11 #import "ios/net/crn_http_url_response.h" | 14 #import "ios/net/crn_http_url_response.h" |
12 #import "ios/third_party/blink/src/html_tokenizer.h" | 15 #import "ios/third_party/blink/src/html_tokenizer.h" |
13 | 16 |
14 // CRWJSInjectionNetworkClient injects an external script tag reference for | 17 // CRWJSInjectionNetworkClient injects an external script tag reference for |
15 // crweb.js into HTML and XHTML documents. To do this correctly, three data | 18 // crweb.js into HTML and XHTML documents. To do this correctly, three data |
16 // points are needed: where to inject the script tag, what encoding the content | 19 // points are needed: where to inject the script tag, what encoding the content |
(...skipping 337 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
354 | 357 |
355 - (void)sendInjectedResponseIfNeeded { | 358 - (void)sendInjectedResponseIfNeeded { |
356 if (!_proceedWithInjection) | 359 if (!_proceedWithInjection) |
357 return; | 360 return; |
358 | 361 |
359 NSData* firstData = [_pendingData firstObject]; | 362 NSData* firstData = [_pendingData firstObject]; |
360 NSUInteger dataLength = [firstData length]; | 363 NSUInteger dataLength = [firstData length]; |
361 if (!dataLength) | 364 if (!dataLength) |
362 return; | 365 return; |
363 | 366 |
364 const uint8* bytes = reinterpret_cast<const uint8*>([firstData bytes]); | 367 const uint8_t* bytes = reinterpret_cast<const uint8_t*>([firstData bytes]); |
365 | 368 |
366 // Construct one data in which to send the content + injected script tag. | 369 // Construct one data in which to send the content + injected script tag. |
367 base::scoped_nsobject<NSMutableData> combined([[NSMutableData alloc] init]); | 370 base::scoped_nsobject<NSMutableData> combined([[NSMutableData alloc] init]); |
368 if (_byteOffsetAtWhichToInject) | 371 if (_byteOffsetAtWhichToInject) |
369 [combined appendBytes:static_cast<const void*>(bytes) | 372 [combined appendBytes:static_cast<const void*>(bytes) |
370 length:_byteOffsetAtWhichToInject]; | 373 length:_byteOffsetAtWhichToInject]; |
371 | 374 |
372 // Send back the JavaScript content to inject. | 375 // Send back the JavaScript content to inject. |
373 [combined appendData:[self jsInjectionContent]]; | 376 [combined appendData:[self jsInjectionContent]]; |
374 [combined | 377 [combined |
(...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
454 // Get some data to investigate. | 457 // Get some data to investigate. |
455 NSData* firstData = [_pendingData firstObject]; | 458 NSData* firstData = [_pendingData firstObject]; |
456 if (!firstData && [firstData length] < kMinimumBytesNeededForBOM) { | 459 if (!firstData && [firstData length] < kMinimumBytesNeededForBOM) { |
457 NOTREACHED(); | 460 NOTREACHED(); |
458 return; | 461 return; |
459 } | 462 } |
460 | 463 |
461 // Do the same check that WebKit does for the byte order mark (BOM), which | 464 // Do the same check that WebKit does for the byte order mark (BOM), which |
462 // must be right at the beginning of the content to be accepted. | 465 // must be right at the beginning of the content to be accepted. |
463 // Info on byte order mark: http://en.wikipedia.org/wiki/Byte_order_mark | 466 // Info on byte order mark: http://en.wikipedia.org/wiki/Byte_order_mark |
464 const uint8* bytes = reinterpret_cast<const uint8*>([firstData bytes]); | 467 const uint8_t* bytes = reinterpret_cast<const uint8_t*>([firstData bytes]); |
465 if (BytesEqual(bytes, 0xFF, 0xFE)) { | 468 if (BytesEqual(bytes, 0xFF, 0xFE)) { |
466 bytes += 2; | 469 bytes += 2; |
467 | 470 |
468 if (!BytesEqual(bytes, 0x00, 0x00)) { | 471 if (!BytesEqual(bytes, 0x00, 0x00)) { |
469 _contentEncoding = NSUTF16LittleEndianStringEncoding; | 472 _contentEncoding = NSUTF16LittleEndianStringEncoding; |
470 _headerLength += 2; | 473 _headerLength += 2; |
471 } else { | 474 } else { |
472 _contentEncoding = NSUTF32LittleEndianStringEncoding; | 475 _contentEncoding = NSUTF32LittleEndianStringEncoding; |
473 _headerLength += 4; | 476 _headerLength += 4; |
474 } | 477 } |
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
515 NSData* firstData = [_pendingData firstObject]; | 518 NSData* firstData = [_pendingData firstObject]; |
516 if (!firstData && [firstData length] < kMinimumBytesNeededForXMLDecl) { | 519 if (!firstData && [firstData length] < kMinimumBytesNeededForXMLDecl) { |
517 NOTREACHED(); | 520 NOTREACHED(); |
518 return; | 521 return; |
519 } | 522 } |
520 | 523 |
521 // Do the same check that WebKit does for an XML declaration. The XML spec | 524 // Do the same check that WebKit does for an XML declaration. The XML spec |
522 // is not exactly clear about what, if anything, can appear before an XML | 525 // is not exactly clear about what, if anything, can appear before an XML |
523 // declaration. Can there be white space? Can there be comments? WebKit only | 526 // declaration. Can there be white space? Can there be comments? WebKit only |
524 // accepts XML declarations if they are right at the beginning of the content. | 527 // accepts XML declarations if they are right at the beginning of the content. |
525 const uint8* bytes = reinterpret_cast<const uint8*>([firstData bytes]); | 528 const uint8_t* bytes = reinterpret_cast<const uint8_t*>([firstData bytes]); |
526 if (BytesEqual(bytes, '<', '?', 'x', 'm', 'l')) { | 529 if (BytesEqual(bytes, '<', '?', 'x', 'm', 'l')) { |
527 _contentEncoding = NSISOLatin1StringEncoding; | 530 _contentEncoding = NSISOLatin1StringEncoding; |
528 } else if (BytesEqual(bytes, '<', 0, '?', 0, 'x', 0)) { | 531 } else if (BytesEqual(bytes, '<', 0, '?', 0, 'x', 0)) { |
529 _contentEncoding = NSUTF16LittleEndianStringEncoding; | 532 _contentEncoding = NSUTF16LittleEndianStringEncoding; |
530 } else if (BytesEqual(bytes, 0, '<', 0, '?', 0, 'x')) { | 533 } else if (BytesEqual(bytes, 0, '<', 0, '?', 0, 'x')) { |
531 _contentEncoding = NSUTF16BigEndianStringEncoding; | 534 _contentEncoding = NSUTF16BigEndianStringEncoding; |
532 } else if (BytesEqual(bytes, '<', 0, 0, 0, '?', 0, 0, 0)) { | 535 } else if (BytesEqual(bytes, '<', 0, 0, 0, '?', 0, 0, 0)) { |
533 _contentEncoding = NSUTF32LittleEndianStringEncoding; | 536 _contentEncoding = NSUTF32LittleEndianStringEncoding; |
534 } else if (BytesEqual(bytes, 0, 0, 0, '<', 0, 0, 0, '?')) { | 537 } else if (BytesEqual(bytes, 0, 0, 0, '<', 0, 0, 0, '?')) { |
535 _contentEncoding = NSUTF32BigEndianStringEncoding; | 538 _contentEncoding = NSUTF32BigEndianStringEncoding; |
(...skipping 22 matching lines...) Expand all Loading... |
558 // It's possible that the server returned data in small chunks, so coalesce | 561 // It's possible that the server returned data in small chunks, so coalesce |
559 // the data into one buffer if needed. Try pooling everything into one chunk | 562 // the data into one buffer if needed. Try pooling everything into one chunk |
560 // that meets the limit of what we look at. | 563 // that meets the limit of what we look at. |
561 [self coalesceDataIfNeeded:kLimitOfBytesToCheckForHeadTag]; | 564 [self coalesceDataIfNeeded:kLimitOfBytesToCheckForHeadTag]; |
562 | 565 |
563 // Get some data to investigate. Of course we need at least | 566 // Get some data to investigate. Of course we need at least |
564 // kMinimumBytesNeededForHTMLTag bytes to do the investigation. | 567 // kMinimumBytesNeededForHTMLTag bytes to do the investigation. |
565 NSData* firstData = [_pendingData firstObject]; | 568 NSData* firstData = [_pendingData firstObject]; |
566 DCHECK([firstData length] >= kMinimumBytesNeededForHTMLTag); | 569 DCHECK([firstData length] >= kMinimumBytesNeededForHTMLTag); |
567 | 570 |
568 const uint8* bytes8 = reinterpret_cast<const uint8*>([firstData bytes]); | 571 const uint8_t* bytes8 = reinterpret_cast<const uint8_t*>([firstData bytes]); |
569 | 572 |
570 WebCore::CharacterProvider provider; | 573 WebCore::CharacterProvider provider; |
571 switch (_contentEncoding) { | 574 switch (_contentEncoding) { |
572 case NSUTF16BigEndianStringEncoding: | 575 case NSUTF16BigEndianStringEncoding: |
573 case NSUTF16LittleEndianStringEncoding: | 576 case NSUTF16LittleEndianStringEncoding: |
574 case NSUTF32BigEndianStringEncoding: | 577 case NSUTF32BigEndianStringEncoding: |
575 case NSUTF32LittleEndianStringEncoding: { | 578 case NSUTF32LittleEndianStringEncoding: { |
576 const uint16* bytes16 = | 579 const uint16_t* bytes16 = |
577 reinterpret_cast<const uint16*>(bytes8 + _headerLength); | 580 reinterpret_cast<const uint16_t*>(bytes8 + _headerLength); |
578 | 581 |
579 provider.setContents(bytes16, [firstData length] - _headerLength); | 582 provider.setContents(bytes16, [firstData length] - _headerLength); |
580 | 583 |
581 if (_contentEncoding == NSUTF16LittleEndianStringEncoding || | 584 if (_contentEncoding == NSUTF16LittleEndianStringEncoding || |
582 _contentEncoding == NSUTF32LittleEndianStringEncoding) | 585 _contentEncoding == NSUTF32LittleEndianStringEncoding) |
583 provider.setLittleEndian(); | 586 provider.setLittleEndian(); |
584 break; | 587 break; |
585 } | 588 } |
586 | 589 |
587 default: { | 590 default: { |
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
624 } | 627 } |
625 } | 628 } |
626 | 629 |
627 // There is an early exit case right at the end of the start-tag from the | 630 // There is an early exit case right at the end of the start-tag from the |
628 // WebCore::HTMLTokenizer::nextToken(), so double check to see if we hit | 631 // WebCore::HTMLTokenizer::nextToken(), so double check to see if we hit |
629 // the limit. | 632 // the limit. |
630 [self checkIfByteLimitPassed:provider]; | 633 [self checkIfByteLimitPassed:provider]; |
631 } | 634 } |
632 | 635 |
633 @end | 636 @end |
OLD | NEW |