Skip to content
This repository has been archived by the owner on May 10, 2018. It is now read-only.

Commit

Permalink
AutoFill: Rewrite AutoFill to complete each frame separately
Browse files Browse the repository at this point in the history
Fixes crash from #1417
  • Loading branch information
nowrep committed Sep 19, 2014
1 parent 40e476e commit 3360a53
Show file tree
Hide file tree
Showing 9 changed files with 77 additions and 28 deletions.
25 changes: 15 additions & 10 deletions src/lib/autofill/autofill.cpp
Expand Up @@ -169,16 +169,16 @@ void AutoFill::removeAllEntries()
}

// 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;
QVector<PasswordEntry> list;

if (!page) {
if (!frame) {
return list;
}

QUrl pageUrl = page->url();
QUrl pageUrl = frame->url();
if (!isStored(pageUrl)) {
return list;
}
Expand All @@ -188,8 +188,8 @@ QVector<PasswordEntry> AutoFill::completePage(WebPage* page)
if (!list.isEmpty()) {
const PasswordEntry entry = list.first();

PageFormCompleter completer(page);
completed = completer.completePage(entry.data);
PageFormCompleter completer;
completed = completer.completeFormData(frame, entry.data);
}

if (!completed) {
Expand All @@ -206,11 +206,16 @@ void AutoFill::post(const QNetworkRequest &request, const QByteArray &outgoingDa
return;
}

QVariant v = request.attribute((QNetworkRequest::Attribute)(QNetworkRequest::User + 100));
WebPage* webPage = static_cast<WebPage*>(v.value<void*>());
if (!WebPage::isPointerSafeToUse(webPage)) {
QWebFrame* frame = qobject_cast<QWebFrame*>(request.originatingObject());
if (!frame) {
return;
}

WebPage* webPage = qobject_cast<WebPage*>(frame->page());
if (!webPage) {
return;
}

WebView* webView = qobject_cast<WebView*>(webPage->view());
if (!webView) {
return;
Expand All @@ -222,8 +227,8 @@ void AutoFill::post(const QNetworkRequest &request, const QByteArray &outgoingDa
return;
}

PageFormCompleter completer(webPage);
const PageFormData formData = completer.extractFormData(outgoingData);
PageFormCompleter completer;
const PageFormData formData = completer.extractFormData(frame, outgoingData);

if (!formData.isValid()) {
return;
Expand Down
4 changes: 2 additions & 2 deletions src/lib/autofill/autofill.h
Expand Up @@ -23,11 +23,11 @@
#include "qzcommon.h"

class QUrl;
class QWebFrame;
class QWebElement;
class QNetworkRequest;

class BrowserWindow;
class WebPage;
class PasswordManager;
struct PageFormData;
struct PasswordEntry;
Expand Down Expand Up @@ -61,7 +61,7 @@ class QUPZILLA_EXPORT AutoFill : public QObject
void removeAllEntries();

void post(const QNetworkRequest &request, const QByteArray &outgoingData);
QVector<PasswordEntry> completePage(WebPage* page);
QVector<PasswordEntry> completeFrame(QWebFrame* frame);

QByteArray exportPasswords();
bool importPasswords(const QByteArray &data);
Expand Down
4 changes: 2 additions & 2 deletions src/lib/autofill/autofillwidget.cpp
Expand Up @@ -68,8 +68,8 @@ void AutoFillWidget::loginToPage()
if (ok && QzTools::containsIndex(m_data, index)) {
const PasswordEntry entry = m_data.at(index);

PageFormCompleter completer(m_view->page());
completer.completePage(entry.data);
PageFormCompleter completer;
completer.completeFormData(m_view->page(), entry.data);
}

close();
Expand Down
39 changes: 35 additions & 4 deletions src/lib/autofill/pageformcompleter.cpp
Expand Up @@ -25,11 +25,36 @@
#include <QUrlQuery>
#endif

PageFormCompleter::PageFormCompleter(QWebPage* page)
: m_page(page)
PageFormCompleter::PageFormCompleter()
: 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
{
QString usernameValue;
Expand Down Expand Up @@ -89,7 +114,7 @@ PageFormData PageFormCompleter::extractFormData(const QByteArray &postData) cons
}

// 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;
const QueryItems queryItems = createQueryItems(data);
Expand Down Expand Up @@ -233,7 +258,13 @@ QWebElementCollection PageFormCompleter::getAllElementsFromPage(const QString &s
{
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;

QList<QWebFrame*> frames;
Expand Down
14 changes: 11 additions & 3 deletions src/lib/autofill/pageformcompleter.h
Expand Up @@ -25,6 +25,7 @@
#include "qzcommon.h"

class QWebPage;
class QWebFrame;
class QWebElement;
class QWebElementCollection;

Expand All @@ -41,15 +42,21 @@ struct PageFormData {
class QUPZILLA_EXPORT PageFormCompleter
{
public:
explicit PageFormCompleter(QWebPage* page);
explicit PageFormCompleter();

PageFormData extractFormData(const QByteArray &postData) const;
bool completePage(const QByteArray &data) const;
PageFormData extractFormData(QWebPage* page, const QByteArray &postData);
PageFormData extractFormData(QWebFrame* frame, const QByteArray &postData);

bool completeFormData(QWebPage* page, const QByteArray &data);
bool completeFormData(QWebFrame* frame, const QByteArray &data);

private:
typedef QPair<QString, QString> QueryItem;
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,
const QString &attributeValue) const;
QByteArray convertWebKitFormBoundaryIfNecessary(const QByteArray &data) const;
Expand All @@ -58,6 +65,7 @@ class QUPZILLA_EXPORT PageFormCompleter
QWebElementCollection getAllElementsFromPage(const QString &selector) const;

QWebPage* m_page;
QWebFrame* m_frame;
};

#endif // PAGEFORMCOMPLETER_H
10 changes: 7 additions & 3 deletions src/lib/webkit/webpage.cpp
Expand Up @@ -93,6 +93,7 @@ WebPage::WebPage(QObject* parent)
connect(this, SIGNAL(printRequested(QWebFrame*)), this, SLOT(printFrame(QWebFrame*)));
connect(this, SIGNAL(downloadRequested(QNetworkRequest)), this, SLOT(downloadRequested(QNetworkRequest)));
connect(this, SIGNAL(windowCloseRequested()), this, SLOT(windowCloseRequested()));
connect(this, SIGNAL(restoreFrameStateRequested(QWebFrame*)), this, SLOT(restoreFrameRequested(QWebFrame*)));

connect(this, SIGNAL(databaseQuotaExceeded(QWebFrame*,QString)),
this, SLOT(dbQuotaExceeded(QWebFrame*)));
Expand Down Expand Up @@ -274,9 +275,6 @@ void WebPage::finished()
m_fileWatcher->removePaths(m_fileWatcher->files());
}

// Autofill
m_passwordEntries = mApp->autoFill()->completePage(this);

// AdBlock
cleanBlockedObjects();
}
Expand Down Expand Up @@ -451,6 +449,12 @@ void WebPage::windowCloseRequested()
webView->closeView();
}

void WebPage::restoreFrameRequested(QWebFrame* frame)
{
// Autofill
m_passwordEntries = mApp->autoFill()->completeFrame(frame);
}

void WebPage::dbQuotaExceeded(QWebFrame* frame)
{
if (!frame) {
Expand Down
1 change: 1 addition & 0 deletions src/lib/webkit/webpage.h
Expand Up @@ -104,6 +104,7 @@ private slots:
void downloadRequested(const QNetworkRequest &request);
void windowCloseRequested();

void restoreFrameRequested(QWebFrame* frame);
void dbQuotaExceeded(QWebFrame* frame);
void doWebSearch(const QString &text);

Expand Down
Binary file removed tests/autotests/autotests
Binary file not shown.
8 changes: 4 additions & 4 deletions tests/autotests/formcompletertest.cpp
Expand Up @@ -284,16 +284,16 @@ void FormCompleterTest::completeWithData(const QString &html, const QByteArray &
{
view->setHtml(html);

PageFormCompleter completer(view->page());
completer.completePage(data);
PageFormCompleter completer;
completer.completeFormData(view->page(), data);
}

PageFormData FormCompleterTest::extractFormData(const QString &html, const QByteArray &data)
{
view->setHtml(html);

PageFormCompleter completer(view->page());
return completer.extractFormData(data);
PageFormCompleter completer;
return completer.extractFormData(view->page(), data);
}

QVariant FormCompleterTest::getElementByIdValue(const QString &id)
Expand Down

0 comments on commit 3360a53

Please sign in to comment.