[SECURITY][PATCH] kdelibs, kdebase

Michal Kochanowicz michal w michal.waw.pl
Pon, 9 Sie 2004, 22:55:53 CEST


On Sat, Aug 07, 2004 at 08:56:10AM +0200, Michal Kochanowicz wrote:
> Załączone łaty naprawiają kilka błędów w konquerorze. Oficjalna
> publikacja przewidziana jest 11.08 (*htmlframes*) i 20.08 (*cookiejar* -
> opóźnienie ze względu na występowanie analogicznego błędu w innych
> przeglądarkach).
No i okazało się że patche kdelibs-htmlframes* wprowadzały regresję. W
załączniku poprawne łatki. Łatki dla kdebase pozostają te same.

BTW: czy naprawdę PLD upadło już tak bardzo, że nawet łatki security
wszyscy mają w dupie?
-- 
--= Michal Kochanowicz =--==--==BOFH==--==--= michal w michal.waw.pl =--
--= finger me for PGP public key or visit http://michal.waw.pl/PGP =--
--==--==--==--==--==-- Vodka. Connecting people.--==--==--==--==--==--
A chodzenie po górach SSIE!!!
-------------- następna część ---------
Index: khtml/khtml_ext.cpp
===================================================================
RCS file: /home/kde/kdelibs/khtml/khtml_ext.cpp,v
retrieving revision 1.55.2.3
diff -u -p -r1.55.2.3 khtml_ext.cpp
--- khtml/khtml_ext.cpp	29 Jun 2003 21:43:00 -0000	1.55.2.3
+++ khtml/khtml_ext.cpp	3 Aug 2004 16:15:15 -0000
@@ -546,6 +546,19 @@ bool KHTMLPartBrowserHostExtension::open
   return m_part->openURLInFrame( url, urlArgs );
 }
 
+void KHTMLPartBrowserHostExtension::virtual_hook( int id, void *data )
+{ 
+  if (id == VIRTUAL_FIND_FRAME_PARENT)
+  {
+    FindFrameParentParams *param = static_cast<FindFrameParentParams*>(data);
+    KHTMLPart *parentPart = m_part->findFrameParent(param->callingPart, param->frame);
+    if (parentPart)
+       param->parent = parentPart->browserHostExtension();
+    return;
+  }
+  BrowserHostExtension::virtual_hook( id, data );
+}
+
 KHTMLZoomFactorAction::KHTMLZoomFactorAction( KHTMLPart *part, bool direction, const QString &text, const QString &icon, const QObject *receiver, const char *slot, QObject *parent, const char *name )
     : KAction( text, icon, 0, receiver, slot, parent, name )
 {
Index: khtml/khtml_ext.h
===================================================================
RCS file: /home/kde/kdelibs/khtml/khtml_ext.h,v
retrieving revision 1.18.4.1
diff -u -p -r1.18.4.1 khtml_ext.h
--- khtml/khtml_ext.h	18 May 2003 12:34:35 -0000	1.18.4.1
+++ khtml/khtml_ext.h	3 Aug 2004 16:15:15 -0000
@@ -66,6 +66,9 @@ public:
   virtual const QPtrList<KParts::ReadOnlyPart> frames() const;
 
   virtual bool openURLInFrame( const KURL &url, const KParts::URLArgs &urlArgs );
+
+protected:
+  virtual void virtual_hook( int id, void* data );
 private:
   KHTMLPart *m_part;
 };
Index: khtml/khtml_part.cpp
===================================================================
RCS file: /home/kde/kdelibs/khtml/khtml_part.cpp,v
retrieving revision 1.770.2.28
diff -u -p -r1.770.2.28 khtml_part.cpp
--- khtml/khtml_part.cpp	10 Jul 2003 12:13:14 -0000	1.770.2.28
+++ khtml/khtml_part.cpp	3 Aug 2004 16:15:18 -0000
@@ -571,12 +571,16 @@ DOM::Document KHTMLPart::document() cons
     return d->m_doc;
 }
 
-
 KParts::BrowserExtension *KHTMLPart::browserExtension() const
 {
   return d->m_extension;
 }
 
+KParts::BrowserHostExtension *KHTMLPart::browserHostExtension() const
+{
+  return d->m_hostExtension;
+}
+
 KHTMLView *KHTMLPart::view() const
 {
   return d->m_view;
@@ -797,7 +801,7 @@ void KHTMLPart::slotShowDocument( const 
     }
     else if ( frameName != QString::fromLatin1( "_self" ) )
     {
-      khtml::ChildFrame *_frame = recursiveFrameRequest( url, args );
+      khtml::ChildFrame *_frame = recursiveFrameRequest( this, url, args );
 
       if ( !_frame )
       {
@@ -2675,7 +2679,7 @@ void KHTMLPart::urlSelected( const QStri
   if ( hasTarget )
   {
     // unknown frame names should open in a new window.
-    khtml::ChildFrame *frame = recursiveFrameRequest( cURL, args, false );
+    khtml::ChildFrame *frame = recursiveFrameRequest( this, cURL, args, false );
     if ( frame )
     {
       args.metaData()["referrer"] = d->m_referrer;
@@ -3584,6 +3588,7 @@ void KHTMLPart::slotChildDocCreated()
 void KHTMLPart::slotChildURLRequest( const KURL &url, const KParts::URLArgs &args )
 {
   khtml::ChildFrame *child = frame( sender()->parent() );
+  KHTMLPart *callingHtmlPart = const_cast<KHTMLPart *>(dynamic_cast<const KHTMLPart *>(sender()->parent()));
 
   // TODO: handle child target correctly! currently the script are always executed fur the parent
   QString urlStr = url.url();
@@ -3616,7 +3621,7 @@ void KHTMLPart::slotChildURLRequest( con
     }
     else if ( frameName != QString::fromLatin1( "_self" ) )
     {
-      khtml::ChildFrame *_frame = recursiveFrameRequest( url, args );
+      khtml::ChildFrame *_frame = recursiveFrameRequest( callingHtmlPart, url, args );
 
       if ( !_frame )
       {
@@ -3654,46 +3659,92 @@ khtml::ChildFrame *KHTMLPart::frame( con
     return 0L;
 }
 
-//#define DEBUG_FINDFRAME
+//#define DEBUG_FINDFRAME
 
-KHTMLPart *KHTMLPart::findFrame( const QString &f )
+bool KHTMLPart::checkFrameAccess(KHTMLPart *callingHtmlPart)
 {
+  if (callingHtmlPart == this)
+    return true; // trivial
+
+  if (htmlDocument().isNull()) {
 #ifdef DEBUG_FINDFRAME
-  kdDebug(6050) << "KHTMLPart::findFrame '" << f << "'" << endl;
-  FrameIt it2 = d->m_frames.begin();
-  FrameIt end = d->m_frames.end();
-  for (; it2 != end; ++it2 )
-      kdDebug(6050) << "  - having frame '" << (*it2).m_name << "'" << endl;
+    kdDebug(6050) << "KHTMLPart::checkFrameAccess: Empty part " << this << " URL = " << m_url.prettyURL() << endl;
 #endif
-  // ### http://www.w3.org/TR/html4/appendix/notes.html#notes-frames
-  ConstFrameIt it = d->m_frames.find( f );
-  if ( it == d->m_frames.end() )
-  {
+    return false; // we are empty?
+  }
+
+  // now compare the domains
+  if (callingHtmlPart && !callingHtmlPart->htmlDocument().isNull() &&
+      !htmlDocument().isNull())  {
+    DOM::DOMString actDomain = callingHtmlPart->htmlDocument().domain();
+    DOM::DOMString destDomain = htmlDocument().domain();
+
 #ifdef DEBUG_FINDFRAME
-    kdDebug(6050) << "KHTMLPart::findFrame frame " << f << " not found" << endl;
+    kdDebug(6050) << "KHTMLPart::checkFrameAccess: actDomain = '" << actDomain.string() << "' destDomain = '" << destDomain.string() << "'" << endl;
 #endif
-    return 0L;
+
+    if (actDomain == destDomain)
+      return true;
   }
-  else {
-    KParts::ReadOnlyPart *p = (*it).m_part;
-    if ( p && p->inherits( "KHTMLPart" ))
-    {
 #ifdef DEBUG_FINDFRAME
-      kdDebug(6050) << "KHTMLPart::findFrame frame " << f << " is a KHTMLPart, ok" << endl;
+  else
+  {
+    kdDebug(6050) << "KHTMLPart::checkFrameAccess: Unknown part/domain " << callingHtmlPart << " tries to access part " << this << endl;
+  }
 #endif
-      return (KHTMLPart*)p;
-    }
-    else
-    {
+  return false;
+}
+
+KHTMLPart *
+KHTMLPart::findFrameParent( KParts::ReadOnlyPart *callingPart, const QString &f, khtml::ChildFrame **childFrame )
+{
 #ifdef DEBUG_FINDFRAME
-      if (p)
-        kdWarning() << "KHTMLPart::findFrame frame " << f << " found but isn't a KHTMLPart ! " << p->className() << endl;
-      else
-        kdWarning() << "KHTMLPart::findFrame frame " << f << " found but m_part=0L" << endl;
+  kdDebug(6050) << "KHTMLPart::findFrameParent: this = " << this << " URL = " << m_url.prettyURL() << " findFrameParent( " << f << " )" << endl;
 #endif
-      return 0L;
+  // Check access
+  KHTMLPart *callingHtmlPart = dynamic_cast<KHTMLPart *>(callingPart);
+  
+  if (!checkFrameAccess(callingHtmlPart))
+     return 0;
+
+  FrameIt it = d->m_frames.find( f );
+  FrameIt end = d->m_frames.end();
+  if ( it != end )
+  {
+#ifdef DEBUG_FINDFRAME
+     kdDebug(6050) << "KHTMLPart::findFrameParent: FOUND!" << endl;
+#endif
+     if (childFrame)
+        *childFrame = &(*it);
+     return this;
+  }
+     
+  it = d->m_frames.begin();
+  for (; it != end; ++it )
+  {
+    KParts::ReadOnlyPart *p = (*it).m_part;
+    if ( p && p->inherits( "KHTMLPart" ))
+    {
+      KHTMLPart *frameParent = static_cast<KHTMLPart*>(p)->findFrameParent(callingPart, f, childFrame);
+      if (frameParent)
+         return frameParent;
     }
   }
+  return 0;
+}
+
+
+KHTMLPart *KHTMLPart::findFrame( const QString &f )
+{
+  khtml::ChildFrame *childFrame;
+  KHTMLPart *parentFrame = findFrameParent(this, f, &childFrame);
+  if (parentFrame)
+  {
+     KParts::ReadOnlyPart *p = childFrame->m_part;
+     if ( p && p->inherits( "KHTMLPart" ))
+        return static_cast<KHTMLPart *>(p);
+  }
+  return 0;
 }
 
 KParts::ReadOnlyPart *KHTMLPart::currentFrame() const
@@ -3731,37 +3782,29 @@ KHTMLPart *KHTMLPart::parentPart()
   return (KHTMLPart *)parent();
 }
 
-khtml::ChildFrame *KHTMLPart::recursiveFrameRequest( const KURL &url, const KParts::URLArgs &args,
-                                                     bool callParent )
+khtml::ChildFrame *KHTMLPart::recursiveFrameRequest( KHTMLPart *callingHtmlPart, const KURL &url, 
+                                                     const KParts::URLArgs &args, bool callParent )
 {
-  FrameIt it = d->m_frames.find( args.frameName );
-
-  if ( it != d->m_frames.end() )
-    return &(*it);
-
-  it = d->m_frames.begin();
-  FrameIt end = d->m_frames.end();
-  for (; it != end; ++it )
-    if ( (*it).m_part && (*it).m_part->inherits( "KHTMLPart" ) )
-    {
-      KHTMLPart *childPart = (KHTMLPart *)(KParts::ReadOnlyPart *)(*it).m_part;
-
-      khtml::ChildFrame *res = childPart->recursiveFrameRequest( url, args, false );
-      if ( !res )
-        continue;
-
-      childPart->requestObject( res, url, args );
-      return 0L;
-    }
+#ifdef DEBUG_FINDFRAME
+  kdDebug( 6050 ) << "KHTMLPart::recursiveFrameRequest this = " << this << ", frame = " << args.frameName << ", url = " << url.prettyURL() << endl;
+#endif  
+  khtml::ChildFrame *childFrame;
+  KHTMLPart *childPart = findFrameParent(callingHtmlPart, args.frameName, &childFrame);
+  if (childPart)
+  {
+     if (childPart == this)
+        return childFrame;
+     
+     childPart->requestObject( childFrame, url, args );
+     return 0;
+  }
 
   if ( parentPart() && callParent )
   {
-    khtml::ChildFrame *res = parentPart()->recursiveFrameRequest( url, args );
-
-    if ( res )
-      parentPart()->requestObject( res, url, args );
+     khtml::ChildFrame *res = parentPart()->recursiveFrameRequest( callingHtmlPart, url, args, callParent );
 
-    return 0L;
+     if ( res )
+       parentPart()->requestObject( res, url, args );
   }
 
   return 0L;
@@ -3769,7 +3812,7 @@ khtml::ChildFrame *KHTMLPart::recursiveF
 
 void KHTMLPart::saveState( QDataStream &stream )
 {
-  kdDebug( 6050 ) << "KHTMLPart::saveState saving URL " << m_url.url() << endl;
+  kdDebug( 6050 ) << "KHTMLPart::saveState this = " << this << " saving URL " << m_url.url() << endl;
 
   stream << m_url << (Q_INT32)d->m_view->contentsX() << (Q_INT32)d->m_view->contentsY()
          << (Q_INT32) d->m_view->contentsWidth() << (Q_INT32) d->m_view->contentsHeight() << (Q_INT32) d->m_view->marginWidth() << (Q_INT32) d->m_view->marginHeight();
Index: khtml/khtml_part.h
===================================================================
RCS file: /home/kde/kdelibs/khtml/khtml_part.h,v
retrieving revision 1.197.2.6
diff -u -p -r1.197.2.6 khtml_part.h
--- khtml/khtml_part.h	10 Jul 2003 12:13:14 -0000	1.197.2.6
+++ khtml/khtml_part.h	3 Aug 2004 16:15:18 -0000
@@ -245,6 +245,8 @@ public:
    */
   KParts::BrowserExtension *browserExtension() const;
   KParts::LiveConnectExtension *liveConnectExtension( const khtml::RenderPart *) const;
+  KParts::BrowserHostExtension *browserHostExtension() const;
+  
   /**
    * Returns a pointer to the HTML document's view.
    */
@@ -653,6 +655,16 @@ public:
   KHTMLPart *findFrame( const QString &f );
 
   /**
+   * @internal
+   * Recursively finds the part containing the frame with name @p f 
+   * and checks if it is accessible by @p callingPart
+   * Returns 0L if no suitable frame can't be found.
+   * Returns parent part if a suitable frame was found and
+   * frame info in @p *childFrame
+   */
+  KHTMLPart *findFrameParent( KParts::ReadOnlyPart *callingPart, const QString &f, khtml::ChildFrame **childFrame=0 );
+
+  /**
    * Return the current frame (the one that has focus)
    * Not necessarily a direct child of ours, framesets can be nested.
    * Returns "this" if this part isn't a frameset.
@@ -1050,6 +1062,12 @@ private:
    * @internal
    */
   bool openURLInFrame( const KURL &url, const KParts::URLArgs &urlArgs );
+  
+  /**
+   * @internal
+   * Returns whether callingHtmlPart may access this part
+   */
+  bool checkFrameAccess(KHTMLPart *callingHtmlPart);
 
   void startAutoScroll();
   void stopAutoScroll();
@@ -1103,7 +1121,7 @@ private:
   DOM::DocumentImpl *xmlDocImpl() const;
   khtml::ChildFrame *frame( const QObject *obj );
 
-  khtml::ChildFrame *recursiveFrameRequest( const KURL &url, const KParts::URLArgs &args, bool callParent = true );
+  khtml::ChildFrame *recursiveFrameRequest( KHTMLPart *callingHtmlPart, const KURL &url, const KParts::URLArgs &args, bool callParent = true );
 
   bool checkLinkSecurity(const KURL &linkURL,const QString &message = QString::null, const QString &button = QString::null);
   QVariant executeScript(QString filename, int baseLine, const DOM::Node &n, const QString &script);
Index: kparts/browserextension.cpp
===================================================================
RCS file: /home/kde/kdelibs/kparts/browserextension.cpp,v
retrieving revision 1.40.2.3
diff -u -p -r1.40.2.3 browserextension.cpp
--- kparts/browserextension.cpp	15 Jul 2003 00:40:51 -0000	1.40.2.3
+++ kparts/browserextension.cpp	3 Aug 2004 16:15:19 -0000
@@ -599,6 +599,17 @@ BrowserHostExtension *BrowserHostExtensi
 void BrowserExtension::virtual_hook( int, void* )
 { /*BASE::virtual_hook( id, data );*/ }
 
+BrowserHostExtension *
+BrowserHostExtension::findFrameParent(KParts::ReadOnlyPart *callingPart, const QString &frame)
+{
+    FindFrameParentParams param;
+    param.parent = 0;
+    param.callingPart = callingPart;
+    param.frame = frame;
+    virtual_hook(VIRTUAL_FIND_FRAME_PARENT, &param);
+    return param.parent;
+}
+
 void BrowserHostExtension::virtual_hook( int, void* )
 { /*BASE::virtual_hook( id, data );*/ }
 
Index: kparts/browserextension.h
===================================================================
RCS file: /home/kde/kdelibs/kparts/browserextension.h,v
retrieving revision 1.94.2.2
diff -u -p -r1.94.2.2 browserextension.h
--- kparts/browserextension.h	18 May 2003 12:36:17 -0000	1.94.2.2
+++ kparts/browserextension.h	3 Aug 2004 16:15:19 -0000
@@ -610,10 +610,16 @@ public:
    *
    * Note that this method does not query the child objects recursively.
    */
-
   virtual const QPtrList<KParts::ReadOnlyPart> frames() const;
 
   /**
+   * @internal
+   * Returns the part that contains @p frame and that may be accessed
+   * by @p callingPart
+   */
+  BrowserHostExtension *findFrameParent(KParts::ReadOnlyPart *callingPart, const QString &frame);
+
+  /**
    * Opens the given url in a hosted child frame. The frame name is specified in the
    * frameName variable in the urlArgs argument structure (see @ref KParts::URLArgs ) .
    */
@@ -626,6 +632,19 @@ public:
   static BrowserHostExtension *childObject( QObject *obj );
 
 protected:
+  /** This 'enum' along with the structure below is NOT part of the public API.
+   * It's going to disappear in KDE 4.0 and is likely to change inbetween.
+   *
+   * @internal
+   */
+  enum { VIRTUAL_FIND_FRAME_PARENT = 0x10 };
+  struct FindFrameParentParams
+  {
+      BrowserHostExtension *parent;
+      KParts::ReadOnlyPart *callingPart;
+      QString frame;
+  };
+                                                    
   virtual void virtual_hook( int id, void* data );
 private:
   class BrowserHostExtensionPrivate;
-------------- następna część ---------
Index: khtml/khtml_ext.cpp
===================================================================
RCS file: /home/kde/kdelibs/khtml/khtml_ext.cpp,v
retrieving revision 1.85.2.2
diff -u -p -r1.85.2.2 khtml_ext.cpp
--- khtml/khtml_ext.cpp	24 Apr 2004 08:20:46 -0000	1.85.2.2
+++ khtml/khtml_ext.cpp	3 Aug 2004 14:36:43 -0000
@@ -646,6 +646,19 @@ bool KHTMLPartBrowserHostExtension::open
   return m_part->openURLInFrame( url, urlArgs );
 }
 
+void KHTMLPartBrowserHostExtension::virtual_hook( int id, void *data )
+{ 
+  if (id == VIRTUAL_FIND_FRAME_PARENT)
+  {
+    FindFrameParentParams *param = static_cast<FindFrameParentParams*>(data);
+    KHTMLPart *parentPart = m_part->findFrameParent(param->callingPart, param->frame);
+    if (parentPart)
+       param->parent = parentPart->browserHostExtension();
+    return;
+  }
+  BrowserHostExtension::virtual_hook( id, data );
+}
+
 // BCI: remove in KDE 4
 KHTMLZoomFactorAction::KHTMLZoomFactorAction( KHTMLPart *part, bool direction, const QString &text, const QString &icon, const QObject *receiver, const char *slot, QObject *parent, const char *name )
     : KAction( text, icon, 0, receiver, slot, parent, name )
Index: khtml/khtml_ext.h
===================================================================
RCS file: /home/kde/kdelibs/khtml/khtml_ext.h,v
retrieving revision 1.26.2.1
diff -u -p -r1.26.2.1 khtml_ext.h
--- khtml/khtml_ext.h	29 Feb 2004 15:27:43 -0000	1.26.2.1
+++ khtml/khtml_ext.h	3 Aug 2004 14:36:43 -0000
@@ -98,6 +98,9 @@ public:
   virtual const QPtrList<KParts::ReadOnlyPart> frames() const;
 
   virtual bool openURLInFrame( const KURL &url, const KParts::URLArgs &urlArgs );
+
+protected:
+  virtual void virtual_hook( int id, void* data );
 private:
   KHTMLPart *m_part;
 };
Index: khtml/khtml_part.cpp
===================================================================
RCS file: /home/kde/kdelibs/khtml/khtml_part.cpp,v
retrieving revision 1.959.2.20
diff -u -p -r1.959.2.20 khtml_part.cpp
--- khtml/khtml_part.cpp	29 Jun 2004 09:08:16 -0000	1.959.2.20
+++ khtml/khtml_part.cpp	3 Aug 2004 14:36:46 -0000
@@ -757,12 +757,16 @@ DOM::Document KHTMLPart::document() cons
     return d->m_doc;
 }
 
-
 KParts::BrowserExtension *KHTMLPart::browserExtension() const
 {
   return d->m_extension;
 }
 
+KParts::BrowserHostExtension *KHTMLPart::browserHostExtension() const
+{
+  return d->m_hostExtension;
+}
+
 KHTMLView *KHTMLPart::view() const
 {
   return d->m_view;
@@ -880,29 +884,18 @@ QVariant KHTMLPart::crossFrameExecuteScr
     // we always allow these
   }
   else {
-    while (destpart->parentPart())
-      destpart = destpart->parentPart();
-    destpart = destpart->findFrame(target);
-
+    destpart = findFrame(target);
     if (!destpart)
-      destpart = this; // ### doesn't make sense, does it?
+       destpart = this;
   }
 
   // easy way out?
   if (destpart == this)
     return executeScript(DOM::Node(), script);
 
-
   // now compare the domains
-  if (!destpart->htmlDocument().isNull() &&
-      !htmlDocument().isNull())  {
-    DOM::DOMString actDomain = htmlDocument().domain();
-    DOM::DOMString destDomain = destpart->htmlDocument().domain();
-
-    if (actDomain == destDomain)
-      return destpart->executeScript(DOM::Node(), script);
-  }
-
+  if (destpart->checkFrameAccess(this))
+    return destpart->executeScript(DOM::Node(), script);
 
   // eww, something went wrong. better execute it in our frame
   return executeScript(DOM::Node(), script);
@@ -3358,7 +3351,7 @@ void KHTMLPart::urlSelected( const QStri
   if ( hasTarget )
   {
     // unknown frame names should open in a new window.
-    khtml::ChildFrame *frame = recursiveFrameRequest( cURL, args, false );
+    khtml::ChildFrame *frame = recursiveFrameRequest( this, cURL, args, false );
     if ( frame )
     {
       args.metaData()["referrer"] = d->m_referrer;
@@ -4364,6 +4357,7 @@ void KHTMLPart::slotChildDocCreated()
 void KHTMLPart::slotChildURLRequest( const KURL &url, const KParts::URLArgs &args )
 {
   khtml::ChildFrame *child = frame( sender()->parent() );
+  KHTMLPart *callingHtmlPart = const_cast<KHTMLPart *>(dynamic_cast<const KHTMLPart *>(sender()->parent()));
 
   // TODO: handle child target correctly! currently the script are always executed fur the parent
   QString urlStr = url.url();
@@ -4395,7 +4389,7 @@ void KHTMLPart::slotChildURLRequest( con
     }
     else if ( frameName != QString::fromLatin1( "_self" ) )
     {
-      khtml::ChildFrame *_frame = recursiveFrameRequest( url, args );
+      khtml::ChildFrame *_frame = recursiveFrameRequest( callingHtmlPart, url, args );
 
       if ( !_frame )
       {
@@ -4437,46 +4431,92 @@ khtml::ChildFrame *KHTMLPart::frame( con
     return 0L;
 }
 
-//#define DEBUG_FINDFRAME
+//#define DEBUG_FINDFRAME
 
-KHTMLPart *KHTMLPart::findFrame( const QString &f )
+bool KHTMLPart::checkFrameAccess(KHTMLPart *callingHtmlPart)
 {
+  if (callingHtmlPart == this)
+    return true; // trivial
+
+  if (htmlDocument().isNull()) {
 #ifdef DEBUG_FINDFRAME
-  kdDebug(6050) << "KHTMLPart::findFrame '" << f << "'" << endl;
-  FrameIt it2 = d->m_frames.begin();
-  FrameIt end = d->m_frames.end();
-  for (; it2 != end; ++it2 )
-      kdDebug(6050) << "  - having frame '" << (*it2).m_name << "'" << endl;
+    kdDebug(6050) << "KHTMLPart::checkFrameAccess: Empty part " << this << " URL = " << m_url << endl;
 #endif
-  // ### http://www.w3.org/TR/html4/appendix/notes.html#notes-frames
-  ConstFrameIt it = d->m_frames.find( f );
-  if ( it == d->m_frames.end() )
-  {
+    return false; // we are empty?
+  }
+
+  // now compare the domains
+  if (callingHtmlPart && !callingHtmlPart->htmlDocument().isNull() &&
+      !htmlDocument().isNull())  {
+    DOM::DOMString actDomain = callingHtmlPart->htmlDocument().domain();
+    DOM::DOMString destDomain = htmlDocument().domain();
+
 #ifdef DEBUG_FINDFRAME
-    kdDebug(6050) << "KHTMLPart::findFrame frame " << f << " not found" << endl;
+    kdDebug(6050) << "KHTMLPart::checkFrameAccess: actDomain = '" << actDomain.string() << "' destDomain = '" << destDomain.string() << "'" << endl;
 #endif
-    return 0L;
+
+    if (actDomain == destDomain)
+      return true;
   }
-  else {
-    KParts::ReadOnlyPart *p = (*it).m_part;
-    if ( p && p->inherits( "KHTMLPart" ))
-    {
 #ifdef DEBUG_FINDFRAME
-      kdDebug(6050) << "KHTMLPart::findFrame frame " << f << " is a KHTMLPart, ok" << endl;
+  else
+  {
+    kdDebug(6050) << "KHTMLPart::checkFrameAccess: Unknown part/domain " << callingHtmlPart << " tries to access part " << this << endl;
+  }
 #endif
-      return (KHTMLPart*)p;
-    }
-    else
-    {
+  return false;
+}
+
+KHTMLPart *
+KHTMLPart::findFrameParent( KParts::ReadOnlyPart *callingPart, const QString &f, khtml::ChildFrame **childFrame )
+{
 #ifdef DEBUG_FINDFRAME
-      if (p)
-        kdWarning() << "KHTMLPart::findFrame frame " << f << " found but isn't a KHTMLPart ! " << p->className() << endl;
-      else
-        kdWarning() << "KHTMLPart::findFrame frame " << f << " found but m_part=0L" << endl;
+  kdDebug(6050) << "KHTMLPart::findFrameParent: this = " << this << " URL = " << m_url << " findFrameParent( " << f << " )" << endl;
+#endif
+  // Check access
+  KHTMLPart *callingHtmlPart = dynamic_cast<KHTMLPart *>(callingPart);
+  
+  if (!checkFrameAccess(callingHtmlPart))
+     return 0;
+
+  FrameIt it = d->m_frames.find( f );
+  FrameIt end = d->m_frames.end();
+  if ( it != end )
+  {
+#ifdef DEBUG_FINDFRAME
+     kdDebug(6050) << "KHTMLPart::findFrameParent: FOUND!" << endl;
 #endif
-      return 0L;
+     if (childFrame)
+        *childFrame = &(*it);
+     return this;
+  }
+     
+  it = d->m_frames.begin();
+  for (; it != end; ++it )
+  {
+    KParts::ReadOnlyPart *p = (*it).m_part;
+    if ( p && p->inherits( "KHTMLPart" ))
+    {
+      KHTMLPart *frameParent = static_cast<KHTMLPart*>(p)->findFrameParent(callingPart, f, childFrame);
+      if (frameParent)
+         return frameParent;
     }
   }
+  return 0;
+}
+
+
+KHTMLPart *KHTMLPart::findFrame( const QString &f )
+{
+  khtml::ChildFrame *childFrame;
+  KHTMLPart *parentFrame = findFrameParent(this, f, &childFrame);
+  if (parentFrame)
+  {
+     KParts::ReadOnlyPart *p = childFrame->m_part;
+     if ( p && p->inherits( "KHTMLPart" ))
+        return static_cast<KHTMLPart *>(p);
+  }
+  return 0;
 }
 
 KParts::ReadOnlyPart *KHTMLPart::currentFrame() const
@@ -4514,37 +4554,29 @@ KHTMLPart *KHTMLPart::parentPart()
   return (KHTMLPart *)parent();
 }
 
-khtml::ChildFrame *KHTMLPart::recursiveFrameRequest( const KURL &url, const KParts::URLArgs &args,
-                                                     bool callParent )
+khtml::ChildFrame *KHTMLPart::recursiveFrameRequest( KHTMLPart *callingHtmlPart, const KURL &url, 
+                                                     const KParts::URLArgs &args, bool callParent )
 {
-  FrameIt it = d->m_frames.find( args.frameName );
-
-  if ( it != d->m_frames.end() )
-    return &(*it);
-
-  it = d->m_frames.begin();
-  FrameIt end = d->m_frames.end();
-  for (; it != end; ++it )
-    if ( (*it).m_part && (*it).m_part->inherits( "KHTMLPart" ) )
-    {
-      KHTMLPart *childPart = (KHTMLPart *)(KParts::ReadOnlyPart *)(*it).m_part;
-
-      khtml::ChildFrame *res = childPart->recursiveFrameRequest( url, args, false );
-      if ( !res )
-        continue;
-
-      childPart->requestObject( res, url, args );
-      return 0L;
-    }
+#ifdef DEBUG_FINDFRAME
+  kdDebug( 6050 ) << "KHTMLPart::recursiveFrameRequest this = " << this << ", frame = " << args.frameName << ", url = " << url << endl;
+#endif  
+  khtml::ChildFrame *childFrame;
+  KHTMLPart *childPart = findFrameParent(callingHtmlPart, args.frameName, &childFrame);
+  if (childPart)
+  {
+     if (childPart == this)
+        return childFrame;
+     
+     childPart->requestObject( childFrame, url, args );
+     return 0;
+  }
 
   if ( parentPart() && callParent )
   {
-    khtml::ChildFrame *res = parentPart()->recursiveFrameRequest( url, args );
+     khtml::ChildFrame *res = parentPart()->recursiveFrameRequest( callingHtmlPart, url, args, callParent );
 
-    if ( res )
-      parentPart()->requestObject( res, url, args );
-
-    return 0L;
+     if ( res )
+       parentPart()->requestObject( res, url, args );
   }
 
   return 0L;
@@ -4552,7 +4584,7 @@ khtml::ChildFrame *KHTMLPart::recursiveF
 
 void KHTMLPart::saveState( QDataStream &stream )
 {
-  kdDebug( 6050 ) << "KHTMLPart::saveState saving URL " << m_url.url() << endl;
+  kdDebug( 6050 ) << "KHTMLPart::saveState this = " << this << " saving URL " << m_url.url() << endl;
 
   stream << m_url << (Q_INT32)d->m_view->contentsX() << (Q_INT32)d->m_view->contentsY()
          << (Q_INT32) d->m_view->contentsWidth() << (Q_INT32) d->m_view->contentsHeight() << (Q_INT32) d->m_view->marginWidth() << (Q_INT32) d->m_view->marginHeight();
Index: khtml/khtml_part.h
===================================================================
RCS file: /home/kde/kdelibs/khtml/khtml_part.h,v
retrieving revision 1.248.2.5
diff -u -p -r1.248.2.5 khtml_part.h
--- khtml/khtml_part.h	29 Jun 2004 09:08:16 -0000	1.248.2.5
+++ khtml/khtml_part.h	3 Aug 2004 14:36:47 -0000
@@ -287,6 +287,7 @@ public:
    */
   KParts::BrowserExtension *browserExtension() const;
   KParts::LiveConnectExtension *liveConnectExtension( const khtml::RenderPart *) const;
+  KParts::BrowserHostExtension *browserHostExtension() const;
 
   /**
    * Returns a pointer to the HTML document's view.
@@ -812,6 +813,16 @@ public:
   KHTMLPart *findFrame( const QString &f );
 
   /**
+   * @internal
+   * Recursively finds the part containing the frame with name @p f 
+   * and checks if it is accessible by @p callingPart
+   * Returns 0L if no suitable frame can't be found.
+   * Returns parent part if a suitable frame was found and
+   * frame info in @p *childFrame
+   */
+  KHTMLPart *findFrameParent( KParts::ReadOnlyPart *callingPart, const QString &f, khtml::ChildFrame **childFrame=0 );
+
+  /**
    * Return the current frame (the one that has focus)
    * Not necessarily a direct child of ours, framesets can be nested.
    * Returns "this" if this part isn't a frameset.
@@ -1376,6 +1387,8 @@ private:
 
   bool restoreURL( const KURL &url );
   void emitSelectionChanged();
+  // Returns whether callingHtmlPart may access this part
+  bool checkFrameAccess(KHTMLPart *callingHtmlPart);
   bool openURLInFrame( const KURL &url, const KParts::URLArgs &urlArgs );
   void startAutoScroll();
   void stopAutoScroll();
@@ -1434,7 +1447,7 @@ private:
   DOM::DocumentImpl *xmlDocImpl() const;
   khtml::ChildFrame *frame( const QObject *obj );
 
-  khtml::ChildFrame *recursiveFrameRequest( const KURL &url, const KParts::URLArgs &args, bool callParent = true );
+  khtml::ChildFrame *recursiveFrameRequest( KHTMLPart *callingHtmlPart, const KURL &url, const KParts::URLArgs &args, bool callParent = true );
 
   bool checkLinkSecurity( const KURL &linkURL,const QString &message = QString::null, const QString &button = QString::null );
   QVariant executeScript( const QString& filename, int baseLine, const DOM::Node &n, const QString& script );
Index: kparts/browserextension.cpp
===================================================================
RCS file: /home/kde/kdelibs/kparts/browserextension.cpp,v
retrieving revision 1.60.2.1
diff -u -p -r1.60.2.1 browserextension.cpp
--- kparts/browserextension.cpp	10 Apr 2004 15:08:49 -0000	1.60.2.1
+++ kparts/browserextension.cpp	3 Aug 2004 14:36:48 -0000
@@ -636,6 +636,17 @@ BrowserHostExtension *BrowserHostExtensi
 void BrowserExtension::virtual_hook( int, void* )
 { /*BASE::virtual_hook( id, data );*/ }
 
+BrowserHostExtension *
+BrowserHostExtension::findFrameParent(KParts::ReadOnlyPart *callingPart, const QString &frame)
+{
+    FindFrameParentParams param;
+    param.parent = 0;
+    param.callingPart = callingPart;
+    param.frame = frame;
+    virtual_hook(VIRTUAL_FIND_FRAME_PARENT, &param);
+    return param.parent;
+}
+
 void BrowserHostExtension::virtual_hook( int, void* )
 { /*BASE::virtual_hook( id, data );*/ }
 
Index: kparts/browserextension.h
===================================================================
RCS file: /home/kde/kdelibs/kparts/browserextension.h,v
retrieving revision 1.110
diff -u -p -r1.110 browserextension.h
--- kparts/browserextension.h	26 Sep 2003 07:13:13 -0000	1.110
+++ kparts/browserextension.h	3 Aug 2004 14:36:48 -0000
@@ -671,10 +671,16 @@ public:
    *
    * Note that this method does not query the child objects recursively.
    */
-
   virtual const QPtrList<KParts::ReadOnlyPart> frames() const;
 
   /**
+   * @internal
+   * Returns the part that contains @p frame and that may be accessed
+   * by @p callingPart
+   */
+  BrowserHostExtension *findFrameParent(KParts::ReadOnlyPart *callingPart, const QString &frame);
+
+  /**
    * Opens the given url in a hosted child frame. The frame name is specified in the
    * frameName variable in the urlArgs argument structure (see KParts::URLArgs ) .
    */
@@ -687,6 +693,19 @@ public:
   static BrowserHostExtension *childObject( QObject *obj );
 
 protected:
+  /** This 'enum' along with the structure below is NOT part of the public API.
+   * It's going to disappear in KDE 4.0 and is likely to change inbetween.
+   *
+   * @internal
+   */
+  enum { VIRTUAL_FIND_FRAME_PARENT = 0x10 };
+  struct FindFrameParentParams
+  {
+      BrowserHostExtension *parent;
+      KParts::ReadOnlyPart *callingPart;
+      QString frame;
+  };
+                                                    
   virtual void virtual_hook( int id, void* data );
 private:
   class BrowserHostExtensionPrivate;


Więcej informacji o liście dyskusyjnej pld-devel-pl