Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(264)

Unified Diff: third_party/WebKit/Source/core/page/FrameTree.cpp

Issue 1968213002: Try harder to make sure that blink::FrameTree::m_uniqueName is truly unique. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 4 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « third_party/WebKit/Source/core/page/FrameTree.h ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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
« no previous file with comments | « third_party/WebKit/Source/core/page/FrameTree.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698