Commit message: None
CVE: CVE-2011-3964
Vulnerability description: Google Chrome before 17.0.963.46 does not properly implement the drag-and-drop feature, which makes it easier for remote attackers to spoof the URL bar via unspecified vectors.

Project: Chrome

HDC WINAPI BeginPaintIntercept(HWND hWnd, LPPAINTSTRUCT lpPaint) {
  if (!edit_hwnd || (hWnd != edit_hwnd))
    return ::BeginPaint(hWnd, lpPaint);

  *lpPaint = paint_struct;
  return paint_struct.hdc;
}

Project: Chrome

LONG OmniboxViewWin::ClipXCoordToVisibleText(LONG x,
                                             bool is_triple_click) const {
  PARAFORMAT2 pf2;
  GetParaFormat(pf2);
  const bool ltr_text_in_ltr_layout = !(pf2.wEffects & PFE_RTLPARA) &&
      !base::i18n::StringContainsStrongRTLChars(GetText());
  const int length = GetTextLength();
  RECT r;
  GetRect(&r);
  const LONG first_position_x = PosFromChar(0).x;
  LONG min_x = first_position_x;
  if (!ltr_text_in_ltr_layout) {
    for (int i = 1; i < length; ++i)
      min_x = std::min(min_x, PosFromChar(i).x);
  }
  const LONG left_bound = std::max(r.left, min_x);
  LONG right_bound = r.right;
  LONG end_position_x = PosFromChar(length).x;
  if (end_position_x >= first_position_x) {
    right_bound = std::min(right_bound, end_position_x);  // LTR case.
  }
  if (x < left_bound) {
    return (is_triple_click && ltr_text_in_ltr_layout) ? left_bound - 1 :
                                                         left_bound;
  }
  if ((length == 0) || (x < right_bound))
    return x;
  return is_triple_click ? (right_bound - 1) : right_bound;
}

Project: Chrome

gfx::NativeView OmniboxViewWin::GetNativeView() const {
  return m_hWnd;
}

Project: Chrome

  gfx::NativeViewAccessible GetNativeViewAccessible() {
    return View::GetNativeViewAccessible();
  }

Project: Chrome

bool OmniboxViewWin::IsEditingOrEmpty() const {
  return model_->user_input_in_progress() || (GetTextLength() == 0);
}

Project: Chrome

bool OmniboxViewWin::IsItemForCommandIdDynamic(int command_id) const {
  return command_id == IDS_PASTE_AND_GO;
}

Project: Chrome

void OmniboxViewWin::OnMButtonDown(UINT /*keys*/, const CPoint& /*point*/) {
  tracking_double_click_ = false;

}

Project: Chrome

void OmniboxViewWin::OnMouseMove(UINT keys, const CPoint& point) {
  if (possible_drag_) {
    StartDragIfNecessary(point);
    return;
  }

  if (tracking_click_[kLeft] && !IsDrag(click_point_[kLeft], point))
    return;

  tracking_click_[kLeft] = false;

  if (!(keys & MK_LBUTTON)) {
    DefWindowProc(WM_MOUSEMOVE, keys, MAKELPARAM(point.x, point.y));
    return;
  }

  CHARRANGE selection;
  GetSel(selection);
  const bool possibly_can_discard_mousemove =
      (selection.cpMin == selection.cpMax) &&
      (((selection.cpMin == 0) &&
        (ClipXCoordToVisibleText(point.x, false) > point.x)) ||
       ((selection.cpMin == GetTextLength()) &&
        (ClipXCoordToVisibleText(point.x, false) < point.x)));
  if (!can_discard_mousemove_ || !possibly_can_discard_mousemove) {
    can_discard_mousemove_ = possibly_can_discard_mousemove;
    ScopedFreeze freeze(this, GetTextObjectModel());
    OnBeforePossibleChange();
    RECT r;
    GetRect(&r);
    DefWindowProc(WM_MOUSEMOVE, keys,
                  MAKELPARAM(point.x, (r.bottom - r.top) / 2));
    OnAfterPossibleChange();
  }
}

Project: Chrome

void OmniboxViewWin::OnPaint(HDC bogus_hdc) {

  CRect paint_clip_rect;
  if (!GetUpdateRect(&paint_clip_rect, true))
    return;

  CPaintDC paint_dc(m_hWnd);
  CDC memory_dc(CreateCompatibleDC(paint_dc));
  CRect rect;
  GetClientRect(&rect);
  CBitmap memory_bitmap(CreateCompatibleBitmap(paint_dc, rect.Width(),
                                               rect.Height()));
  HBITMAP old_bitmap = memory_dc.SelectBitmap(memory_bitmap);

  HWND old_edit_hwnd = edit_hwnd;
  edit_hwnd = m_hWnd;
  paint_struct = paint_dc.m_ps;
  paint_struct.hdc = memory_dc;
  DefWindowProc(WM_PAINT, reinterpret_cast<WPARAM>(bogus_hdc), 0);

  EraseTopOfSelection(&memory_dc, rect, paint_clip_rect);

  if (insecure_scheme_component_.is_nonempty())
    DrawSlashForInsecureScheme(memory_dc, rect, paint_clip_rect);

  if (drop_highlight_position_ != -1)
    DrawDropHighlight(memory_dc, rect, paint_clip_rect);

  BitBlt(paint_dc, rect.left, rect.top, rect.Width(), rect.Height(), memory_dc,
         rect.left, rect.top, SRCCOPY);
  memory_dc.SelectBitmap(old_bitmap);
  edit_hwnd = old_edit_hwnd;
}

Project: Chrome

void OmniboxViewWin::StartDragIfNecessary(const CPoint& point) {
  if (initiated_drag_ || !IsDrag(click_point_[kLeft], point))
    return;

  ui::OSExchangeData data;

  DWORD supported_modes = DROPEFFECT_COPY;

  CHARRANGE sel;
  GetSelection(sel);

  {
    ScopedFreeze freeze(this, GetTextObjectModel());
    DefWindowProc(WM_LBUTTONUP, 0,
                  MAKELPARAM(click_point_[kLeft].x, click_point_[kLeft].y));
    SetSelectionRange(sel);
  }

  const string16 start_text(GetText());
  string16 text_to_write(GetSelectedText());
  GURL url;
  bool write_url;
  const bool is_all_selected = IsSelectAllForRange(sel);

  model()->AdjustTextForCopy(std::min(sel.cpMin, sel.cpMax), is_all_selected,
                             &text_to_write, &url, &write_url);

  if (write_url) {
    string16 title;
    SkBitmap favicon;
    if (is_all_selected)
      model_->GetDataForURLExport(&url, &title, &favicon);
    drag_utils::SetURLAndDragImage(url, title, favicon, &data);
    supported_modes |= DROPEFFECT_LINK;
    content::RecordAction(UserMetricsAction("Omnibox_DragURL"));
  } else {
    supported_modes |= DROPEFFECT_MOVE;
    content::RecordAction(UserMetricsAction("Omnibox_DragString"));
  }

  data.SetString(text_to_write);

  scoped_refptr<ui::DragSource> drag_source(new ui::DragSource);
  DWORD dropped_mode;
  AutoReset<bool> auto_reset_in_drag(&in_drag_, true);
  if (DoDragDrop(ui::OSExchangeDataProviderWin::GetIDataObject(data),
                 drag_source, supported_modes, &dropped_mode) ==
          DRAGDROP_S_DROP) {
    if ((dropped_mode == DROPEFFECT_MOVE) && (start_text == GetText())) {
      ScopedFreeze freeze(this, GetTextObjectModel());
      OnBeforePossibleChange();
      SetSelectionRange(sel);
      ReplaceSel(L"", true);
      OnAfterPossibleChange();
    }
    possible_drag_ = false;
  } else {
    CPoint cursor_location;
    GetCursorPos(&cursor_location);

    CRect client_rect;
    GetClientRect(&client_rect);

    CPoint client_origin_on_screen(client_rect.left, client_rect.top);
    ClientToScreen(&client_origin_on_screen);
    client_rect.MoveToXY(client_origin_on_screen.x,
                         client_origin_on_screen.y);
    possible_drag_ = (client_rect.PtInRect(cursor_location) &&
                      ((GetKeyState(VK_LBUTTON) != 0) ||
                       (GetKeyState(VK_MBUTTON) != 0) ||
                       (GetKeyState(VK_RBUTTON) != 0)));
  }

  initiated_drag_ = true;
  tracking_click_[kLeft] = false;
}

Project: Chrome

void OmniboxViewWin::TextChanged() {
  ScopedFreeze freeze(this, GetTextObjectModel());
  EmphasizeURLComponents();
  model_->OnChanged();
}

Project: Chrome

int OmniboxViewWin::TextWidth() const {
  return WidthNeededToDisplay(GetText());
}

Project: Chrome

void OmniboxViewWin::EditDropTarget::UpdateDropHighlightPosition(
    const POINT& cursor_screen_position) {
  if (drag_has_string_) {
    POINT client_position = cursor_screen_position;
    ::ScreenToClient(edit_->m_hWnd, &client_position);
    int drop_position = edit_->CharFromPos(client_position);
    if (edit_->in_drag()) {
      LONG sel_start, sel_end;
      edit_->GetSel(sel_start, sel_end);
      if ((sel_start != sel_end) && (drop_position >= sel_start) &&
          (drop_position <= sel_end))
        drop_position = -1;
    } else {
      drop_position = -1;
    }
    edit_->SetDropHighlightPosition(drop_position);
  }
}

Project: Chrome

void OmniboxViewWin::UpdatePopup() {
  ScopedFreeze freeze(this, GetTextObjectModel());
  model_->SetInputInProgress(true);

  if (ime_candidate_window_open_)
    return;

  if (!model_->has_focus()) {
    return;
  }

  CHARRANGE sel;
  GetSel(sel);
  model_->StartAutocomplete(sel.cpMax != sel.cpMin,
                            (sel.cpMax < GetTextLength()) || IsImeComposing());
}