summaryrefslogtreecommitdiffstats
path: root/WebKit/android/nav
diff options
context:
space:
mode:
authorCary Clark <cary@android.com>2010-09-30 15:14:40 -0400
committerCary Clark <cary@android.com>2010-09-30 15:14:40 -0400
commit8180f8161470f2d0d6080c64149cf25ed3b755a5 (patch)
tree387418df0beb238b165021ac40a1f76a175e34e0 /WebKit/android/nav
parent1441f89dceb65cbe25d23b1b90005e51d3ed28bd (diff)
downloadexternal_webkit-8180f8161470f2d0d6080c64149cf25ed3b755a5.zip
external_webkit-8180f8161470f2d0d6080c64149cf25ed3b755a5.tar.gz
external_webkit-8180f8161470f2d0d6080c64149cf25ed3b755a5.tar.bz2
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
Diffstat (limited to 'WebKit/android/nav')
-rw-r--r--WebKit/android/nav/CacheBuilder.cpp11
-rw-r--r--WebKit/android/nav/CacheBuilder.h2
2 files changed, 8 insertions, 5 deletions
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,