$NetBSD: patch-av,v 1.8.4.1 2004/08/13 13:05:05 agc Exp $ 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(dynamic_cast(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(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(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(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();