Chromium Code Reviews| Index: content/browser/renderer_host/render_widget_host_view_mac.mm |
| diff --git a/content/browser/renderer_host/render_widget_host_view_mac.mm b/content/browser/renderer_host/render_widget_host_view_mac.mm |
| index f4181638e616790dc650c1d63cad95f896645551..93a2a14f4094e1e9c7612faf011eb20c9b50ff60 100644 |
| --- a/content/browser/renderer_host/render_widget_host_view_mac.mm |
| +++ b/content/browser/renderer_host/render_widget_host_view_mac.mm |
| @@ -3017,6 +3017,12 @@ extern NSString *NSTextInputReplacementRangeAttributeName; |
| return rect; |
| } |
| +- (NSRange)selectedRange { |
| + if (selectedRange_.location == NSNotFound) |
|
Avi (use Gerrit)
2016/11/12 02:13:35
Oh. Oops.
|
| + return NSMakeRange(NSNotFound, 0); |
| + return selectedRange_; |
| +} |
| + |
| - (NSRange)markedRange { |
| // An input method calls this method to check if an application really has |
| // a text being composed when hasMarkedText call returns true. |
| @@ -3029,9 +3035,17 @@ extern NSString *NSTextInputReplacementRangeAttributeName; |
| - (NSAttributedString*)attributedSubstringForProposedRange:(NSRange)range |
| actualRange:(NSRangePointer)actualRange { |
| - // TODO(thakis): Pipe |actualRange| through TextInputClientMac machinery. |
| + // Prepare |actualRange| as if the proposed range is invalid. If it is valid, |
| + // then |actualRange| will be updated again. |
| if (actualRange) |
| - *actualRange = range; |
| + *actualRange = NSMakeRange(NSNotFound, 0); |
| + |
| + // The caller of this method is allowed to pass nonsensical ranges. These |
| + // can't even be converted into gfx::Ranges. |
| + if (range.location == NSNotFound || range.length == 0) |
| + return nil; |
| + if (range.length >= std::numeric_limits<NSUInteger>::max() - range.location) |
| + return nil; |
| const gfx::Range requested_range(range); |
| if (requested_range.is_reversed()) |
| @@ -3049,15 +3063,16 @@ extern NSString *NSTextInputReplacementRangeAttributeName; |
| expected_range = gfx::Range(offset, offset + expected_text->size()); |
| } |
| - if (!expected_range.Contains(requested_range)) |
| + gfx::Range actual_range = expected_range.Intersect(requested_range); |
| + if (!actual_range.IsValid()) |
| return nil; |
| // Gets the raw bytes to avoid unnecessary string copies for generating |
| // NSString. |
| const base::char16* bytes = |
| - &(*expected_text)[requested_range.start() - expected_range.start()]; |
| + &(*expected_text)[actual_range.start() - expected_range.start()]; |
| // Avoid integer overflow. |
| - base::CheckedNumeric<size_t> requested_len = requested_range.length(); |
| + base::CheckedNumeric<size_t> requested_len = actual_range.length(); |
| requested_len *= sizeof(base::char16); |
| NSUInteger bytes_len = base::strict_cast<NSUInteger, size_t>( |
| requested_len.ValueOrDefault(0)); |
| @@ -3065,6 +3080,9 @@ extern NSString *NSTextInputReplacementRangeAttributeName; |
| [[NSString alloc] initWithBytes:bytes |
| length:bytes_len |
| encoding:NSUTF16LittleEndianStringEncoding]); |
| + if (actualRange) |
| + *actualRange = actual_range.ToNSRange(); |
| + |
| return [[[NSAttributedString alloc] initWithString:ns_string] autorelease]; |
| } |