1
mirror of https://invent.kde.org/network/falkon.git synced 2024-12-24 12:46:35 +01:00

AutoFill: Rewrite AutoFill to complete each frame separately

Fixes crash from #1417
This commit is contained in:
David Rosca 2014-09-19 13:16:02 +02:00
parent 40e476e626
commit 3360a531f1
9 changed files with 77 additions and 28 deletions

View File

@ -169,16 +169,16 @@ void AutoFill::removeAllEntries()
} }
// If password was filled in the page, returns all saved passwords on this page // If password was filled in the page, returns all saved passwords on this page
QVector<PasswordEntry> AutoFill::completePage(WebPage* page) QVector<PasswordEntry> AutoFill::completeFrame(QWebFrame* frame)
{ {
bool completed = false; bool completed = false;
QVector<PasswordEntry> list; QVector<PasswordEntry> list;
if (!page) { if (!frame) {
return list; return list;
} }
QUrl pageUrl = page->url(); QUrl pageUrl = frame->url();
if (!isStored(pageUrl)) { if (!isStored(pageUrl)) {
return list; return list;
} }
@ -188,8 +188,8 @@ QVector<PasswordEntry> AutoFill::completePage(WebPage* page)
if (!list.isEmpty()) { if (!list.isEmpty()) {
const PasswordEntry entry = list.first(); const PasswordEntry entry = list.first();
PageFormCompleter completer(page); PageFormCompleter completer;
completed = completer.completePage(entry.data); completed = completer.completeFormData(frame, entry.data);
} }
if (!completed) { if (!completed) {
@ -206,11 +206,16 @@ void AutoFill::post(const QNetworkRequest &request, const QByteArray &outgoingDa
return; return;
} }
QVariant v = request.attribute((QNetworkRequest::Attribute)(QNetworkRequest::User + 100)); QWebFrame* frame = qobject_cast<QWebFrame*>(request.originatingObject());
WebPage* webPage = static_cast<WebPage*>(v.value<void*>()); if (!frame) {
if (!WebPage::isPointerSafeToUse(webPage)) {
return; return;
} }
WebPage* webPage = qobject_cast<WebPage*>(frame->page());
if (!webPage) {
return;
}
WebView* webView = qobject_cast<WebView*>(webPage->view()); WebView* webView = qobject_cast<WebView*>(webPage->view());
if (!webView) { if (!webView) {
return; return;
@ -222,8 +227,8 @@ void AutoFill::post(const QNetworkRequest &request, const QByteArray &outgoingDa
return; return;
} }
PageFormCompleter completer(webPage); PageFormCompleter completer;
const PageFormData formData = completer.extractFormData(outgoingData); const PageFormData formData = completer.extractFormData(frame, outgoingData);
if (!formData.isValid()) { if (!formData.isValid()) {
return; return;

View File

@ -23,11 +23,11 @@
#include "qzcommon.h" #include "qzcommon.h"
class QUrl; class QUrl;
class QWebFrame;
class QWebElement; class QWebElement;
class QNetworkRequest; class QNetworkRequest;
class BrowserWindow; class BrowserWindow;
class WebPage;
class PasswordManager; class PasswordManager;
struct PageFormData; struct PageFormData;
struct PasswordEntry; struct PasswordEntry;
@ -61,7 +61,7 @@ public:
void removeAllEntries(); void removeAllEntries();
void post(const QNetworkRequest &request, const QByteArray &outgoingData); void post(const QNetworkRequest &request, const QByteArray &outgoingData);
QVector<PasswordEntry> completePage(WebPage* page); QVector<PasswordEntry> completeFrame(QWebFrame* frame);
QByteArray exportPasswords(); QByteArray exportPasswords();
bool importPasswords(const QByteArray &data); bool importPasswords(const QByteArray &data);

View File

@ -68,8 +68,8 @@ void AutoFillWidget::loginToPage()
if (ok && QzTools::containsIndex(m_data, index)) { if (ok && QzTools::containsIndex(m_data, index)) {
const PasswordEntry entry = m_data.at(index); const PasswordEntry entry = m_data.at(index);
PageFormCompleter completer(m_view->page()); PageFormCompleter completer;
completer.completePage(entry.data); completer.completeFormData(m_view->page(), entry.data);
} }
close(); close();

View File

@ -25,11 +25,36 @@
#include <QUrlQuery> #include <QUrlQuery>
#endif #endif
PageFormCompleter::PageFormCompleter(QWebPage* page) PageFormCompleter::PageFormCompleter()
: m_page(page) : m_page(0)
, m_frame(0)
{ {
} }
PageFormData PageFormCompleter::extractFormData(QWebPage* page, const QByteArray &postData)
{
m_page = page;
return extractFormData(postData);
}
PageFormData PageFormCompleter::extractFormData(QWebFrame* frame, const QByteArray &postData)
{
m_frame = frame;
return extractFormData(postData);
}
bool PageFormCompleter::completeFormData(QWebPage* page, const QByteArray &data)
{
m_page = page;
return completeFormData(data);
}
bool PageFormCompleter::completeFormData(QWebFrame* frame, const QByteArray &data)
{
m_frame = frame;
return completeFormData(data);
}
PageFormData PageFormCompleter::extractFormData(const QByteArray &postData) const PageFormData PageFormCompleter::extractFormData(const QByteArray &postData) const
{ {
QString usernameValue; QString usernameValue;
@ -89,7 +114,7 @@ PageFormData PageFormCompleter::extractFormData(const QByteArray &postData) cons
} }
// Returns if any data was actually filled in page // Returns if any data was actually filled in page
bool PageFormCompleter::completePage(const QByteArray &data) const bool PageFormCompleter::completeFormData(const QByteArray &data) const
{ {
bool completed = false; bool completed = false;
const QueryItems queryItems = createQueryItems(data); const QueryItems queryItems = createQueryItems(data);
@ -233,7 +258,13 @@ QWebElementCollection PageFormCompleter::getAllElementsFromPage(const QString &s
{ {
QWebElementCollection list; QWebElementCollection list;
if (!m_page || !m_page->mainFrame()) if (!m_page && !m_frame)
return list;
if (m_frame)
return m_frame->findAllElements(selector);
if (!m_page->mainFrame())
return list; return list;
QList<QWebFrame*> frames; QList<QWebFrame*> frames;

View File

@ -25,6 +25,7 @@
#include "qzcommon.h" #include "qzcommon.h"
class QWebPage; class QWebPage;
class QWebFrame;
class QWebElement; class QWebElement;
class QWebElementCollection; class QWebElementCollection;
@ -41,15 +42,21 @@ struct PageFormData {
class QUPZILLA_EXPORT PageFormCompleter class QUPZILLA_EXPORT PageFormCompleter
{ {
public: public:
explicit PageFormCompleter(QWebPage* page); explicit PageFormCompleter();
PageFormData extractFormData(const QByteArray &postData) const; PageFormData extractFormData(QWebPage* page, const QByteArray &postData);
bool completePage(const QByteArray &data) const; PageFormData extractFormData(QWebFrame* frame, const QByteArray &postData);
bool completeFormData(QWebPage* page, const QByteArray &data);
bool completeFormData(QWebFrame* frame, const QByteArray &data);
private: private:
typedef QPair<QString, QString> QueryItem; typedef QPair<QString, QString> QueryItem;
typedef QList<QPair<QString, QString> > QueryItems; typedef QList<QPair<QString, QString> > QueryItems;
PageFormData extractFormData(const QByteArray &postData) const;
bool completeFormData(const QByteArray &data) const;
bool queryItemsContains(const QueryItems &queryItems, const QString &attributeName, bool queryItemsContains(const QueryItems &queryItems, const QString &attributeName,
const QString &attributeValue) const; const QString &attributeValue) const;
QByteArray convertWebKitFormBoundaryIfNecessary(const QByteArray &data) const; QByteArray convertWebKitFormBoundaryIfNecessary(const QByteArray &data) const;
@ -58,6 +65,7 @@ private:
QWebElementCollection getAllElementsFromPage(const QString &selector) const; QWebElementCollection getAllElementsFromPage(const QString &selector) const;
QWebPage* m_page; QWebPage* m_page;
QWebFrame* m_frame;
}; };
#endif // PAGEFORMCOMPLETER_H #endif // PAGEFORMCOMPLETER_H

View File

@ -93,6 +93,7 @@ WebPage::WebPage(QObject* parent)
connect(this, SIGNAL(printRequested(QWebFrame*)), this, SLOT(printFrame(QWebFrame*))); connect(this, SIGNAL(printRequested(QWebFrame*)), this, SLOT(printFrame(QWebFrame*)));
connect(this, SIGNAL(downloadRequested(QNetworkRequest)), this, SLOT(downloadRequested(QNetworkRequest))); connect(this, SIGNAL(downloadRequested(QNetworkRequest)), this, SLOT(downloadRequested(QNetworkRequest)));
connect(this, SIGNAL(windowCloseRequested()), this, SLOT(windowCloseRequested())); connect(this, SIGNAL(windowCloseRequested()), this, SLOT(windowCloseRequested()));
connect(this, SIGNAL(restoreFrameStateRequested(QWebFrame*)), this, SLOT(restoreFrameRequested(QWebFrame*)));
connect(this, SIGNAL(databaseQuotaExceeded(QWebFrame*,QString)), connect(this, SIGNAL(databaseQuotaExceeded(QWebFrame*,QString)),
this, SLOT(dbQuotaExceeded(QWebFrame*))); this, SLOT(dbQuotaExceeded(QWebFrame*)));
@ -274,9 +275,6 @@ void WebPage::finished()
m_fileWatcher->removePaths(m_fileWatcher->files()); m_fileWatcher->removePaths(m_fileWatcher->files());
} }
// Autofill
m_passwordEntries = mApp->autoFill()->completePage(this);
// AdBlock // AdBlock
cleanBlockedObjects(); cleanBlockedObjects();
} }
@ -451,6 +449,12 @@ void WebPage::windowCloseRequested()
webView->closeView(); webView->closeView();
} }
void WebPage::restoreFrameRequested(QWebFrame* frame)
{
// Autofill
m_passwordEntries = mApp->autoFill()->completeFrame(frame);
}
void WebPage::dbQuotaExceeded(QWebFrame* frame) void WebPage::dbQuotaExceeded(QWebFrame* frame)
{ {
if (!frame) { if (!frame) {

View File

@ -104,6 +104,7 @@ private slots:
void downloadRequested(const QNetworkRequest &request); void downloadRequested(const QNetworkRequest &request);
void windowCloseRequested(); void windowCloseRequested();
void restoreFrameRequested(QWebFrame* frame);
void dbQuotaExceeded(QWebFrame* frame); void dbQuotaExceeded(QWebFrame* frame);
void doWebSearch(const QString &text); void doWebSearch(const QString &text);

Binary file not shown.

View File

@ -284,16 +284,16 @@ void FormCompleterTest::completeWithData(const QString &html, const QByteArray &
{ {
view->setHtml(html); view->setHtml(html);
PageFormCompleter completer(view->page()); PageFormCompleter completer;
completer.completePage(data); completer.completeFormData(view->page(), data);
} }
PageFormData FormCompleterTest::extractFormData(const QString &html, const QByteArray &data) PageFormData FormCompleterTest::extractFormData(const QString &html, const QByteArray &data)
{ {
view->setHtml(html); view->setHtml(html);
PageFormCompleter completer(view->page()); PageFormCompleter completer;
return completer.extractFormData(data); return completer.extractFormData(view->page(), data);
} }
QVariant FormCompleterTest::getElementByIdValue(const QString &id) QVariant FormCompleterTest::getElementByIdValue(const QString &id)