Index: third_party/WebKit/Source/core/page/FrameTree.cpp |
diff --git a/third_party/WebKit/Source/core/page/FrameTree.cpp b/third_party/WebKit/Source/core/page/FrameTree.cpp |
index c218e8b0f95a0bb7b3a1206b5158dc434674bcae..42101c999ad6364732c0ee3cfd3c1e371a642c67 100644 |
--- a/third_party/WebKit/Source/core/page/FrameTree.cpp |
+++ b/third_party/WebKit/Source/core/page/FrameTree.cpp |
@@ -27,6 +27,8 @@ |
#include "core/frame/RemoteFrame.h" |
#include "core/frame/RemoteFrameView.h" |
#include "core/page/Page.h" |
+#include "wtf/Assertions.h" |
+#include "wtf/CryptographicallyRandomNumber.h" |
#include "wtf/Vector.h" |
#include "wtf/text/CString.h" |
#include "wtf/text/StringBuilder.h" |
@@ -54,15 +56,22 @@ FrameTree::~FrameTree() |
void FrameTree::setName(const AtomicString& name, const AtomicString& fallbackName) |
{ |
m_name = name; |
- if (!parent()) { |
- m_uniqueName = name; |
- return; |
- } |
- // Remove our old frame name so it's not considered in calculateUniqueNameForChildFrame. |
+ // Remove our old frame name so it's not considered in calculateUniqueNameForChildFrame |
+ // and ensureUniquenessOfUniqueName calls below. |
m_uniqueName = AtomicString(); |
- m_uniqueName = parent()->tree().calculateUniqueNameForChildFrame(true, name, fallbackName); |
+ // Calculate a new unique name based on inputs. |
+ if (parent()) { |
+ setUniqueName( |
+ parent()->tree().calculateUniqueNameForChildFrame(true, name, fallbackName)); |
+ } else if (name.isEmpty()) { |
+ // Only main frame can have an empty unique name, so for main frames |
+ // emptiness guarantees uniquness. |
+ setUniqueName(name); |
+ } else { |
+ setUniqueName(ensureUniquenessOfUniqueName(name)); |
+ } |
} |
void FrameTree::setPrecalculatedName(const AtomicString& name, const AtomicString& uniqueName) |
@@ -74,6 +83,12 @@ void FrameTree::setPrecalculatedName(const AtomicString& name, const AtomicStrin |
} |
m_name = name; |
+ |
+ // TODO(lukasza): We would like to assert uniqueness below (i.e. by calling |
+ // setUniqueName), but |
+ // 1) uniqueness is currently violated by provisional/old frame pairs. |
+ // 2) there is an unresolved race between 2 OOPIFs, that can result in a |
+ // non-unique |uniqueName| - see https://crbug.com/558680#c14. |
m_uniqueName = uniqueName; |
} |
@@ -125,6 +140,12 @@ Frame* FrameTree::lastChild() const |
bool FrameTree::uniqueNameExists(const AtomicString& name) const |
{ |
+ // Before recalculating or checking unique name, we set m_uniqueName |
+ // to an empty string (so the soon-to-be-removed name does not count |
+ // as a collision). This means that uniqueNameExists would return |
+ // false positives when called with an empty |name|. |
+ ASSERT(!name.isEmpty()); |
+ |
for (Frame* frame = top(); frame; frame = frame->tree().traverseNext()) { |
if (frame->tree().uniqueName() == name) |
return true; |
@@ -183,7 +204,32 @@ AtomicString FrameTree::calculateUniqueNameForChildFrame( |
uniqueName.appendNumber(childCount() - (existingChildFrame ? 1 : 0)); |
uniqueName.appendLiteral("-->-->"); |
- return uniqueName.toAtomicString(); |
+ return ensureUniquenessOfUniqueName(uniqueName.toAtomicString()); |
+} |
+ |
+AtomicString FrameTree::ensureUniquenessOfUniqueName(const AtomicString& potentiallyUniqueName) const |
+{ |
+ if (!uniqueNameExists(potentiallyUniqueName)) |
+ return potentiallyUniqueName; |
+ |
+ StringBuilder uniqueNameBuilder; |
+ uniqueNameBuilder.append(potentiallyUniqueName); |
+ do { |
+ uniqueNameBuilder.append('-'); |
+ uniqueNameBuilder.appendNumber(cryptographicallyRandomNumber()); |
+ } while (uniqueNameExists(uniqueNameBuilder.toAtomicString())); |
dcheng
2016/05/12 05:31:18
So according to the spec, a valid name cannot star
|
+ return uniqueNameBuilder.toAtomicString(); |
+} |
+ |
+void FrameTree::setUniqueName(const AtomicString& uniqueName) |
+{ |
+ if (parent()) { |
+ ASSERT(!uniqueName.isEmpty() && !uniqueNameExists(uniqueName)); |
+ } else { |
+ ASSERT(uniqueName.isEmpty() || !uniqueNameExists(uniqueName)); |
+ } |
+ |
+ m_uniqueName = uniqueName; |
} |
Frame* FrameTree::scopedChild(unsigned index) const |