bool Instance::HandleInputEvent(const pp::InputEvent& event) {
  pp::InputEvent event_device_res(event);
  {
    pp::MouseInputEvent mouse_event(event);
    if (!mouse_event.is_null()) {
      pp::Point point = mouse_event.GetPosition();
      pp::Point movement = mouse_event.GetMovement();
      ScalePoint(device_scale_, &point);
      ScalePoint(device_scale_, &movement);
      mouse_event = pp::MouseInputEvent(
          this,
          event.GetType(),
          event.GetTimeStamp(),
          event.GetModifiers(),
          mouse_event.GetButton(),
          point,
          mouse_event.GetClickCount(),
          movement);
      event_device_res = mouse_event;
    }
  }

  if (event.GetType() == PP_INPUTEVENT_TYPE_MOUSEMOVE &&
     (event.GetModifiers() & PP_INPUTEVENT_MODIFIER_MIDDLEBUTTONDOWN)) {
    pp::MouseInputEvent mouse_event(event_device_res);
    pp::Point pos = mouse_event.GetPosition();
    EnableAutoscroll(pos);
    UpdateCursor(CalculateAutoscroll(pos));
    return true;
  } else {
    DisableAutoscroll();
  }

#ifdef ENABLE_THUMBNAILS
  if (event.GetType() == PP_INPUTEVENT_TYPE_MOUSELEAVE)
    thumbnails_.SlideOut();

  if (thumbnails_.HandleEvent(event_device_res))
    return true;
#endif

  if (toolbar_->HandleEvent(event_device_res))
    return true;

#ifdef ENABLE_THUMBNAILS
  if (v_scrollbar_.get() && event.GetType() == PP_INPUTEVENT_TYPE_MOUSEMOVE) {
    pp::MouseInputEvent mouse_event(event);
    pp::Point pt = mouse_event.GetPosition();
    pp::Rect v_scrollbar_rc;
    v_scrollbar_->GetLocation(&v_scrollbar_rc);
    if (v_scrollbar_rc.Contains(pt) &&
        (event.GetModifiers() & PP_INPUTEVENT_MODIFIER_LEFTBUTTONDOWN)) {
      thumbnails_.SlideIn();
    }

    if (!v_scrollbar_rc.Contains(pt) && thumbnails_.visible() &&
        !(event.GetModifiers() & PP_INPUTEVENT_MODIFIER_LEFTBUTTONDOWN) &&
        !thumbnails_.rect().Contains(pt)) {
      thumbnails_.SlideOut();
    }
  }
#endif

  pp::InputEvent offset_event(event_device_res);
  bool try_engine_first = true;
  switch (offset_event.GetType()) {
    case PP_INPUTEVENT_TYPE_MOUSEDOWN:
    case PP_INPUTEVENT_TYPE_MOUSEUP:
    case PP_INPUTEVENT_TYPE_MOUSEMOVE:
    case PP_INPUTEVENT_TYPE_MOUSEENTER:
    case PP_INPUTEVENT_TYPE_MOUSELEAVE: {
      pp::MouseInputEvent mouse_event(event_device_res);
      pp::MouseInputEvent mouse_event_dip(event);
      pp::Point point = mouse_event.GetPosition();
      point.set_x(point.x() - available_area_.x());
      offset_event = pp::MouseInputEvent(
          this,
          event.GetType(),
          event.GetTimeStamp(),
          event.GetModifiers(),
          mouse_event.GetButton(),
          point,
          mouse_event.GetClickCount(),
          mouse_event.GetMovement());
      if (!engine_->IsSelecting()) {
        if (!IsOverlayScrollbar() &&
            !available_area_.Contains(mouse_event.GetPosition())) {
          try_engine_first = false;
        } else if (IsOverlayScrollbar()) {
          pp::Rect temp;
          if ((v_scrollbar_.get() && v_scrollbar_->GetLocation(&temp) &&
              temp.Contains(mouse_event_dip.GetPosition())) ||
              (h_scrollbar_.get() && h_scrollbar_->GetLocation(&temp) &&
              temp.Contains(mouse_event_dip.GetPosition()))) {
            try_engine_first = false;
          }
        }
      }
      break;
    }
    default:
      break;
  }
  if (try_engine_first && engine_->HandleEvent(offset_event))
    return true;

  if (v_scrollbar_.get() && event.GetType() == PP_INPUTEVENT_TYPE_KEYDOWN) {
    pp::KeyboardInputEvent keyboard_event(event);
    bool no_h_scrollbar = !h_scrollbar_.get();
    uint32_t key_code = keyboard_event.GetKeyCode();
    bool page_down = no_h_scrollbar && key_code == ui::VKEY_RIGHT;
    bool page_up = no_h_scrollbar && key_code == ui::VKEY_LEFT;
    if (zoom_mode_ == ZOOM_FIT_TO_PAGE) {
      bool has_shift =
          keyboard_event.GetModifiers() & PP_INPUTEVENT_MODIFIER_SHIFTKEY;
      bool key_is_space = key_code == ui::VKEY_SPACE;
      page_down |= key_is_space || key_code == ui::VKEY_NEXT;
      page_up |= (key_is_space && has_shift) || (key_code == ui::VKEY_PRIOR);
     }
     if (page_down) {
       int page = engine_->GetFirstVisiblePage();
      if (engine_->GetPageRect(page).bottom() * zoom_ <=
          v_scrollbar_->GetValue())
        page++;
      ScrollToPage(page + 1);
      UpdateCursor(PP_CURSORTYPE_POINTER);
       return true;
     } else if (page_up) {
       int page = engine_->GetFirstVisiblePage();
       if (engine_->GetPageRect(page).y() * zoom_ >= v_scrollbar_->GetValue())
         page--;
       ScrollToPage(page);
      UpdateCursor(PP_CURSORTYPE_POINTER);
      return true;
    }
  }

  if (v_scrollbar_.get() && v_scrollbar_->HandleEvent(event)) {
    UpdateCursor(PP_CURSORTYPE_POINTER);
    return true;
  }

  if (h_scrollbar_.get() && h_scrollbar_->HandleEvent(event)) {
    UpdateCursor(PP_CURSORTYPE_POINTER);
    return true;
  }

  if (timer_pending_ &&
      (event.GetType() == PP_INPUTEVENT_TYPE_MOUSEUP ||
       event.GetType() == PP_INPUTEVENT_TYPE_MOUSEMOVE)) {
    timer_factory_.CancelAll();
    timer_pending_ = false;
  } else if (event.GetType() == PP_INPUTEVENT_TYPE_MOUSEMOVE &&
             engine_->IsSelecting()) {
    bool set_timer = false;
    pp::MouseInputEvent mouse_event(event);
    if (v_scrollbar_.get() &&
        (mouse_event.GetPosition().y() <= 0 ||
         mouse_event.GetPosition().y() >= (plugin_dip_size_.height() - 1))) {
      v_scrollbar_->ScrollBy(
          PP_SCROLLBY_LINE, mouse_event.GetPosition().y() >= 0 ? 1: -1);
      set_timer = true;
    }
    if (h_scrollbar_.get() &&
        (mouse_event.GetPosition().x() <= 0 ||
         mouse_event.GetPosition().x() >= (plugin_dip_size_.width() - 1))) {
      h_scrollbar_->ScrollBy(PP_SCROLLBY_LINE,
          mouse_event.GetPosition().x() >= 0 ? 1: -1);
      set_timer = true;
    }

    if (set_timer) {
      last_mouse_event_ = pp::MouseInputEvent(event);

      pp::CompletionCallback callback =
          timer_factory_.NewCallback(&Instance::OnTimerFired);
      pp::Module::Get()->core()->CallOnMainThread(kDragTimerMs, callback);
      timer_pending_ = true;
    }
  }

  if (event.GetType() == PP_INPUTEVENT_TYPE_KEYDOWN &&
      event.GetModifiers() & kDefaultKeyModifier) {
    pp::KeyboardInputEvent keyboard_event(event);
    switch (keyboard_event.GetKeyCode()) {
      case 'A':
        engine_->SelectAll();
        return true;
    }
  }

  return (event.GetType() == PP_INPUTEVENT_TYPE_MOUSEDOWN);
}

The Instance::HandleInputEvent function in pdf/instance.cc in the PDFium component in Google Chrome before 38.0.2125.101 interprets a certain -1 value as an index instead of a no-visible-page error code, which allows remote attackers to cause a denial of service (out-of-bounds read) via unspecified vectors.


bool Instance::HandleInputEvent(const pp::InputEvent& event) {
  pp::InputEvent event_device_res(event);
  {
    pp::MouseInputEvent mouse_event(event);
    if (!mouse_event.is_null()) {
      pp::Point point = mouse_event.GetPosition();
      pp::Point movement = mouse_event.GetMovement();
      ScalePoint(device_scale_, &point);
      ScalePoint(device_scale_, &movement);
      mouse_event = pp::MouseInputEvent(
          this,
          event.GetType(),
          event.GetTimeStamp(),
          event.GetModifiers(),
          mouse_event.GetButton(),
          point,
          mouse_event.GetClickCount(),
          movement);
      event_device_res = mouse_event;
    }
  }

  if (event.GetType() == PP_INPUTEVENT_TYPE_MOUSEMOVE &&
     (event.GetModifiers() & PP_INPUTEVENT_MODIFIER_MIDDLEBUTTONDOWN)) {
    pp::MouseInputEvent mouse_event(event_device_res);
    pp::Point pos = mouse_event.GetPosition();
    EnableAutoscroll(pos);
    UpdateCursor(CalculateAutoscroll(pos));
    return true;
  } else {
    DisableAutoscroll();
  }

#ifdef ENABLE_THUMBNAILS
  if (event.GetType() == PP_INPUTEVENT_TYPE_MOUSELEAVE)
    thumbnails_.SlideOut();

  if (thumbnails_.HandleEvent(event_device_res))
    return true;
#endif

  if (toolbar_->HandleEvent(event_device_res))
    return true;

#ifdef ENABLE_THUMBNAILS
  if (v_scrollbar_.get() && event.GetType() == PP_INPUTEVENT_TYPE_MOUSEMOVE) {
    pp::MouseInputEvent mouse_event(event);
    pp::Point pt = mouse_event.GetPosition();
    pp::Rect v_scrollbar_rc;
    v_scrollbar_->GetLocation(&v_scrollbar_rc);
    if (v_scrollbar_rc.Contains(pt) &&
        (event.GetModifiers() & PP_INPUTEVENT_MODIFIER_LEFTBUTTONDOWN)) {
      thumbnails_.SlideIn();
    }

    if (!v_scrollbar_rc.Contains(pt) && thumbnails_.visible() &&
        !(event.GetModifiers() & PP_INPUTEVENT_MODIFIER_LEFTBUTTONDOWN) &&
        !thumbnails_.rect().Contains(pt)) {
      thumbnails_.SlideOut();
    }
  }
#endif

  pp::InputEvent offset_event(event_device_res);
  bool try_engine_first = true;
  switch (offset_event.GetType()) {
    case PP_INPUTEVENT_TYPE_MOUSEDOWN:
    case PP_INPUTEVENT_TYPE_MOUSEUP:
    case PP_INPUTEVENT_TYPE_MOUSEMOVE:
    case PP_INPUTEVENT_TYPE_MOUSEENTER:
    case PP_INPUTEVENT_TYPE_MOUSELEAVE: {
      pp::MouseInputEvent mouse_event(event_device_res);
      pp::MouseInputEvent mouse_event_dip(event);
      pp::Point point = mouse_event.GetPosition();
      point.set_x(point.x() - available_area_.x());
      offset_event = pp::MouseInputEvent(
          this,
          event.GetType(),
          event.GetTimeStamp(),
          event.GetModifiers(),
          mouse_event.GetButton(),
          point,
          mouse_event.GetClickCount(),
          mouse_event.GetMovement());
      if (!engine_->IsSelecting()) {
        if (!IsOverlayScrollbar() &&
            !available_area_.Contains(mouse_event.GetPosition())) {
          try_engine_first = false;
        } else if (IsOverlayScrollbar()) {
          pp::Rect temp;
          if ((v_scrollbar_.get() && v_scrollbar_->GetLocation(&temp) &&
              temp.Contains(mouse_event_dip.GetPosition())) ||
              (h_scrollbar_.get() && h_scrollbar_->GetLocation(&temp) &&
              temp.Contains(mouse_event_dip.GetPosition()))) {
            try_engine_first = false;
          }
        }
      }
      break;
    }
    default:
      break;
  }
  if (try_engine_first && engine_->HandleEvent(offset_event))
    return true;

  if (v_scrollbar_.get() && event.GetType() == PP_INPUTEVENT_TYPE_KEYDOWN) {
    pp::KeyboardInputEvent keyboard_event(event);
    bool no_h_scrollbar = !h_scrollbar_.get();
    uint32_t key_code = keyboard_event.GetKeyCode();
    bool page_down = no_h_scrollbar && key_code == ui::VKEY_RIGHT;
    bool page_up = no_h_scrollbar && key_code == ui::VKEY_LEFT;
    if (zoom_mode_ == ZOOM_FIT_TO_PAGE) {
      bool has_shift =
          keyboard_event.GetModifiers() & PP_INPUTEVENT_MODIFIER_SHIFTKEY;
      bool key_is_space = key_code == ui::VKEY_SPACE;
      page_down |= key_is_space || key_code == ui::VKEY_NEXT;
      page_up |= (key_is_space && has_shift) || (key_code == ui::VKEY_PRIOR);
     }
     if (page_down) {
       int page = engine_->GetFirstVisiblePage();
      if (page == -1)
        return true;
      if (engine_->GetPageRect(page).bottom() * zoom_ <=
          v_scrollbar_->GetValue())
        page++;
      ScrollToPage(page + 1);
      UpdateCursor(PP_CURSORTYPE_POINTER);
       return true;
     } else if (page_up) {
       int page = engine_->GetFirstVisiblePage();
      if (page == -1)
        return true;
       if (engine_->GetPageRect(page).y() * zoom_ >= v_scrollbar_->GetValue())
         page--;
       ScrollToPage(page);
      UpdateCursor(PP_CURSORTYPE_POINTER);
      return true;
    }
  }

  if (v_scrollbar_.get() && v_scrollbar_->HandleEvent(event)) {
    UpdateCursor(PP_CURSORTYPE_POINTER);
    return true;
  }

  if (h_scrollbar_.get() && h_scrollbar_->HandleEvent(event)) {
    UpdateCursor(PP_CURSORTYPE_POINTER);
    return true;
  }

  if (timer_pending_ &&
      (event.GetType() == PP_INPUTEVENT_TYPE_MOUSEUP ||
       event.GetType() == PP_INPUTEVENT_TYPE_MOUSEMOVE)) {
    timer_factory_.CancelAll();
    timer_pending_ = false;
  } else if (event.GetType() == PP_INPUTEVENT_TYPE_MOUSEMOVE &&
             engine_->IsSelecting()) {
    bool set_timer = false;
    pp::MouseInputEvent mouse_event(event);
    if (v_scrollbar_.get() &&
        (mouse_event.GetPosition().y() <= 0 ||
         mouse_event.GetPosition().y() >= (plugin_dip_size_.height() - 1))) {
      v_scrollbar_->ScrollBy(
          PP_SCROLLBY_LINE, mouse_event.GetPosition().y() >= 0 ? 1: -1);
      set_timer = true;
    }
    if (h_scrollbar_.get() &&
        (mouse_event.GetPosition().x() <= 0 ||
         mouse_event.GetPosition().x() >= (plugin_dip_size_.width() - 1))) {
      h_scrollbar_->ScrollBy(PP_SCROLLBY_LINE,
          mouse_event.GetPosition().x() >= 0 ? 1: -1);
      set_timer = true;
    }

    if (set_timer) {
      last_mouse_event_ = pp::MouseInputEvent(event);

      pp::CompletionCallback callback =
          timer_factory_.NewCallback(&Instance::OnTimerFired);
      pp::Module::Get()->core()->CallOnMainThread(kDragTimerMs, callback);
      timer_pending_ = true;
    }
  }

  if (event.GetType() == PP_INPUTEVENT_TYPE_KEYDOWN &&
      event.GetModifiers() & kDefaultKeyModifier) {
    pp::KeyboardInputEvent keyboard_event(event);
    switch (keyboard_event.GetKeyCode()) {
      case 'A':
        engine_->SelectAll();
        return true;
    }
  }

  return (event.GetType() == PP_INPUTEVENT_TYPE_MOUSEDOWN);
}


bool ResourceFetcher::canRequest(Resource::Type type, const KURL& url, const ResourceLoaderOptions& options, bool forPreload, FetchRequest::OriginRestriction originRestriction) const
{
    SecurityOrigin* securityOrigin = options.securityOrigin.get();
    if (!securityOrigin && document())
        securityOrigin = document()->securityOrigin();

    if (securityOrigin && !securityOrigin->canDisplay(url)) {
        if (!forPreload)
            context().reportLocalLoadFailed(url);
        WTF_LOG(ResourceLoading, "ResourceFetcher::requestResource URL was not allowed by SecurityOrigin::canDisplay");
        return 0;
    }

    bool shouldBypassMainWorldContentSecurityPolicy = (frame() && frame()->script().shouldBypassMainWorldContentSecurityPolicy()) || (options.contentSecurityPolicyOption == DoNotCheckContentSecurityPolicy);

    switch (type) {
    case Resource::MainResource:
    case Resource::Image:
    case Resource::CSSStyleSheet:
    case Resource::Script:
    case Resource::Font:
    case Resource::Raw:
    case Resource::LinkPrefetch:
    case Resource::LinkSubresource:
    case Resource::TextTrack:
    case Resource::ImportResource:
    case Resource::Media:
        if (originRestriction == FetchRequest::RestrictToSameOrigin && !securityOrigin->canRequest(url)) {
            printAccessDeniedMessage(url);
            return false;
        }
        break;
    case Resource::XSLStyleSheet:
        ASSERT(RuntimeEnabledFeatures::xsltEnabled());
    case Resource::SVGDocument:
        if (!securityOrigin->canRequest(url)) {
            printAccessDeniedMessage(url);
            return false;
        }
        break;
    }

    ContentSecurityPolicy::ReportingStatus cspReporting = forPreload ?
        ContentSecurityPolicy::SuppressReport : ContentSecurityPolicy::SendReport;

    switch (type) {
    case Resource::XSLStyleSheet:
        ASSERT(RuntimeEnabledFeatures::xsltEnabled());
        if (!shouldBypassMainWorldContentSecurityPolicy && !m_document->contentSecurityPolicy()->allowScriptFromSource(url, cspReporting))
            return false;
        break;
    case Resource::Script:
    case Resource::ImportResource:
        if (!shouldBypassMainWorldContentSecurityPolicy && !m_document->contentSecurityPolicy()->allowScriptFromSource(url, cspReporting))
            return false;

        if (frame()) {
            Settings* settings = frame()->settings();
            if (!frame()->loader().client()->allowScriptFromSource(!settings || settings->scriptEnabled(), url)) {
                frame()->loader().client()->didNotAllowScript();
                return false;
            }
        }
        break;
    case Resource::CSSStyleSheet:
        if (!shouldBypassMainWorldContentSecurityPolicy && !m_document->contentSecurityPolicy()->allowStyleFromSource(url, cspReporting))
            return false;
        break;
    case Resource::SVGDocument:
    case Resource::Image:
        if (!shouldBypassMainWorldContentSecurityPolicy && !m_document->contentSecurityPolicy()->allowImageFromSource(url, cspReporting))
            return false;
        break;
    case Resource::Font: {
        if (!shouldBypassMainWorldContentSecurityPolicy && !m_document->contentSecurityPolicy()->allowFontFromSource(url, cspReporting))
            return false;
        break;
    }
    case Resource::MainResource:
    case Resource::Raw:
    case Resource::LinkPrefetch:
    case Resource::LinkSubresource:
        break;
    case Resource::Media:
    case Resource::TextTrack:
        if (!shouldBypassMainWorldContentSecurityPolicy && !m_document->contentSecurityPolicy()->allowMediaFromSource(url, cspReporting))
            return false;
         break;
     }

    if (!checkInsecureContent(type, url, options.mixedContentBlockingTreatment))
        return false;

    return true;
}

The ResourceFetcher::canRequest function in core/fetch/ResourceFetcher.cpp in Blink, as used in Google Chrome before 36.0.1985.125, does not properly restrict subresource requests associated with SVG files, which allows remote attackers to bypass the Same Origin Policy via a crafted file.


bool ResourceFetcher::canRequest(Resource::Type type, const KURL& url, const ResourceLoaderOptions& options, bool forPreload, FetchRequest::OriginRestriction originRestriction) const
{
    SecurityOrigin* securityOrigin = options.securityOrigin.get();
    if (!securityOrigin && document())
        securityOrigin = document()->securityOrigin();

    if (securityOrigin && !securityOrigin->canDisplay(url)) {
        if (!forPreload)
            context().reportLocalLoadFailed(url);
        WTF_LOG(ResourceLoading, "ResourceFetcher::requestResource URL was not allowed by SecurityOrigin::canDisplay");
        return 0;
    }

    bool shouldBypassMainWorldContentSecurityPolicy = (frame() && frame()->script().shouldBypassMainWorldContentSecurityPolicy()) || (options.contentSecurityPolicyOption == DoNotCheckContentSecurityPolicy);

    switch (type) {
    case Resource::MainResource:
    case Resource::Image:
    case Resource::CSSStyleSheet:
    case Resource::Script:
    case Resource::Font:
    case Resource::Raw:
    case Resource::LinkPrefetch:
    case Resource::LinkSubresource:
    case Resource::TextTrack:
    case Resource::ImportResource:
    case Resource::Media:
        if (originRestriction == FetchRequest::RestrictToSameOrigin && !securityOrigin->canRequest(url)) {
            printAccessDeniedMessage(url);
            return false;
        }
        break;
    case Resource::XSLStyleSheet:
        ASSERT(RuntimeEnabledFeatures::xsltEnabled());
    case Resource::SVGDocument:
        if (!securityOrigin->canRequest(url)) {
            printAccessDeniedMessage(url);
            return false;
        }
        break;
    }

    ContentSecurityPolicy::ReportingStatus cspReporting = forPreload ?
        ContentSecurityPolicy::SuppressReport : ContentSecurityPolicy::SendReport;

    switch (type) {
    case Resource::XSLStyleSheet:
        ASSERT(RuntimeEnabledFeatures::xsltEnabled());
        if (!shouldBypassMainWorldContentSecurityPolicy && !m_document->contentSecurityPolicy()->allowScriptFromSource(url, cspReporting))
            return false;
        break;
    case Resource::Script:
    case Resource::ImportResource:
        if (!shouldBypassMainWorldContentSecurityPolicy && !m_document->contentSecurityPolicy()->allowScriptFromSource(url, cspReporting))
            return false;

        if (frame()) {
            Settings* settings = frame()->settings();
            if (!frame()->loader().client()->allowScriptFromSource(!settings || settings->scriptEnabled(), url)) {
                frame()->loader().client()->didNotAllowScript();
                return false;
            }
        }
        break;
    case Resource::CSSStyleSheet:
        if (!shouldBypassMainWorldContentSecurityPolicy && !m_document->contentSecurityPolicy()->allowStyleFromSource(url, cspReporting))
            return false;
        break;
    case Resource::SVGDocument:
    case Resource::Image:
        if (!shouldBypassMainWorldContentSecurityPolicy && !m_document->contentSecurityPolicy()->allowImageFromSource(url, cspReporting))
            return false;
        break;
    case Resource::Font: {
        if (!shouldBypassMainWorldContentSecurityPolicy && !m_document->contentSecurityPolicy()->allowFontFromSource(url, cspReporting))
            return false;
        break;
    }
    case Resource::MainResource:
    case Resource::Raw:
    case Resource::LinkPrefetch:
    case Resource::LinkSubresource:
        break;
    case Resource::Media:
    case Resource::TextTrack:
        if (!shouldBypassMainWorldContentSecurityPolicy && !m_document->contentSecurityPolicy()->allowMediaFromSource(url, cspReporting))
            return false;
         break;
     }

    // SVG Images have unique security rules that prevent all subresource requests
    // except for data urls.
    if (type != Resource::MainResource) {
        if (frame() && frame()->chromeClient().isSVGImageChromeClient() && !url.protocolIsData())
            return false;
    }

    if (!checkInsecureContent(type, url, options.mixedContentBlockingTreatment))
        return false;

    return true;
}


int FFmpegVideoDecoder::GetVideoBuffer(AVCodecContext* codec_context,
                                       AVFrame* frame) {
  VideoFrame::Format format = PixelFormatToVideoFormat(codec_context->pix_fmt);
  if (format == VideoFrame::UNKNOWN)
    return AVERROR(EINVAL);
  DCHECK(format == VideoFrame::YV12 || format == VideoFrame::YV16 ||
          format == VideoFrame::YV12J);

   gfx::Size size(codec_context->width, codec_context->height);
  int ret;
  if ((ret = av_image_check_size(size.width(), size.height(), 0, NULL)) < 0)
     return ret;

   gfx::Size natural_size;
  if (codec_context->sample_aspect_ratio.num > 0) {
    natural_size = GetNaturalSize(size,
                                  codec_context->sample_aspect_ratio.num,
                                  codec_context->sample_aspect_ratio.den);
  } else {
     natural_size = config_.natural_size();
   }

  if (!VideoFrame::IsValidConfig(format, size, gfx::Rect(size), natural_size))
     return AVERROR(EINVAL);

  scoped_refptr<VideoFrame> video_frame =
      frame_pool_.CreateFrame(format, size, gfx::Rect(size),
                              natural_size, kNoTimestamp());

   for (int i = 0; i < 3; i++) {
     frame->base[i] = video_frame->data(i);
    frame->data[i] = video_frame->data(i);
    frame->linesize[i] = video_frame->stride(i);
  }

   frame->opaque = NULL;
   video_frame.swap(reinterpret_cast<VideoFrame**>(&frame->opaque));
   frame->type = FF_BUFFER_TYPE_USER;
  frame->width = codec_context->width;
  frame->height = codec_context->height;
   frame->format = codec_context->pix_fmt;

   return 0;
}

Heap-based buffer overflow in the FFmpegVideoDecoder::GetVideoBuffer function in media/filters/ffmpeg_video_decoder.cc in Google Chrome before 35.0.1916.153 allows remote attackers to cause a denial of service or possibly have unspecified other impact by leveraging VideoFrame data structures that are too small for proper interaction with an underlying FFmpeg library.


int FFmpegVideoDecoder::GetVideoBuffer(AVCodecContext* codec_context,
                                       AVFrame* frame) {
  VideoFrame::Format format = PixelFormatToVideoFormat(codec_context->pix_fmt);
  if (format == VideoFrame::UNKNOWN)
    return AVERROR(EINVAL);
  DCHECK(format == VideoFrame::YV12 || format == VideoFrame::YV16 ||
          format == VideoFrame::YV12J);

   gfx::Size size(codec_context->width, codec_context->height);
  const int ret = av_image_check_size(size.width(), size.height(), 0, NULL);
  if (ret < 0)
     return ret;

   gfx::Size natural_size;
  if (codec_context->sample_aspect_ratio.num > 0) {
    natural_size = GetNaturalSize(size,
                                  codec_context->sample_aspect_ratio.num,
                                  codec_context->sample_aspect_ratio.den);
  } else {
     natural_size = config_.natural_size();
   }

  // FFmpeg has specific requirements on the allocation size of the frame.  The
  // following logic replicates FFmpeg's allocation strategy to ensure buffers
  // are not overread / overwritten.  See ff_init_buffer_info() for details.
  //
  // When lowres is non-zero, dimensions should be divided by 2^(lowres), but
  // since we don't use this, just DCHECK that it's zero.
  DCHECK_EQ(codec_context->lowres, 0);
  gfx::Size coded_size(std::max(size.width(), codec_context->coded_width),
                       std::max(size.height(), codec_context->coded_height));

  if (!VideoFrame::IsValidConfig(
          format, coded_size, gfx::Rect(size), natural_size))
     return AVERROR(EINVAL);

  scoped_refptr<VideoFrame> video_frame = frame_pool_.CreateFrame(
      format, coded_size, gfx::Rect(size), natural_size, kNoTimestamp());

   for (int i = 0; i < 3; i++) {
     frame->base[i] = video_frame->data(i);
    frame->data[i] = video_frame->data(i);
    frame->linesize[i] = video_frame->stride(i);
  }

   frame->opaque = NULL;
   video_frame.swap(reinterpret_cast<VideoFrame**>(&frame->opaque));
   frame->type = FF_BUFFER_TYPE_USER;
  frame->width = coded_size.width();
  frame->height = coded_size.height();
   frame->format = codec_context->pix_fmt;

   return 0;
}


bool AsyncPixelTransfersCompletedQuery::End(
    base::subtle::Atomic32 submit_count) {
  AsyncMemoryParams mem_params;
  Buffer buffer = manager()->decoder()->GetSharedMemoryBuffer(shm_id());
  if (!buffer.shared_memory)
    return false;
  mem_params.shared_memory = buffer.shared_memory;
   mem_params.shm_size = buffer.size;
   mem_params.shm_data_offset = shm_offset();
   mem_params.shm_data_size = sizeof(QuerySync);

   observer_ = new AsyncPixelTransferCompletionObserverImpl(submit_count);

  manager()->decoder()->GetAsyncPixelTransferManager()
      ->AsyncNotifyCompletion(mem_params, observer_);

  return AddToPendingTransferQueue(submit_count);
}

The AsyncPixelTransfersCompletedQuery::End function in gpu/command_buffer/service/query_manager.cc in Google Chrome, as used in Google Chrome OS before 33.0.1750.152, does not check whether a certain position is within the bounds of a shared-memory segment, which allows remote attackers to cause a denial of service (GPU command-buffer memory corruption) or possibly have unspecified other impact via unknown vectors.


bool AsyncPixelTransfersCompletedQuery::End(
    base::subtle::Atomic32 submit_count) {
  AsyncMemoryParams mem_params;
  Buffer buffer = manager()->decoder()->GetSharedMemoryBuffer(shm_id());
  if (!buffer.shared_memory)
    return false;
  mem_params.shared_memory = buffer.shared_memory;
   mem_params.shm_size = buffer.size;
   mem_params.shm_data_offset = shm_offset();
   mem_params.shm_data_size = sizeof(QuerySync);
  uint32 end = mem_params.shm_data_offset + mem_params.shm_data_size;
  if (end > mem_params.shm_size || end < mem_params.shm_data_offset)
    return false;

   observer_ = new AsyncPixelTransferCompletionObserverImpl(submit_count);

  manager()->decoder()->GetAsyncPixelTransferManager()
      ->AsyncNotifyCompletion(mem_params, observer_);

  return AddToPendingTransferQueue(submit_count);
}


bool IsSmartVirtualKeyboardEnabled() {
  if (base::CommandLine::ForCurrentProcess()->HasSwitch(
           keyboard::switches::kEnableVirtualKeyboard)) {
     return false;
   }
  return !base::CommandLine::ForCurrentProcess()->HasSwitch(
      keyboard::switches::kDisableSmartVirtualKeyboard);
 }

Use-after-free vulnerability in modules/speech/SpeechSynthesis.cpp in Blink, as used in Google Chrome before 33.0.1750.149, allows remote attackers to cause a denial of service or possibly have unspecified other impact by leveraging improper handling of a certain utterance data structure.


bool IsSmartVirtualKeyboardEnabled() {
  if (base::CommandLine::ForCurrentProcess()->HasSwitch(
           keyboard::switches::kEnableVirtualKeyboard)) {
     return false;
   }
  return keyboard::IsSmartDeployEnabled();
 }


void RenderSVGImage::paint(PaintInfo& paintInfo, const LayoutPoint&)
{
    ANNOTATE_GRAPHICS_CONTEXT(paintInfo, this);

    if (paintInfo.context->paintingDisabled() || style()->visibility() == HIDDEN || !m_imageResource->hasImage())
        return;

    FloatRect boundingBox = repaintRectInLocalCoordinates();
    if (!SVGRenderSupport::paintInfoIntersectsRepaintRect(boundingBox, m_localTransform, paintInfo))
        return;

    PaintInfo childPaintInfo(paintInfo);
    bool drawsOutline = style()->outlineWidth() && (childPaintInfo.phase == PaintPhaseOutline || childPaintInfo.phase == PaintPhaseSelfOutline);
    if (drawsOutline || childPaintInfo.phase == PaintPhaseForeground) {
         GraphicsContextStateSaver stateSaver(*childPaintInfo.context);
         childPaintInfo.applyTransform(m_localTransform);

        if (childPaintInfo.phase == PaintPhaseForeground) {
             SVGRenderingContext renderingContext(this, childPaintInfo);

             if (renderingContext.isRenderingPrepared()) {
                if (style()->svgStyle()->bufferedRendering() == BR_STATIC  && renderingContext.bufferForeground(m_bufferedForeground))
                     return;

                 paintForeground(childPaintInfo);
            }
        }

        if (drawsOutline)
            paintOutline(childPaintInfo, IntRect(boundingBox));
    }
}

Use-after-free vulnerability in the RenderSVGImage::paint function in core/rendering/svg/RenderSVGImage.cpp in Blink, as used in Google Chrome before 32.0.1700.102, allows remote attackers to cause a denial of service or possibly have unspecified other impact via vectors involving a zero-size SVG image.


void RenderSVGImage::paint(PaintInfo& paintInfo, const LayoutPoint&)
{
    ANNOTATE_GRAPHICS_CONTEXT(paintInfo, this);

    if (paintInfo.context->paintingDisabled() || style()->visibility() == HIDDEN || !m_imageResource->hasImage())
        return;

    FloatRect boundingBox = repaintRectInLocalCoordinates();
    if (!SVGRenderSupport::paintInfoIntersectsRepaintRect(boundingBox, m_localTransform, paintInfo))
        return;

    PaintInfo childPaintInfo(paintInfo);
    bool drawsOutline = style()->outlineWidth() && (childPaintInfo.phase == PaintPhaseOutline || childPaintInfo.phase == PaintPhaseSelfOutline);
    if (drawsOutline || childPaintInfo.phase == PaintPhaseForeground) {
         GraphicsContextStateSaver stateSaver(*childPaintInfo.context);
         childPaintInfo.applyTransform(m_localTransform);

        if (childPaintInfo.phase == PaintPhaseForeground && !m_objectBoundingBox.isEmpty()) {
             SVGRenderingContext renderingContext(this, childPaintInfo);

             if (renderingContext.isRenderingPrepared()) {
                if (style()->svgStyle()->bufferedRendering() == BR_STATIC && renderingContext.bufferForeground(m_bufferedForeground))
                     return;

                 paintForeground(childPaintInfo);
            }
        }

        if (drawsOutline)
            paintOutline(childPaintInfo, IntRect(boundingBox));
    }
}


void SVGImage::setContainerSize(const IntSize& size)
{
    if (!m_page || !usesContainerSize())
        return;

    LocalFrame* frame = m_page->mainFrame();
     SVGSVGElement* rootElement = toSVGDocument(frame->document())->rootElement();
     if (!rootElement)
         return;
    RenderSVGRoot* renderer = toRenderSVGRoot(rootElement->renderer());
    if (!renderer)
        return;

     FrameView* view = frameView();
     view->resize(this->containerSize());

     renderer->setContainerSize(size);
 }

Use-after-free vulnerability in the SVGImage::setContainerSize function in core/svg/graphics/SVGImage.cpp in the SVG implementation in Blink, as used in Google Chrome before 33.0.1750.146, allows remote attackers to cause a denial of service or possibly have unspecified other impact via vectors related to the resizing of a view.


void SVGImage::setContainerSize(const IntSize& size)
{
    if (!m_page || !usesContainerSize())
        return;

    LocalFrame* frame = m_page->mainFrame();
     SVGSVGElement* rootElement = toSVGDocument(frame->document())->rootElement();
     if (!rootElement)
         return;

     FrameView* view = frameView();
     view->resize(this->containerSize());

    RenderSVGRoot* renderer = toRenderSVGRoot(rootElement->renderer());
    if (!renderer)
        return;
     renderer->setContainerSize(size);
 }


int32_t PepperFlashRendererHost::OnNavigate(
    ppapi::host::HostMessageContext* host_context,
    const ppapi::URLRequestInfoData& data,
    const std::string& target,
    bool from_user_action) {
  content::PepperPluginInstance* plugin_instance =
      host_->GetPluginInstance(pp_instance());
   if (!plugin_instance)
     return PP_ERROR_FAILED;

  ppapi::proxy::HostDispatcher* host_dispatcher =
      ppapi::proxy::HostDispatcher::GetForInstance(pp_instance());
  host_dispatcher->set_allow_plugin_reentrancy();

  base::WeakPtr<PepperFlashRendererHost> weak_ptr = weak_factory_.GetWeakPtr();
  navigate_replies_.push_back(host_context->MakeReplyMessageContext());
  plugin_instance->Navigate(data, target.c_str(), from_user_action);
  if (weak_ptr.get()) {
    SendReply(navigate_replies_.back(), IPC::Message());
    navigate_replies_.pop_back();
  }

  return PP_OK_COMPLETIONPENDING;
}


int32_t PepperFlashRendererHost::OnNavigate(
    ppapi::host::HostMessageContext* host_context,
    const ppapi::URLRequestInfoData& data,
    const std::string& target,
    bool from_user_action) {
  content::PepperPluginInstance* plugin_instance =
      host_->GetPluginInstance(pp_instance());
   if (!plugin_instance)
     return PP_ERROR_FAILED;

  std::map<std::string, FlashNavigateUsage>& rejected_headers =
      g_rejected_headers.Get();
  if (rejected_headers.empty()) {
    for (size_t i = 0; i < arraysize(kRejectedHttpRequestHeaders); ++i)
      rejected_headers[kRejectedHttpRequestHeaders[i]] =
          static_cast<FlashNavigateUsage>(i);
  }

  net::HttpUtil::HeadersIterator header_iter(data.headers.begin(),
                                             data.headers.end(),
                                             "\n\r");
  bool rejected = false;
  while (header_iter.GetNext()) {
    std::string lower_case_header_name = StringToLowerASCII(header_iter.name());
    if (!IsSimpleHeader(lower_case_header_name, header_iter.values())) {
      rejected = true;

      std::map<std::string, FlashNavigateUsage>::const_iterator iter =
          rejected_headers.find(lower_case_header_name);
      FlashNavigateUsage usage = iter != rejected_headers.end() ?
          iter->second : REJECT_OTHER_HEADERS;
      RecordFlashNavigateUsage(usage);
    }
  }

  RecordFlashNavigateUsage(TOTAL_NAVIGATE_REQUESTS);
  if (rejected) {
    RecordFlashNavigateUsage(TOTAL_REJECTED_NAVIGATE_REQUESTS);
    return PP_ERROR_NOACCESS;
  }

  ppapi::proxy::HostDispatcher* host_dispatcher =
      ppapi::proxy::HostDispatcher::GetForInstance(pp_instance());
  host_dispatcher->set_allow_plugin_reentrancy();

  base::WeakPtr<PepperFlashRendererHost> weak_ptr = weak_factory_.GetWeakPtr();
  navigate_replies_.push_back(host_context->MakeReplyMessageContext());
  plugin_instance->Navigate(data, target.c_str(), from_user_action);
  if (weak_ptr.get()) {
    SendReply(navigate_replies_.back(), IPC::Message());
    navigate_replies_.pop_back();
  }

  return PP_OK_COMPLETIONPENDING;
}


void ScreenPositionController::ConvertHostPointToRelativeToRootWindow(
    aura::Window* root_window,
    const aura::Window::Windows& root_windows,
    gfx::Point* point,
    aura::Window** target_root) {
  DCHECK(!root_window->parent());
   gfx::Point point_in_root(*point);
   root_window->GetHost()->ConvertPointFromHost(&point_in_root);

  *target_root = root_window;
  *point = point_in_root;
 #if defined(USE_X11) || defined(USE_OZONE)
  if (!root_window->GetHost()->GetBounds().Contains(*point)) {

    gfx::Point location_in_native(point_in_root);

    root_window->GetHost()->ConvertPointToNativeScreen(&location_in_native);

    for (size_t i = 0; i < root_windows.size(); ++i) {
      aura::WindowTreeHost* host = root_windows[i]->GetHost();
      const gfx::Rect native_bounds = host->GetBounds();
      if (native_bounds.Contains(location_in_native)) {
         *target_root = root_windows[i];
         *point = location_in_native;
         host->ConvertPointFromNativeScreen(point);
        break;
       }
     }
   }
#else
  NOTIMPLEMENTED();
 #endif
 }


void ScreenPositionController::ConvertHostPointToRelativeToRootWindow(
    aura::Window* root_window,
    const aura::Window::Windows& root_windows,
    gfx::Point* point,
    aura::Window** target_root) {
  DCHECK(!root_window->parent());
   gfx::Point point_in_root(*point);
   root_window->GetHost()->ConvertPointFromHost(&point_in_root);

 #if defined(USE_X11) || defined(USE_OZONE)
  gfx::Rect host_bounds(root_window->GetHost()->GetBounds().size());
  if (!host_bounds.Contains(*point)) {

    gfx::Point location_in_native(point_in_root);

    root_window->GetHost()->ConvertPointToNativeScreen(&location_in_native);

    for (size_t i = 0; i < root_windows.size(); ++i) {
      aura::WindowTreeHost* host = root_windows[i]->GetHost();
      const gfx::Rect native_bounds = host->GetBounds();
      if (native_bounds.Contains(location_in_native)) {
         *target_root = root_windows[i];
         *point = location_in_native;
         host->ConvertPointFromNativeScreen(point);
        return;
       }
     }
   }
 #endif
  *target_root = root_window;
  *point = point_in_root;
 }


 void FormAssociatedElement::formRemovedFromTree(const Node* formRoot)
 {
     ASSERT(m_form);
    if (toHTMLElement(this)->highestAncestor() != formRoot)
        setForm(0);
 }

The OneClickSigninBubbleView::WindowClosing function in browser/ui/views/sync/one_click_signin_bubble_view.cc in Google Chrome before 32.0.1700.76 on Windows and before 32.0.1700.77 on Mac OS X and Linux allows attackers to trigger a sync with an arbitrary Google account by leveraging improper handling of the closing of an untrusted signin confirm dialog.


 void FormAssociatedElement::formRemovedFromTree(const Node* formRoot)
 {
     ASSERT(m_form);
    if (toHTMLElement(this)->highestAncestor() == formRoot)
        return;
    RefPtr<HTMLElement> protector(toHTMLElement(this));
    setForm(0);
 }


 void WebPageSerializerImpl::openTagToString(Element* element,
                                             SerializeDomParam* param)
 {
    bool needSkip;
    StringBuilder result;
    result.append(preActionBeforeSerializeOpenTag(element, param, &needSkip));
    if (needSkip)
        return;
    result.append('<');
    result.append(element->nodeName().lower());
    AttributeCollection attributes = element->attributes();
    AttributeCollection::iterator end = attributes.end();
    for (AttributeCollection::iterator it = attributes.begin(); it != end; ++it) {
        result.append(' ');
        result.append(it->name().toString());
        result.appendLiteral("=\"");
        if (!it->value().isEmpty()) {
            const String& attrValue = it->value();

            const QualifiedName& attrName = it->name();
             if (element->hasLegalLinkAttribute(attrName)) {
                 if (attrValue.startsWith("javascript:", TextCaseInsensitive)) {
                    result.append(attrValue);
                 } else {
                     WebLocalFrameImpl* subFrame = WebLocalFrameImpl::fromFrameOwnerElement(element);
                    String completeURL = subFrame ? subFrame->frame()->document()->url() :
                                                    param->document->completeURL(attrValue);
                    if (m_localLinks.contains(completeURL)) {
                        if (!param->directoryName.isEmpty()) {
                            result.appendLiteral("./");
                             result.append(param->directoryName);
                             result.append('/');
                         }
                        result.append(m_localLinks.get(completeURL));
                     } else {
                        result.append(completeURL);
                     }
                 }
             } else {
                if (param->isHTMLDocument)
                    result.append(m_htmlEntities.convertEntitiesInString(attrValue));
                else
                    result.append(m_xmlEntities.convertEntitiesInString(attrValue));
            }
        }
        result.append('\"');
    }

    String addedContents = postActionAfterSerializeOpenTag(element, param);
    if (element->hasChildren() || param->haveAddedContentsBeforeEnd)
        result.append('>');
    result.append(addedContents);
    saveHTMLContentToBuffer(result.toString(), param);
}

The WebPageSerializerImpl::openTagToString function in WebKit/Source/web/WebPageSerializerImpl.cpp in the page serializer in Google Chrome before 47.0.2526.80 does not properly use HTML entities, which might allow remote attackers to inject arbitrary web script or HTML via a crafted document, as demonstrated by a double-quote character inside a single-quoted string.


 void WebPageSerializerImpl::openTagToString(Element* element,
                                             SerializeDomParam* param)
 {
    bool needSkip;
    StringBuilder result;
    result.append(preActionBeforeSerializeOpenTag(element, param, &needSkip));
    if (needSkip)
        return;
    result.append('<');
    result.append(element->nodeName().lower());
    AttributeCollection attributes = element->attributes();
    AttributeCollection::iterator end = attributes.end();
    for (AttributeCollection::iterator it = attributes.begin(); it != end; ++it) {
        result.append(' ');
        result.append(it->name().toString());
        result.appendLiteral("=\"");
        if (!it->value().isEmpty()) {
            const String& attrValue = it->value();

            const QualifiedName& attrName = it->name();
             if (element->hasLegalLinkAttribute(attrName)) {
                 if (attrValue.startsWith("javascript:", TextCaseInsensitive)) {
                    result.append(m_htmlEntities.convertEntitiesInString(attrValue));
                 } else {
                     WebLocalFrameImpl* subFrame = WebLocalFrameImpl::fromFrameOwnerElement(element);
                    String completeURL = subFrame ? subFrame->frame()->document()->url() :
                                                    param->document->completeURL(attrValue);
                    if (m_localLinks.contains(completeURL)) {
                        if (!param->directoryName.isEmpty()) {
                            result.appendLiteral("./");
                             result.append(param->directoryName);
                             result.append('/');
                         }
                        result.append(m_htmlEntities.convertEntitiesInString(m_localLinks.get(completeURL)));
                     } else {
                        result.append(m_htmlEntities.convertEntitiesInString(completeURL));
                     }
                 }
             } else {
                if (param->isHTMLDocument)
                    result.append(m_htmlEntities.convertEntitiesInString(attrValue));
                else
                    result.append(m_xmlEntities.convertEntitiesInString(attrValue));
            }
        }
        result.append('\"');
    }

    String addedContents = postActionAfterSerializeOpenTag(element, param);
    if (element->hasChildren() || param->haveAddedContentsBeforeEnd)
        result.append('>');
    result.append(addedContents);
    saveHTMLContentToBuffer(result.toString(), param);
}


 void Document::detach(const AttachContext& context)
 {
     TRACE_EVENT0("blink", "Document::detach");
    ASSERT(!m_frame || m_frame->tree().childCount() == 0);
     if (!isActive())
         return;

    FrameNavigationDisabler navigationDisabler(*m_frame);
    HTMLFrameOwnerElement::UpdateSuspendScope suspendWidgetHierarchyUpdates;
    ScriptForbiddenScope forbidScript;
    view()->dispose();
    m_markers->prepareForDestruction();
    if (LocalDOMWindow* window = this->domWindow())
        window->willDetachDocumentFromFrame();

    m_lifecycle.advanceTo(DocumentLifecycle::Stopping);

    if (page())
        page()->documentDetached(this);
    InspectorInstrumentation::documentDetached(this);

    if (m_frame->loader().client()->sharedWorkerRepositoryClient())
        m_frame->loader().client()->sharedWorkerRepositoryClient()->documentDetached(this);

    stopActiveDOMObjects();

    if (m_scriptedAnimationController)
        m_scriptedAnimationController->clearDocumentPointer();
    m_scriptedAnimationController.clear();

    m_scriptedIdleTaskController.clear();

    if (svgExtensions())
        accessSVGExtensions().pauseAnimations();

    if (m_domWindow)
        m_domWindow->clearEventQueue();

    if (m_layoutView)
        m_layoutView->setIsInWindow(false);

    if (registrationContext())
        registrationContext()->documentWasDetached();

    m_hoverNode = nullptr;
    m_activeHoverElement = nullptr;
    m_autofocusElement = nullptr;

    if (m_focusedElement.get()) {
        RefPtrWillBeRawPtr<Element> oldFocusedElement = m_focusedElement;
        m_focusedElement = nullptr;
        if (frameHost())
            frameHost()->chromeClient().focusedNodeChanged(oldFocusedElement.get(), nullptr);
    }

    if (this == &axObjectCacheOwner())
        clearAXObjectCache();

    m_layoutView = nullptr;
    ContainerNode::detach(context);

    if (this != &axObjectCacheOwner()) {
        if (AXObjectCache* cache = existingAXObjectCache()) {
            for (Node& node : NodeTraversal::descendantsOf(*this)) {
                cache->remove(&node);
            }
        }
    }

    styleEngine().didDetach();

    frameHost()->eventHandlerRegistry().documentDetached(*this);

    m_frame->inputMethodController().documentDetached();

    if (!loader())
        m_fetcher->clearContext();
    if (m_importsController)
        HTMLImportsController::removeFrom(*this);

    m_timers.setTimerTaskRunner(
        Platform::current()->currentThread()->scheduler()->timerTaskRunner()->adoptClone());

    m_frame = nullptr;

    if (m_mediaQueryMatcher)
        m_mediaQueryMatcher->documentDetached();

    DocumentLifecycleNotifier::notifyDocumentWasDetached();
    m_lifecycle.advanceTo(DocumentLifecycle::Stopped);

    DocumentLifecycleNotifier::notifyContextDestroyed();
    ExecutionContext::notifyContextDestroyed();
}

The DOM implementation in Google Chrome before 47.0.2526.73 allows remote attackers to bypass the Same Origin Policy via unspecified vectors, a different vulnerability than CVE-2015-6770.


 void Document::detach(const AttachContext& context)
 {
     TRACE_EVENT0("blink", "Document::detach");
    RELEASE_ASSERT(!m_frame || m_frame->tree().childCount() == 0);
     if (!isActive())
         return;

    FrameNavigationDisabler navigationDisabler(*m_frame);
    HTMLFrameOwnerElement::UpdateSuspendScope suspendWidgetHierarchyUpdates;
    ScriptForbiddenScope forbidScript;
    view()->dispose();
    m_markers->prepareForDestruction();
    if (LocalDOMWindow* window = this->domWindow())
        window->willDetachDocumentFromFrame();

    m_lifecycle.advanceTo(DocumentLifecycle::Stopping);

    if (page())
        page()->documentDetached(this);
    InspectorInstrumentation::documentDetached(this);

    if (m_frame->loader().client()->sharedWorkerRepositoryClient())
        m_frame->loader().client()->sharedWorkerRepositoryClient()->documentDetached(this);

    stopActiveDOMObjects();

    if (m_scriptedAnimationController)
        m_scriptedAnimationController->clearDocumentPointer();
    m_scriptedAnimationController.clear();

    m_scriptedIdleTaskController.clear();

    if (svgExtensions())
        accessSVGExtensions().pauseAnimations();

    if (m_domWindow)
        m_domWindow->clearEventQueue();

    if (m_layoutView)
        m_layoutView->setIsInWindow(false);

    if (registrationContext())
        registrationContext()->documentWasDetached();

    m_hoverNode = nullptr;
    m_activeHoverElement = nullptr;
    m_autofocusElement = nullptr;

    if (m_focusedElement.get()) {
        RefPtrWillBeRawPtr<Element> oldFocusedElement = m_focusedElement;
        m_focusedElement = nullptr;
        if (frameHost())
            frameHost()->chromeClient().focusedNodeChanged(oldFocusedElement.get(), nullptr);
    }

    if (this == &axObjectCacheOwner())
        clearAXObjectCache();

    m_layoutView = nullptr;
    ContainerNode::detach(context);

    if (this != &axObjectCacheOwner()) {
        if (AXObjectCache* cache = existingAXObjectCache()) {
            for (Node& node : NodeTraversal::descendantsOf(*this)) {
                cache->remove(&node);
            }
        }
    }

    styleEngine().didDetach();

    frameHost()->eventHandlerRegistry().documentDetached(*this);

    m_frame->inputMethodController().documentDetached();

    if (!loader())
        m_fetcher->clearContext();
    if (m_importsController)
        HTMLImportsController::removeFrom(*this);

    m_timers.setTimerTaskRunner(
        Platform::current()->currentThread()->scheduler()->timerTaskRunner()->adoptClone());

    m_frame = nullptr;

    if (m_mediaQueryMatcher)
        m_mediaQueryMatcher->documentDetached();

    DocumentLifecycleNotifier::notifyDocumentWasDetached();
    m_lifecycle.advanceTo(DocumentLifecycle::Stopped);

    DocumentLifecycleNotifier::notifyContextDestroyed();
    ExecutionContext::notifyContextDestroyed();
}


void DownloadUIAdapterDelegate::OpenItem(const OfflineItem& item,
                                          int64_t offline_id) {
   JNIEnv* env = AttachCurrentThread();
   Java_OfflinePageDownloadBridge_openItem(
      env, ConvertUTF8ToJavaString(env, item.page_url.spec()), offline_id);
 }

The DOM implementation in Blink, as used in Google Chrome before 47.0.2526.73, does not prevent javascript: URL navigation while a document is being detached, which allows remote attackers to bypass the Same Origin Policy via crafted JavaScript code that improperly interacts with a plugin.


void DownloadUIAdapterDelegate::OpenItem(const OfflineItem& item,
                                          int64_t offline_id) {
   JNIEnv* env = AttachCurrentThread();
   Java_OfflinePageDownloadBridge_openItem(
      env, ConvertUTF8ToJavaString(env, item.page_url.spec()), offline_id,
      offline_pages::ShouldOfflinePagesInDownloadHomeOpenInCct());
 }


int FindStartOffsetOfFileInZipFile(const char* zip_file, const char* filename) {
  FileDescriptor fd;
  if (!fd.OpenReadOnly(zip_file)) {
    LOG_ERRNO("%s: open failed trying to open zip file %s\n",
              __FUNCTION__, zip_file);
    return CRAZY_OFFSET_FAILED;
  }

  struct stat stat_buf;
  if (stat(zip_file, &stat_buf) == -1) {
    LOG_ERRNO("%s: stat failed trying to stat zip file %s\n",
              __FUNCTION__, zip_file);
    return CRAZY_OFFSET_FAILED;
  }

  if (stat_buf.st_size > kMaxZipFileLength) {
    LOG("%s: The size %ld of %s is too large to map\n",
        __FUNCTION__, stat_buf.st_size, zip_file);
    return CRAZY_OFFSET_FAILED;
  }

  void* mem = fd.Map(NULL, stat_buf.st_size, PROT_READ, MAP_PRIVATE, 0);
  if (mem == MAP_FAILED) {
    LOG_ERRNO("%s: mmap failed trying to mmap zip file %s\n",
              __FUNCTION__, zip_file);
    return CRAZY_OFFSET_FAILED;
  }
   ScopedMMap scoped_mmap(mem, stat_buf.st_size);

   uint8_t* mem_bytes = static_cast<uint8_t*>(mem);
  int off;
  for (off = stat_buf.st_size - sizeof(kEndOfCentralDirectoryMarker);
       off >= 0; --off) {
     if (ReadUInt32(mem_bytes, off) == kEndOfCentralDirectoryMarker) {
       break;
     }
  }
  if (off == -1) {
    LOG("%s: Failed to find end of central directory in %s\n",
        __FUNCTION__, zip_file);
    return CRAZY_OFFSET_FAILED;
  }

  uint32_t length_of_central_dir = ReadUInt32(
      mem_bytes, off + kOffsetOfCentralDirLengthInEndOfCentralDirectory);
  uint32_t start_of_central_dir = ReadUInt32(
      mem_bytes, off + kOffsetOfStartOfCentralDirInEndOfCentralDirectory);

  if (start_of_central_dir > off) {
    LOG("%s: Found out of range offset %u for start of directory in %s\n",
        __FUNCTION__, start_of_central_dir, zip_file);
    return CRAZY_OFFSET_FAILED;
  }

  uint32_t end_of_central_dir = start_of_central_dir + length_of_central_dir;
  if (end_of_central_dir > off) {
    LOG("%s: Found out of range offset %u for end of directory in %s\n",
        __FUNCTION__, end_of_central_dir, zip_file);
    return CRAZY_OFFSET_FAILED;
  }

  uint32_t num_entries = ReadUInt16(
      mem_bytes, off + kOffsetNumOfEntriesInEndOfCentralDirectory);

  off = start_of_central_dir;
  const int target_len = strlen(filename);
  int n = 0;
  for (; n < num_entries && off < end_of_central_dir; ++n) {
    uint32_t marker = ReadUInt32(mem_bytes, off);
    if (marker != kCentralDirHeaderMarker) {
      LOG("%s: Failed to find central directory header marker in %s. "
          "Found 0x%x but expected 0x%x\n", __FUNCTION__,
          zip_file, marker, kCentralDirHeaderMarker);
      return CRAZY_OFFSET_FAILED;
    }
    uint32_t file_name_length =
        ReadUInt16(mem_bytes, off + kOffsetFilenameLengthInCentralDirectory);
    uint32_t extra_field_length =
        ReadUInt16(mem_bytes, off + kOffsetExtraFieldLengthInCentralDirectory);
    uint32_t comment_field_length =
        ReadUInt16(mem_bytes, off + kOffsetCommentLengthInCentralDirectory);
    uint32_t header_length = kOffsetFilenameInCentralDirectory +
        file_name_length + extra_field_length + comment_field_length;

    uint32_t local_header_offset =
        ReadUInt32(mem_bytes, off + kOffsetLocalHeaderOffsetInCentralDirectory);

    uint8_t* filename_bytes =
        mem_bytes + off + kOffsetFilenameInCentralDirectory;

    if (file_name_length == target_len &&
        memcmp(filename_bytes, filename, target_len) == 0) {
      uint32_t marker = ReadUInt32(mem_bytes, local_header_offset);
      if (marker != kLocalHeaderMarker) {
        LOG("%s: Failed to find local file header marker in %s. "
            "Found 0x%x but expected 0x%x\n", __FUNCTION__,
            zip_file, marker, kLocalHeaderMarker);
        return CRAZY_OFFSET_FAILED;
      }

      uint32_t compression_method =
          ReadUInt16(
              mem_bytes,
              local_header_offset + kOffsetCompressionMethodInLocalHeader);
      if (compression_method != kCompressionMethodStored) {
        LOG("%s: %s is compressed within %s. "
            "Found compression method %u but expected %u\n", __FUNCTION__,
            filename, zip_file, compression_method, kCompressionMethodStored);
        return CRAZY_OFFSET_FAILED;
      }

      uint32_t file_name_length =
          ReadUInt16(
              mem_bytes,
              local_header_offset + kOffsetFilenameLengthInLocalHeader);
      uint32_t extra_field_length =
          ReadUInt16(
              mem_bytes,
              local_header_offset + kOffsetExtraFieldLengthInLocalHeader);
      uint32_t header_length =
          kOffsetFilenameInLocalHeader + file_name_length + extra_field_length;

      return local_header_offset + header_length;
    }

    off += header_length;
  }

  if (n < num_entries) {
    LOG("%s: Did not find all the expected entries in the central directory. "
        "Found %d but expected %d\n", __FUNCTION__, n, num_entries);
  }

  if (off < end_of_central_dir) {
    LOG("%s: There are %d extra bytes at the end of the central directory.\n",
        __FUNCTION__, end_of_central_dir - off);
  }

  LOG("%s: Did not find %s in %s\n", __FUNCTION__, filename, zip_file);
  return CRAZY_OFFSET_FAILED;
}

The FindStartOffsetOfFileInZipFile function in crazy_linker_zip.cpp in crazy_linker (aka Crazy Linker) in Android 5.x and 6.x, as used in Google Chrome before 47.0.2526.73, improperly searches for an EOCD record, which allows attackers to bypass a signature-validation requirement via a crafted ZIP archive.


int FindStartOffsetOfFileInZipFile(const char* zip_file, const char* filename) {
  FileDescriptor fd;
  if (!fd.OpenReadOnly(zip_file)) {
    LOG_ERRNO("%s: open failed trying to open zip file %s\n",
              __FUNCTION__, zip_file);
    return CRAZY_OFFSET_FAILED;
  }

  struct stat stat_buf;
  if (stat(zip_file, &stat_buf) == -1) {
    LOG_ERRNO("%s: stat failed trying to stat zip file %s\n",
              __FUNCTION__, zip_file);
    return CRAZY_OFFSET_FAILED;
  }

  if (stat_buf.st_size > kMaxZipFileLength) {
    LOG("%s: The size %ld of %s is too large to map\n",
        __FUNCTION__, stat_buf.st_size, zip_file);
    return CRAZY_OFFSET_FAILED;
  }

  void* mem = fd.Map(NULL, stat_buf.st_size, PROT_READ, MAP_PRIVATE, 0);
  if (mem == MAP_FAILED) {
    LOG_ERRNO("%s: mmap failed trying to mmap zip file %s\n",
              __FUNCTION__, zip_file);
    return CRAZY_OFFSET_FAILED;
  }
   ScopedMMap scoped_mmap(mem, stat_buf.st_size);

  // central directory marker. The earliest occurrence we accept is
  // size of end of central directory bytes back from from the end of the
  // file.
   uint8_t* mem_bytes = static_cast<uint8_t*>(mem);
  int off = stat_buf.st_size - kEndOfCentralDirectoryRecordSize;
  for (; off >= 0; --off) {
     if (ReadUInt32(mem_bytes, off) == kEndOfCentralDirectoryMarker) {
       break;
     }
  }
  if (off == -1) {
    LOG("%s: Failed to find end of central directory in %s\n",
        __FUNCTION__, zip_file);
    return CRAZY_OFFSET_FAILED;
  }

  uint32_t length_of_central_dir = ReadUInt32(
      mem_bytes, off + kOffsetOfCentralDirLengthInEndOfCentralDirectory);
  uint32_t start_of_central_dir = ReadUInt32(
      mem_bytes, off + kOffsetOfStartOfCentralDirInEndOfCentralDirectory);

  if (start_of_central_dir > off) {
    LOG("%s: Found out of range offset %u for start of directory in %s\n",
        __FUNCTION__, start_of_central_dir, zip_file);
    return CRAZY_OFFSET_FAILED;
  }

  uint32_t end_of_central_dir = start_of_central_dir + length_of_central_dir;
  if (end_of_central_dir > off) {
    LOG("%s: Found out of range offset %u for end of directory in %s\n",
        __FUNCTION__, end_of_central_dir, zip_file);
    return CRAZY_OFFSET_FAILED;
  }

  uint32_t num_entries = ReadUInt16(
      mem_bytes, off + kOffsetNumOfEntriesInEndOfCentralDirectory);

  off = start_of_central_dir;
  const int target_len = strlen(filename);
  int n = 0;
  for (; n < num_entries && off < end_of_central_dir; ++n) {
    uint32_t marker = ReadUInt32(mem_bytes, off);
    if (marker != kCentralDirHeaderMarker) {
      LOG("%s: Failed to find central directory header marker in %s. "
          "Found 0x%x but expected 0x%x\n", __FUNCTION__,
          zip_file, marker, kCentralDirHeaderMarker);
      return CRAZY_OFFSET_FAILED;
    }
    uint32_t file_name_length =
        ReadUInt16(mem_bytes, off + kOffsetFilenameLengthInCentralDirectory);
    uint32_t extra_field_length =
        ReadUInt16(mem_bytes, off + kOffsetExtraFieldLengthInCentralDirectory);
    uint32_t comment_field_length =
        ReadUInt16(mem_bytes, off + kOffsetCommentLengthInCentralDirectory);
    uint32_t header_length = kOffsetFilenameInCentralDirectory +
        file_name_length + extra_field_length + comment_field_length;

    uint32_t local_header_offset =
        ReadUInt32(mem_bytes, off + kOffsetLocalHeaderOffsetInCentralDirectory);

    uint8_t* filename_bytes =
        mem_bytes + off + kOffsetFilenameInCentralDirectory;

    if (file_name_length == target_len &&
        memcmp(filename_bytes, filename, target_len) == 0) {
      uint32_t marker = ReadUInt32(mem_bytes, local_header_offset);
      if (marker != kLocalHeaderMarker) {
        LOG("%s: Failed to find local file header marker in %s. "
            "Found 0x%x but expected 0x%x\n", __FUNCTION__,
            zip_file, marker, kLocalHeaderMarker);
        return CRAZY_OFFSET_FAILED;
      }

      uint32_t compression_method =
          ReadUInt16(
              mem_bytes,
              local_header_offset + kOffsetCompressionMethodInLocalHeader);
      if (compression_method != kCompressionMethodStored) {
        LOG("%s: %s is compressed within %s. "
            "Found compression method %u but expected %u\n", __FUNCTION__,
            filename, zip_file, compression_method, kCompressionMethodStored);
        return CRAZY_OFFSET_FAILED;
      }

      uint32_t file_name_length =
          ReadUInt16(
              mem_bytes,
              local_header_offset + kOffsetFilenameLengthInLocalHeader);
      uint32_t extra_field_length =
          ReadUInt16(
              mem_bytes,
              local_header_offset + kOffsetExtraFieldLengthInLocalHeader);
      uint32_t header_length =
          kOffsetFilenameInLocalHeader + file_name_length + extra_field_length;

      return local_header_offset + header_length;
    }

    off += header_length;
  }

  if (n < num_entries) {
    LOG("%s: Did not find all the expected entries in the central directory. "
        "Found %d but expected %d\n", __FUNCTION__, n, num_entries);
  }

  if (off < end_of_central_dir) {
    LOG("%s: There are %d extra bytes at the end of the central directory.\n",
        __FUNCTION__, end_of_central_dir - off);
  }

  LOG("%s: Did not find %s in %s\n", __FUNCTION__, filename, zip_file);
  return CRAZY_OFFSET_FAILED;
}


 bool CSPSourceList::matches(const KURL& url, ContentSecurityPolicy::RedirectStatus redirectStatus) const
 {
    if (m_allowStar)
         return true;

     KURL effectiveURL = m_policy->selfMatchesInnerURL() && SecurityOrigin::shouldUseInnerURL(url) ? SecurityOrigin::extractInnerURL(url) : url;

     if (m_allowSelf && m_policy->urlMatchesSelf(effectiveURL))
         return true;

    for (size_t i = 0; i < m_list.size(); ++i) {
        if (m_list[i].matches(effectiveURL, redirectStatus))
            return true;
    }
    return false;
 }

The CSPSourceList::matches function in WebKit/Source/core/frame/csp/CSPSourceList.cpp in the Content Security Policy (CSP) implementation in Google Chrome before 47.0.2526.73 accepts a blob:, data:, or filesystem: URL as a match for a * pattern, which allows remote attackers to bypass intended scheme restrictions in opportunistic circumstances by leveraging a policy that relies on this pattern.


 bool CSPSourceList::matches(const KURL& url, ContentSecurityPolicy::RedirectStatus redirectStatus) const
 {
    // The CSP spec specifically states that data:, blob:, and filesystem URLs
    // should not be captured by a '*" source
    // (http://www.w3.org/TR/CSP2/#source-list-guid-matching). Thus, in the
    // case of a full wildcard, data:, blob:, and filesystem: URLs are
    // explicitly checked for in the source list before allowing them through.
    if (m_allowStar) {
        if (url.protocolIs("blob") || url.protocolIs("data") || url.protocolIs("filesystem"))
            return hasSourceMatchInList(url, redirectStatus);
         return true;
    }

     KURL effectiveURL = m_policy->selfMatchesInnerURL() && SecurityOrigin::shouldUseInnerURL(url) ? SecurityOrigin::extractInnerURL(url) : url;

     if (m_allowSelf && m_policy->urlMatchesSelf(effectiveURL))
         return true;

    return hasSourceMatchInList(effectiveURL, redirectStatus);
 }


void MidiManagerUsb::DispatchSendMidiData(MidiManagerClient* client,
                                           uint32_t port_index,
                                           const std::vector<uint8>& data,
                                           double timestamp) {
  DCHECK_LT(port_index, output_streams_.size());
   output_streams_[port_index]->Send(data);
   client->AccumulateMidiBytesSent(data.size());
 }

Array index error in the MidiManagerUsb::DispatchSendMidiData function in media/midi/midi_manager_usb.cc in Google Chrome before 41.0.2272.76 allows remote attackers to cause a denial of service or possibly have unspecified other impact by leveraging renderer access to provide an invalid port index that triggers an out-of-bounds write operation, a different vulnerability than CVE-2015-1212.


void MidiManagerUsb::DispatchSendMidiData(MidiManagerClient* client,
                                           uint32_t port_index,
                                           const std::vector<uint8>& data,
                                           double timestamp) {
  if (port_index >= output_streams_.size()) {
    // |port_index| is provided by a renderer so we can't believe that it is
    // in the valid range.
    // TODO(toyoshim): Move this check to MidiHost and kill the renderer when
    // it fails.
    return;
  }
   output_streams_[port_index]->Send(data);
   client->AccumulateMidiBytesSent(data.size());
 }


bool OutOfProcessInstance::Init(uint32_t argc,
                                 const char* argn[],
                                 const char* argv[]) {
   pp::Var document_url_var = pp::URLUtil_Dev::Get()->GetDocumentURL(this);
  std::string document_url = document_url_var.is_string() ?
      document_url_var.AsString() : std::string();
   std::string extension_url = std::string(kChromeExtension);
  bool in_extension =
      !document_url.compare(0, extension_url.size(), extension_url);
  if (in_extension) {
    for (uint32_t i = 0; i < argc; ++i) {
      if (strcmp(argn[i], "full-frame") == 0) {
        full_ = true;
        break;
      }
     }
   }

  if (full_)
    SetPluginToHandleFindRequests();

  pp::VarDictionary translated_strings;
  translated_strings.Set(kType, kJSSetTranslatedStringsType);
  translated_strings.Set(kJSGetPasswordString,
      GetLocalizedString(PP_RESOURCESTRING_PDFGETPASSWORD));
  translated_strings.Set(kJSLoadingString,
      GetLocalizedString(PP_RESOURCESTRING_PDFLOADING));
  translated_strings.Set(kJSLoadFailedString,
      GetLocalizedString(PP_RESOURCESTRING_PDFLOAD_FAILED));
  PostMessage(translated_strings);

  text_input_.reset(new pp::TextInput_Dev(this));

  const char* stream_url = nullptr;
  const char* original_url = nullptr;
  const char* headers = nullptr;
  bool is_material = false;
  for (uint32_t i = 0; i < argc; ++i) {
    if (strcmp(argn[i], "src") == 0)
      original_url = argv[i];
    else if (strcmp(argn[i], "stream-url") == 0)
      stream_url = argv[i];
    else if (strcmp(argn[i], "headers") == 0)
      headers = argv[i];
    else if (strcmp(argn[i], "is-material") == 0)
      is_material = true;
    else if (strcmp(argn[i], "top-toolbar-height") == 0)
      base::StringToInt(argv[i], &top_toolbar_height_);
  }

  if (is_material)
    background_color_ = kBackgroundColorMaterial;
  else
    background_color_ = kBackgroundColor;

  if (!original_url)
    return false;

  if (!stream_url)
    stream_url = original_url;

  if (IsPrintPreviewUrl(original_url))
    return true;

  LoadUrl(stream_url);
  url_ = original_url;
  return engine_->New(original_url, headers);
}

The PDF viewer in Google Chrome before 46.0.2490.86 does not properly restrict scripting messages and API exposure, which allows remote attackers to bypass the Same Origin Policy via an unintended embedder or unintended plugin loading, related to pdf.js and out_of_process_instance.cc.


bool OutOfProcessInstance::Init(uint32_t argc,
                                 const char* argn[],
                                 const char* argv[]) {
  // the plugin to be loaded in the extension and print preview to avoid
  // exposing sensitive APIs directly to external websites.
   pp::Var document_url_var = pp::URLUtil_Dev::Get()->GetDocumentURL(this);
  if (!document_url_var.is_string())
    return false;
  std::string document_url = document_url_var.AsString();
   std::string extension_url = std::string(kChromeExtension);
  std::string print_preview_url = std::string(kChromePrint);
  if (!base::StringPiece(document_url).starts_with(kChromeExtension) &&
      !base::StringPiece(document_url).starts_with(kChromePrint)) {
    return false;
  }

  // Check if the plugin is full frame. This is passed in from JS.
  for (uint32_t i = 0; i < argc; ++i) {
    if (strcmp(argn[i], "full-frame") == 0) {
      full_ = true;
      break;
     }
   }

  if (full_)
    SetPluginToHandleFindRequests();

  pp::VarDictionary translated_strings;
  translated_strings.Set(kType, kJSSetTranslatedStringsType);
  translated_strings.Set(kJSGetPasswordString,
      GetLocalizedString(PP_RESOURCESTRING_PDFGETPASSWORD));
  translated_strings.Set(kJSLoadingString,
      GetLocalizedString(PP_RESOURCESTRING_PDFLOADING));
  translated_strings.Set(kJSLoadFailedString,
      GetLocalizedString(PP_RESOURCESTRING_PDFLOAD_FAILED));
  PostMessage(translated_strings);

  text_input_.reset(new pp::TextInput_Dev(this));

  const char* stream_url = nullptr;
  const char* original_url = nullptr;
  const char* headers = nullptr;
  bool is_material = false;
  for (uint32_t i = 0; i < argc; ++i) {
    if (strcmp(argn[i], "src") == 0)
      original_url = argv[i];
    else if (strcmp(argn[i], "stream-url") == 0)
      stream_url = argv[i];
    else if (strcmp(argn[i], "headers") == 0)
      headers = argv[i];
    else if (strcmp(argn[i], "is-material") == 0)
      is_material = true;
    else if (strcmp(argn[i], "top-toolbar-height") == 0)
      base::StringToInt(argv[i], &top_toolbar_height_);
  }

  if (is_material)
    background_color_ = kBackgroundColorMaterial;
  else
    background_color_ = kBackgroundColor;

  if (!original_url)
    return false;

  if (!stream_url)
    stream_url = original_url;

  if (IsPrintPreviewUrl(original_url))
    return true;

  LoadUrl(stream_url);
  url_ = original_url;
  return engine_->New(original_url, headers);
}


bool ScreenLayoutObserver::GetDisplayMessageForNotification(
    const ScreenLayoutObserver::DisplayInfoMap& old_info,
    base::string16* out_message,
    base::string16* out_additional_message) {
  if (old_display_mode_ != current_display_mode_) {
    if (current_display_mode_ == DisplayMode::MIRRORING) {
      *out_message = GetEnterMirrorModeMessage();
      return true;
    }
    if (old_display_mode_ == DisplayMode::MIRRORING &&
        GetExitMirrorModeMessage(out_message, out_additional_message)) {
      return true;
    }

    if (current_display_mode_ == DisplayMode::UNIFIED) {
      *out_message = GetEnterUnifiedModeMessage();
      return true;
    }
    if (old_display_mode_ == DisplayMode::UNIFIED) {
      *out_message = GetExitUnifiedModeMessage();
      return true;
    }

    if (current_display_mode_ == DisplayMode::DOCKED ||
        old_display_mode_ == DisplayMode::DOCKED) {
      return false;
    }
  }

  if (display_info_.size() < old_info.size()) {
    for (const auto& iter : old_info) {
      if (display_info_.count(iter.first))
        continue;

      *out_message =
          GetDisplayRemovedMessage(iter.second, out_additional_message);
      return true;
    }
  } else if (display_info_.size() > old_info.size()) {
    for (const auto& iter : display_info_) {
      if (old_info.count(iter.first))
        continue;

      *out_message = GetDisplayAddedMessage(iter.first, out_additional_message);
      return true;
    }
  }

  for (const auto& iter : display_info_) {
    DisplayInfoMap::const_iterator old_iter = old_info.find(iter.first);
    if (old_iter == old_info.end()) {
      NOTREACHED() << "A display mode transition that should have been handled"
                      "earlier.";
      return false;
    }

    if (iter.second.configured_ui_scale() !=
        old_iter->second.configured_ui_scale()) {
      *out_additional_message = l10n_util::GetStringFUTF16(
          IDS_ASH_STATUS_TRAY_DISPLAY_RESOLUTION_CHANGED,
           GetDisplayName(iter.first), GetDisplaySize(iter.first));
       return true;
     }
    if (iter.second.GetActiveRotation() !=
        old_iter->second.GetActiveRotation()) {
       int rotation_text_id = 0;
       switch (iter.second.GetActiveRotation()) {
         case display::Display::ROTATE_0:
          rotation_text_id = IDS_ASH_STATUS_TRAY_DISPLAY_STANDARD_ORIENTATION;
          break;
        case display::Display::ROTATE_90:
          rotation_text_id = IDS_ASH_STATUS_TRAY_DISPLAY_ORIENTATION_90;
          break;
        case display::Display::ROTATE_180:
          rotation_text_id = IDS_ASH_STATUS_TRAY_DISPLAY_ORIENTATION_180;
          break;
        case display::Display::ROTATE_270:
          rotation_text_id = IDS_ASH_STATUS_TRAY_DISPLAY_ORIENTATION_270;
          break;
      }
      *out_additional_message = l10n_util::GetStringFUTF16(
          IDS_ASH_STATUS_TRAY_DISPLAY_ROTATED, GetDisplayName(iter.first),
          l10n_util::GetStringUTF16(rotation_text_id));
      return true;
    }
  }

  return false;
}

Google Chrome before 41.0.2272.118 does not properly handle the interaction of IPC, the Gamepad API, and Google V8, which allows remote attackers to execute arbitrary code via unspecified vectors.


bool ScreenLayoutObserver::GetDisplayMessageForNotification(
    const ScreenLayoutObserver::DisplayInfoMap& old_info,
    base::string16* out_message,
    base::string16* out_additional_message) {
  if (old_display_mode_ != current_display_mode_) {
    if (current_display_mode_ == DisplayMode::MIRRORING) {
      *out_message = GetEnterMirrorModeMessage();
      return true;
    }
    if (old_display_mode_ == DisplayMode::MIRRORING &&
        GetExitMirrorModeMessage(out_message, out_additional_message)) {
      return true;
    }

    if (current_display_mode_ == DisplayMode::UNIFIED) {
      *out_message = GetEnterUnifiedModeMessage();
      return true;
    }
    if (old_display_mode_ == DisplayMode::UNIFIED) {
      *out_message = GetExitUnifiedModeMessage();
      return true;
    }

    if (current_display_mode_ == DisplayMode::DOCKED ||
        old_display_mode_ == DisplayMode::DOCKED) {
      return false;
    }
  }

  if (display_info_.size() < old_info.size()) {
    for (const auto& iter : old_info) {
      if (display_info_.count(iter.first))
        continue;

      *out_message =
          GetDisplayRemovedMessage(iter.second, out_additional_message);
      return true;
    }
  } else if (display_info_.size() > old_info.size()) {
    for (const auto& iter : display_info_) {
      if (old_info.count(iter.first))
        continue;

      *out_message = GetDisplayAddedMessage(iter.first, out_additional_message);
      return true;
    }
  }

  for (const auto& iter : display_info_) {
    DisplayInfoMap::const_iterator old_iter = old_info.find(iter.first);
    if (old_iter == old_info.end()) {
      NOTREACHED() << "A display mode transition that should have been handled"
                      "earlier.";
      return false;
    }

    if (iter.second.configured_ui_scale() !=
        old_iter->second.configured_ui_scale()) {
      *out_additional_message = l10n_util::GetStringFUTF16(
          IDS_ASH_STATUS_TRAY_DISPLAY_RESOLUTION_CHANGED,
           GetDisplayName(iter.first), GetDisplaySize(iter.first));
       return true;
     }
    // We don't show rotation change notification when the rotation source is
    // the accelerometer.
    if (iter.second.active_rotation_source() !=
            display::Display::ROTATION_SOURCE_ACCELEROMETER &&
        iter.second.GetActiveRotation() !=
            old_iter->second.GetActiveRotation()) {
       int rotation_text_id = 0;
       switch (iter.second.GetActiveRotation()) {
         case display::Display::ROTATE_0:
          rotation_text_id = IDS_ASH_STATUS_TRAY_DISPLAY_STANDARD_ORIENTATION;
          break;
        case display::Display::ROTATE_90:
          rotation_text_id = IDS_ASH_STATUS_TRAY_DISPLAY_ORIENTATION_90;
          break;
        case display::Display::ROTATE_180:
          rotation_text_id = IDS_ASH_STATUS_TRAY_DISPLAY_ORIENTATION_180;
          break;
        case display::Display::ROTATE_270:
          rotation_text_id = IDS_ASH_STATUS_TRAY_DISPLAY_ORIENTATION_270;
          break;
      }
      *out_additional_message = l10n_util::GetStringFUTF16(
          IDS_ASH_STATUS_TRAY_DISPLAY_ROTATED, GetDisplayName(iter.first),
          l10n_util::GetStringUTF16(rotation_text_id));
      return true;
    }
  }

  return false;
}


bool Document::SetFocusedElement(Element* new_focused_element,
                                 const FocusParams& params) {
  DCHECK(!lifecycle_.InDetach());

  clear_focused_element_timer_.Stop();

  if (new_focused_element && (new_focused_element->GetDocument() != this))
    return true;

  if (NodeChildRemovalTracker::IsBeingRemoved(new_focused_element))
    return true;

  if (focused_element_ == new_focused_element)
    return true;

  bool focus_change_blocked = false;
  Element* old_focused_element = focused_element_;
  focused_element_ = nullptr;

  UpdateDistributionForFlatTreeTraversal();
  Node* ancestor = (old_focused_element && old_focused_element->isConnected() &&
                    new_focused_element)
                       ? FlatTreeTraversal::CommonAncestor(*old_focused_element,
                                                           *new_focused_element)
                       : nullptr;

  if (old_focused_element) {
    old_focused_element->SetFocused(false, params.type);
    old_focused_element->SetHasFocusWithinUpToAncestor(false, ancestor);

    if (GetPage() && (GetPage()->GetFocusController().IsFocused())) {
      old_focused_element->DispatchBlurEvent(new_focused_element, params.type,
                                             params.source_capabilities);
      if (focused_element_) {
        focus_change_blocked = true;
        new_focused_element = nullptr;
      }

      old_focused_element->DispatchFocusOutEvent(event_type_names::kFocusout,
                                                 new_focused_element,
                                                 params.source_capabilities);
      old_focused_element->DispatchFocusOutEvent(event_type_names::kDOMFocusOut,
                                                 new_focused_element,
                                                 params.source_capabilities);

      if (focused_element_) {
        focus_change_blocked = true;
        new_focused_element = nullptr;
      }
    }
  }

  if (new_focused_element)
    UpdateStyleAndLayoutTreeForNode(new_focused_element);
  if (new_focused_element && new_focused_element->IsFocusable()) {
     if (IsRootEditableElement(*new_focused_element) &&
         !AcceptsEditingFocus(*new_focused_element)) {
      focus_change_blocked = true;
      goto SetFocusedElementDone;
     }
     focused_element_ = new_focused_element;
    SetSequentialFocusNavigationStartingPoint(focused_element_.Get());

    if (params.type != kWebFocusTypeNone)
      last_focus_type_ = params.type;

    focused_element_->SetFocused(true, params.type);
    focused_element_->SetHasFocusWithinUpToAncestor(true, ancestor);

     if (focused_element_ != new_focused_element) {
      focus_change_blocked = true;
      goto SetFocusedElementDone;
     }
     CancelFocusAppearanceUpdate();
     EnsurePaintLocationDataValidForNode(focused_element_);
    if (focused_element_ != new_focused_element) {
      focus_change_blocked = true;
      goto SetFocusedElementDone;
    }
     focused_element_->UpdateFocusAppearanceWithOptions(
         params.selection_behavior, params.options);

    if (GetPage() && (GetPage()->GetFocusController().IsFocused())) {
      focused_element_->DispatchFocusEvent(old_focused_element, params.type,
                                           params.source_capabilities);

       if (focused_element_ != new_focused_element) {
        focus_change_blocked = true;
        goto SetFocusedElementDone;
       }
       focused_element_->DispatchFocusInEvent(event_type_names::kFocusin,
                                             old_focused_element, params.type,
                                             params.source_capabilities);

       if (focused_element_ != new_focused_element) {
        focus_change_blocked = true;
        goto SetFocusedElementDone;
       }

      focused_element_->DispatchFocusInEvent(event_type_names::kDOMFocusIn,
                                             old_focused_element, params.type,
                                             params.source_capabilities);

       if (focused_element_ != new_focused_element) {
        focus_change_blocked = true;
        goto SetFocusedElementDone;
       }
     }
   }

  if (!focus_change_blocked && focused_element_) {
    if (AXObjectCache* cache = ExistingAXObjectCache()) {
      cache->HandleFocusedUIElementChanged(old_focused_element,
                                           new_focused_element);
    }
  }

  if (!focus_change_blocked && GetPage()) {
    GetPage()->GetChromeClient().FocusedNodeChanged(old_focused_element,
                                                     focused_element_.Get());
   }

SetFocusedElementDone:
   UpdateStyleAndLayoutTree();
   if (LocalFrame* frame = GetFrame())
     frame->Selection().DidChangeFocus();
  return !focus_change_blocked;
}

WebKit/Source/bindings/modules/v8/V8BindingForModules.cpp in Blink, as used in Google Chrome before 53.0.2785.113, does not properly consider getter side effects during array key conversion, which allows remote attackers to cause a denial of service (use-after-free) or possibly have unspecified other impact via crafted Indexed Database (aka IndexedDB) API calls.


bool Document::SetFocusedElement(Element* new_focused_element,
                                 const FocusParams& params) {
  DCHECK(!lifecycle_.InDetach());

  clear_focused_element_timer_.Stop();

  if (new_focused_element && (new_focused_element->GetDocument() != this))
    return true;

  if (NodeChildRemovalTracker::IsBeingRemoved(new_focused_element))
    return true;

  if (focused_element_ == new_focused_element)
    return true;

  bool focus_change_blocked = false;
  Element* old_focused_element = focused_element_;
  focused_element_ = nullptr;

  UpdateDistributionForFlatTreeTraversal();
  Node* ancestor = (old_focused_element && old_focused_element->isConnected() &&
                    new_focused_element)
                       ? FlatTreeTraversal::CommonAncestor(*old_focused_element,
                                                           *new_focused_element)
                       : nullptr;

  if (old_focused_element) {
    old_focused_element->SetFocused(false, params.type);
    old_focused_element->SetHasFocusWithinUpToAncestor(false, ancestor);

    if (GetPage() && (GetPage()->GetFocusController().IsFocused())) {
      old_focused_element->DispatchBlurEvent(new_focused_element, params.type,
                                             params.source_capabilities);
      if (focused_element_) {
        focus_change_blocked = true;
        new_focused_element = nullptr;
      }

      old_focused_element->DispatchFocusOutEvent(event_type_names::kFocusout,
                                                 new_focused_element,
                                                 params.source_capabilities);
      old_focused_element->DispatchFocusOutEvent(event_type_names::kDOMFocusOut,
                                                 new_focused_element,
                                                 params.source_capabilities);

      if (focused_element_) {
        focus_change_blocked = true;
        new_focused_element = nullptr;
      }
    }
  }

  if (new_focused_element)
    UpdateStyleAndLayoutTreeForNode(new_focused_element);
  if (new_focused_element && new_focused_element->IsFocusable()) {
     if (IsRootEditableElement(*new_focused_element) &&
         !AcceptsEditingFocus(*new_focused_element)) {
      UpdateStyleAndLayoutTree();
      if (LocalFrame* frame = GetFrame())
        frame->Selection().DidChangeFocus();
      return false;
     }
     focused_element_ = new_focused_element;
    SetSequentialFocusNavigationStartingPoint(focused_element_.Get());

    if (params.type != kWebFocusTypeNone)
      last_focus_type_ = params.type;

    focused_element_->SetFocused(true, params.type);
    focused_element_->SetHasFocusWithinUpToAncestor(true, ancestor);

     if (focused_element_ != new_focused_element) {
      UpdateStyleAndLayoutTree();
      if (LocalFrame* frame = GetFrame())
        frame->Selection().DidChangeFocus();
      return false;
     }
     CancelFocusAppearanceUpdate();
     EnsurePaintLocationDataValidForNode(focused_element_);
     focused_element_->UpdateFocusAppearanceWithOptions(
         params.selection_behavior, params.options);

    if (GetPage() && (GetPage()->GetFocusController().IsFocused())) {
      focused_element_->DispatchFocusEvent(old_focused_element, params.type,
                                           params.source_capabilities);

       if (focused_element_ != new_focused_element) {
        UpdateStyleAndLayoutTree();
        if (LocalFrame* frame = GetFrame())
          frame->Selection().DidChangeFocus();
        return false;
       }
       focused_element_->DispatchFocusInEvent(event_type_names::kFocusin,
                                             old_focused_element, params.type,
                                             params.source_capabilities);

       if (focused_element_ != new_focused_element) {
        UpdateStyleAndLayoutTree();
        if (LocalFrame* frame = GetFrame())
          frame->Selection().DidChangeFocus();
        return false;
       }

      focused_element_->DispatchFocusInEvent(event_type_names::kDOMFocusIn,
                                             old_focused_element, params.type,
                                             params.source_capabilities);

       if (focused_element_ != new_focused_element) {
        UpdateStyleAndLayoutTree();
        if (LocalFrame* frame = GetFrame())
          frame->Selection().DidChangeFocus();
        return false;
       }
     }
   }

  if (!focus_change_blocked && focused_element_) {
    if (AXObjectCache* cache = ExistingAXObjectCache()) {
      cache->HandleFocusedUIElementChanged(old_focused_element,
                                           new_focused_element);
    }
  }

  if (!focus_change_blocked && GetPage()) {
    GetPage()->GetChromeClient().FocusedNodeChanged(old_focused_element,
                                                     focused_element_.Get());
   }

   UpdateStyleAndLayoutTree();
   if (LocalFrame* frame = GetFrame())
     frame->Selection().DidChangeFocus();
  return !focus_change_blocked;
}


ChooserContextBase::GetGrantedObjects(const GURL& requesting_origin,
                                      const GURL& embedding_origin) {
  DCHECK_EQ(requesting_origin, requesting_origin.GetOrigin());
  DCHECK_EQ(embedding_origin, embedding_origin.GetOrigin());

  if (!CanRequestObjectPermission(requesting_origin, embedding_origin))
     return {};

   std::vector<std::unique_ptr<Object>> results;
  auto* info = new content_settings::SettingInfo();
   std::unique_ptr<base::DictionaryValue> setting =
      GetWebsiteSetting(requesting_origin, embedding_origin, info);
   std::unique_ptr<base::Value> objects;
   if (!setting->Remove(kObjectListKey, &objects))
     return results;

  std::unique_ptr<base::ListValue> object_list =
      base::ListValue::From(std::move(objects));
  if (!object_list)
    return results;

  for (auto& object : *object_list) {
     base::DictionaryValue* object_dict;
     if (object.GetAsDictionary(&object_dict) && IsValidObject(*object_dict)) {
       results.push_back(std::make_unique<Object>(
          requesting_origin, embedding_origin, object_dict, info->source,
           host_content_settings_map_->is_incognito()));
     }
   }
  return results;
}

Integer overflow in the opj_tcd_get_decoded_tile_size function in tcd.c in OpenJPEG, as used in PDFium in Google Chrome before 53.0.2785.89 on Windows and OS X and before 53.0.2785.92 on Linux, allows remote attackers to cause a denial of service (heap-based buffer overflow) or possibly have unspecified other impact via crafted JPEG 2000 data.


ChooserContextBase::GetGrantedObjects(const GURL& requesting_origin,
                                      const GURL& embedding_origin) {
  DCHECK_EQ(requesting_origin, requesting_origin.GetOrigin());
  DCHECK_EQ(embedding_origin, embedding_origin.GetOrigin());

  if (!CanRequestObjectPermission(requesting_origin, embedding_origin))
     return {};

   std::vector<std::unique_ptr<Object>> results;
  content_settings::SettingInfo info;
   std::unique_ptr<base::DictionaryValue> setting =
      GetWebsiteSetting(requesting_origin, embedding_origin, &info);
   std::unique_ptr<base::Value> objects;
   if (!setting->Remove(kObjectListKey, &objects))
     return results;

  std::unique_ptr<base::ListValue> object_list =
      base::ListValue::From(std::move(objects));
  if (!object_list)
    return results;

  for (auto& object : *object_list) {
     base::DictionaryValue* object_dict;
     if (object.GetAsDictionary(&object_dict) && IsValidObject(*object_dict)) {
       results.push_back(std::make_unique<Object>(
          requesting_origin, embedding_origin, object_dict, info.source,
           host_content_settings_map_->is_incognito()));
     }
   }
  return results;
}


void EventBindings::AttachFilteredEvent(
    const v8::FunctionCallbackInfo<v8::Value>& args) {
  CHECK_EQ(2, args.Length());
  CHECK(args[0]->IsString());
  CHECK(args[1]->IsObject());

  std::string event_name = *v8::String::Utf8Value(args[0]);
  if (!context()->HasAccessOrThrowError(event_name))
    return;

  std::unique_ptr<base::DictionaryValue> filter;
  {
    std::unique_ptr<content::V8ValueConverter> converter(
        content::V8ValueConverter::create());
    std::unique_ptr<base::Value> filter_value(converter->FromV8Value(
        v8::Local<v8::Object>::Cast(args[1]), context()->v8_context()));
    if (!filter_value || !filter_value->IsType(base::Value::TYPE_DICTIONARY)) {
      args.GetReturnValue().Set(static_cast<int32_t>(-1));
      return;
    }
     filter = base::DictionaryValue::From(std::move(filter_value));
   }

  base::DictionaryValue* filter_weak = filter.get();
   int id = g_event_filter.Get().AddEventMatcher(
       event_name, ParseEventMatcher(std::move(filter)));
   attached_matcher_ids_.insert(id);

   std::string extension_id = context()->GetExtensionID();
   if (AddFilter(event_name, extension_id, *filter_weak)) {
     bool lazy = ExtensionFrameHelper::IsContextForEventPage(context());
    content::RenderThread::Get()->Send(new ExtensionHostMsg_AddFilteredListener(
        extension_id, event_name, *filter_weak, lazy));
  }

  args.GetReturnValue().Set(static_cast<int32_t>(id));
}

extensions/renderer/event_bindings.cc in the event bindings in Google Chrome before 53.0.2785.89 on Windows and OS X and before 53.0.2785.92 on Linux attempts to process filtered events after failure to add an event matcher, which allows remote attackers to cause a denial of service (use-after-free) or possibly have unspecified other impact via unknown vectors.


void EventBindings::AttachFilteredEvent(
    const v8::FunctionCallbackInfo<v8::Value>& args) {
  CHECK_EQ(2, args.Length());
  CHECK(args[0]->IsString());
  CHECK(args[1]->IsObject());

  std::string event_name = *v8::String::Utf8Value(args[0]);
  if (!context()->HasAccessOrThrowError(event_name))
    return;

  std::unique_ptr<base::DictionaryValue> filter;
  {
    std::unique_ptr<content::V8ValueConverter> converter(
        content::V8ValueConverter::create());
    std::unique_ptr<base::Value> filter_value(converter->FromV8Value(
        v8::Local<v8::Object>::Cast(args[1]), context()->v8_context()));
    if (!filter_value || !filter_value->IsType(base::Value::TYPE_DICTIONARY)) {
      args.GetReturnValue().Set(static_cast<int32_t>(-1));
      return;
    }
     filter = base::DictionaryValue::From(std::move(filter_value));
   }

   int id = g_event_filter.Get().AddEventMatcher(
       event_name, ParseEventMatcher(std::move(filter)));
  if (id == -1) {
    args.GetReturnValue().Set(static_cast<int32_t>(-1));
    return;
  }
   attached_matcher_ids_.insert(id);

  const EventMatcher* matcher = g_event_filter.Get().GetEventMatcher(id);
  DCHECK(matcher);
  base::DictionaryValue* filter_weak = matcher->value();
   std::string extension_id = context()->GetExtensionID();
   if (AddFilter(event_name, extension_id, *filter_weak)) {
     bool lazy = ExtensionFrameHelper::IsContextForEventPage(context());
    content::RenderThread::Get()->Send(new ExtensionHostMsg_AddFilteredListener(
        extension_id, event_name, *filter_weak, lazy));
  }

  args.GetReturnValue().Set(static_cast<int32_t>(id));
}


void AXTree::PopulateOrderedSetItems(const AXNode* ordered_set,
                                     const AXNode* local_parent,
                                     std::vector<const AXNode*>& items,
                                     bool node_is_radio_button) const {
  if (!(ordered_set == local_parent)) {
    if (local_parent->data().role == ordered_set->data().role)
      return;
  }

   for (int i = 0; i < local_parent->child_count(); ++i) {
     const AXNode* child = local_parent->GetUnignoredChildAtIndex(i);

     if (node_is_radio_button &&
         child->data().role == ax::mojom::Role::kRadioButton)
      items.push_back(child);

    if (!node_is_radio_button && child->SetRoleMatchesItemRole(ordered_set))
      items.push_back(child);

    if (child->data().role == ax::mojom::Role::kGenericContainer ||
        child->data().role == ax::mojom::Role::kIgnored) {
      PopulateOrderedSetItems(ordered_set, child, items, node_is_radio_button);
    }
  }
}

Multiple integer overflows in the opj_tcd_init_tile function in tcd.c in OpenJPEG, as used in PDFium in Google Chrome before 53.0.2785.89 on Windows and OS X and before 53.0.2785.92 on Linux, allow remote attackers to cause a denial of service (heap-based buffer overflow) or possibly have unspecified other impact via crafted JPEG 2000 data.


void AXTree::PopulateOrderedSetItems(const AXNode* ordered_set,
                                     const AXNode* local_parent,
                                     std::vector<const AXNode*>& items,
                                     bool node_is_radio_button) const {
  if (!(ordered_set == local_parent)) {
    if (local_parent->data().role == ordered_set->data().role)
      return;
  }

   for (int i = 0; i < local_parent->child_count(); ++i) {
     const AXNode* child = local_parent->GetUnignoredChildAtIndex(i);

    // Invisible children should not be counted.
    // However, in the collapsed container case (e.g. a combobox), items can
    // still be chosen/navigated. However, the options in these collapsed
    // containers are historically marked invisible. Therefore, in that case,
    // count the invisible items. Only check 2 levels up, as combobox containers
    // are never higher.
    if (child->data().HasState(ax::mojom::State::kInvisible) &&
        !IsCollapsed(local_parent) && !IsCollapsed(local_parent->parent())) {
      continue;
    }

     if (node_is_radio_button &&
         child->data().role == ax::mojom::Role::kRadioButton)
      items.push_back(child);

    if (!node_is_radio_button && child->SetRoleMatchesItemRole(ordered_set))
      items.push_back(child);

    if (child->data().role == ax::mojom::Role::kGenericContainer ||
        child->data().role == ax::mojom::Role::kIgnored) {
      PopulateOrderedSetItems(ordered_set, child, items, node_is_radio_button);
    }
  }
}