From 8180f8161470f2d0d6080c64149cf25ed3b755a5 Mon Sep 17 00:00:00 2001 From: Cary Clark Date: Thu, 30 Sep 2010 15:14:40 -0400 Subject: Do not merge: fix array overwrite crasher If two nodes have the same coordinates, one is deleted. If either has focus, the focus needs to be transfered to the other, and the focus index recomputed, so the index won't point to the wrong node. If the two nodes are at the end of the list, the index may point off the end of the array, subsequently crashing on access. This is a possible security issue. Change-Id: I1ca934074637fbf68e40318fbc354e28c6b474ba http://b/3043268 --- WebKit/android/nav/CacheBuilder.cpp | 11 +++++++---- WebKit/android/nav/CacheBuilder.h | 2 +- 2 files changed, 8 insertions(+), 5 deletions(-) (limited to 'WebKit/android/nav') diff --git a/WebKit/android/nav/CacheBuilder.cpp b/WebKit/android/nav/CacheBuilder.cpp index 7ee2a16..214058c 100644 --- a/WebKit/android/nav/CacheBuilder.cpp +++ b/WebKit/android/nav/CacheBuilder.cpp @@ -960,7 +960,7 @@ void CacheBuilder::BuildFrame(Frame* root, Frame* frame, FocusTracker* last = &tracker.last(); int lastChildIndex = cachedFrame->size() - 1; while (node == last->mLastChild) { - if (CleanUpContainedNodes(cachedFrame, last, lastChildIndex)) + if (CleanUpContainedNodes(cachedRoot, cachedFrame, last, lastChildIndex)) cacheIndex--; tracker.removeLast(); lastChildIndex = last->mCachedNodeIndex; @@ -1344,14 +1344,14 @@ void CacheBuilder::BuildFrame(Frame* root, Frame* frame, while (tracker.size() > 1) { FocusTracker* last = &tracker.last(); int lastChildIndex = cachedFrame->size() - 1; - if (CleanUpContainedNodes(cachedFrame, last, lastChildIndex)) + if (CleanUpContainedNodes(cachedRoot, cachedFrame, last, lastChildIndex)) cacheIndex--; tracker.removeLast(); } } -bool CacheBuilder::CleanUpContainedNodes(CachedFrame* cachedFrame, - const FocusTracker* last, int lastChildIndex) +bool CacheBuilder::CleanUpContainedNodes(CachedRoot* cachedRoot, + CachedFrame* cachedFrame, const FocusTracker* last, int lastChildIndex) { // if outer is body, disable outer // or if there's more than one inner, disable outer @@ -1380,9 +1380,12 @@ bool CacheBuilder::CleanUpContainedNodes(CachedFrame* cachedFrame, HasTriggerEvent(lastNode) == false; if (onlyChildCached->parent() == lastCached) onlyChildCached->setParentIndex(lastCached->parentIndex()); + bool hasFocus = lastCached->isFocus() || onlyChildCached->isFocus(); if (outerIsMouseMoveOnly || onlyChild->isKeyboardFocusable(NULL)) *lastCached = *onlyChildCached; cachedFrame->removeLast(); + if (hasFocus) + cachedRoot->setCachedFocus(cachedFrame, cachedFrame->lastNode()); return true; } diff --git a/WebKit/android/nav/CacheBuilder.h b/WebKit/android/nav/CacheBuilder.h index 4ded58d..407d590 100644 --- a/WebKit/android/nav/CacheBuilder.h +++ b/WebKit/android/nav/CacheBuilder.h @@ -215,7 +215,7 @@ private: static bool NodeHasEventListeners(Node* node, AtomicString* eventTypes, int length); void BuildFrame(Frame* root, Frame* frame, CachedRoot* cachedRoot, CachedFrame* cachedFrame); - bool CleanUpContainedNodes(CachedFrame* cachedFrame, + bool CleanUpContainedNodes(CachedRoot* cachedRoot, CachedFrame* cachedFrame, const FocusTracker* last, int lastChildIndex); static bool ConstructTextRect(Text* textNode, InlineTextBox* textBox, int start, int relEnd, int x, int y, -- cgit v1.1