[prev in list] [next in list] [prev in thread] [next in thread] 

List:       kde-commits
Subject:    KDE/kdelibs/khtml
From:       Maks Orlovich <maksim () kde ! org>
Date:       2010-11-24 2:00:58
Message-ID: 20101124020058.69AD3AC8A4 () svn ! kde ! org
[Download RAW message or body]

SVN commit 1200140 by orlovich:

For stuff like cross-frame form submission, we want to use the HTML5 "can navigate" \
algorithm and not normal XSS checks. Makes the new mail reader on libero.it get \
further (Probably will need more adjustment, though)


 M  +1 -1      khtml_ext.cpp  
 M  +55 -9     khtml_part.cpp  
 M  +6 -0      khtmlpart_p.h  


--- trunk/KDE/kdelibs/khtml/khtml_ext.cpp #1200139:1200140
@@ -992,7 +992,7 @@
 KParts::BrowserHostExtension* KHTMLPartBrowserHostExtension::findFrameParent( \
                KParts::ReadOnlyPart
       *callingPart, const QString &frame )
 {
-    KHTMLPart *parentPart = m_part->findFrameParent(callingPart, frame);
+    KHTMLPart *parentPart = m_part->d->findFrameParent(callingPart, frame, 0, true \
/* navigation*/);  if (parentPart)
        return parentPart->browserHostExtension();
     return 0;
--- trunk/KDE/kdelibs/khtml/khtml_part.cpp #1200139:1200140
@@ -5166,36 +5166,46 @@
 KHTMLPart *
 KHTMLPart::findFrameParent( KParts::ReadOnlyPart *callingPart, const QString &f, \
khtml::ChildFrame **childFrame )  {
+    return d->findFrameParent(callingPart, f, childFrame, false);
+}
+
+KHTMLPart* KHTMLPartPrivate::findFrameParent(KParts::ReadOnlyPart* callingPart, 
+                                             const QString& f, khtml::ChildFrame \
**childFrame, bool checkForNavigation) +{
 #ifdef DEBUG_FINDFRAME
-  kDebug(6050) << this << "URL =" << url() << "name =" << objectName() << \
"findFrameParent(" << f << ")"; +    kDebug(6050) << q << "URL =" << q->url() << \
"name =" << q->objectName() << "findFrameParent(" << f << ")";  #endif
   // Check access
   KHTMLPart* const callingHtmlPart = dynamic_cast<KHTMLPart *>(callingPart);
 
-  if (!checkFrameAccess(callingHtmlPart))
+    if (!checkForNavigation && !q->checkFrameAccess(callingHtmlPart))
      return 0;
 
-  if (!childFrame && !parentPart() && (objectName() == f))
-     return this;
+    if (!childFrame && !q->parentPart() && (q->objectName() == f)) {
+        if (!checkForNavigation || callingHtmlPart->d->canNavigate(q))
+            return q;
+    }
 
-  FrameIt it = d->m_frames.find( f );
-  const FrameIt end = d->m_frames.end();
+    FrameIt it = m_frames.find( f );
+    const FrameIt end = m_frames.end();
   if ( it != end )
   {
 #ifdef DEBUG_FINDFRAME
      kDebug(6050) << "FOUND!";
 #endif
+        if (!checkForNavigation || \
callingHtmlPart->d->canNavigate((*it)->m_part.data())) {  if (childFrame)
         *childFrame = *it;
-     return this;
+            return q;
   }
+    }
 
-  it = d->m_frames.begin();
+    it = m_frames.begin();
   for (; it != end; ++it )
   {
     if ( KHTMLPart* p = qobject_cast<KHTMLPart*>((*it)->m_part.data()) )
     {
-      KHTMLPart* const frameParent = p->findFrameParent(callingPart, f, childFrame);
+            KHTMLPart* const frameParent = p->d->findFrameParent(callingPart, f, \
childFrame, checkForNavigation);  if (frameParent)
          return frameParent;
     }
@@ -5203,7 +5213,43 @@
   return 0;
 }
 
+KHTMLPart* KHTMLPartPrivate::top()
+{
+    KHTMLPart* t = q;
+    while (t->parentPart())
+        t = t->parentPart();
+    return t;
+}
 
+bool KHTMLPartPrivate::canNavigate(KParts::ReadOnlyPart* bCand)
+{
+    KHTMLPart* b = qobject_cast<KHTMLPart*>(bCand);
+    assert(b);
+
+    // HTML5 gives conditions for this (a) being able to navigate b
+    
+    // 1) Same domain
+    if (q->checkFrameAccess(b))
+        return true;
+        
+    // 2) A is nested, with B its top
+    if (q->parentPart() && top() == b)
+        return true;
+        
+    // 3) B is 'auxilary' -- window.open with opener, 
+    // and A can navigate B's opener
+    if (b->opener() && canNavigate(b->opener()))
+        return true;
+        
+    // 4) B is not top-level, but an ancestor of it has same origin as A
+    for (KHTMLPart* anc = b->parentPart(); anc; anc = anc->parentPart()) {
+        if (anc->checkFrameAccess(q))
+            return true;
+    }
+    
+    return false;
+}
+
 KHTMLPart *KHTMLPart::findFrame( const QString &f )
 {
   khtml::ChildFrame *childFrame;
--- trunk/KDE/kdelibs/khtml/khtmlpart_p.h #1200139:1200140
@@ -453,6 +453,12 @@
   void renameFrameForContainer(DOM::HTMLPartContainerElementImpl* cont,
                                const QString& newName);
 
+  KHTMLPart* findFrameParent(KParts::ReadOnlyPart* callingPart, const QString& f, 
+                             khtml::ChildFrame **childFrame, bool \
checkForNavigation); +                             
+  bool canNavigate(KParts::ReadOnlyPart* b);
+  KHTMLPart* top();
+
   // Check whether the frame is fully loaded.
   // The return value doesn't consider any pending redirections.
   // If the return value is true, however, pendingRedirections will


[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic