summaryrefslogtreecommitdiff
path: root/Source/WebCore/loader/FormSubmission.cpp
diff options
context:
space:
mode:
authorLorry Tar Creator <lorry-tar-importer@lorry>2017-06-27 06:07:23 +0000
committerLorry Tar Creator <lorry-tar-importer@lorry>2017-06-27 06:07:23 +0000
commit1bf1084f2b10c3b47fd1a588d85d21ed0eb41d0c (patch)
tree46dcd36c86e7fbc6e5df36deb463b33e9967a6f7 /Source/WebCore/loader/FormSubmission.cpp
parent32761a6cee1d0dee366b885b7b9c777e67885688 (diff)
downloadWebKitGtk-tarball-master.tar.gz
Diffstat (limited to 'Source/WebCore/loader/FormSubmission.cpp')
-rw-r--r--Source/WebCore/loader/FormSubmission.cpp144
1 files changed, 79 insertions, 65 deletions
diff --git a/Source/WebCore/loader/FormSubmission.cpp b/Source/WebCore/loader/FormSubmission.cpp
index 4d1a6e85b..1d742ea33 100644
--- a/Source/WebCore/loader/FormSubmission.cpp
+++ b/Source/WebCore/loader/FormSubmission.cpp
@@ -1,5 +1,6 @@
/*
* Copyright (C) 2010 Google Inc. All rights reserved.
+ * Copyright (C) 2015-2016 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
@@ -31,6 +32,7 @@
#include "config.h"
#include "FormSubmission.h"
+#include "ContentSecurityPolicy.h"
#include "DOMFormData.h"
#include "Document.h"
#include "Event.h"
@@ -45,9 +47,9 @@
#include "HTMLInputElement.h"
#include "HTMLNames.h"
#include "HTMLParserIdioms.h"
+#include "NoEventDispatchAssertion.h"
#include "TextEncoding.h"
#include <wtf/CurrentTime.h>
-#include <wtf/RandomNumber.h>
namespace WebCore {
@@ -65,7 +67,7 @@ static void appendMailtoPostFormDataToURL(URL& url, const FormData& data, const
{
String body = data.flattenToString();
- if (equalIgnoringCase(encodingType, "text/plain")) {
+ if (equalLettersIgnoringASCIICase(encodingType, "text/plain")) {
// Convention seems to be to decode, and s/&/\r\n/. Also, spaces are encoded as %20.
body = decodeURLEscapeSequences(body.replaceWithLiteral('&', "\r\n").replace('+', ' ') + "\r\n");
}
@@ -76,10 +78,10 @@ static void appendMailtoPostFormDataToURL(URL& url, const FormData& data, const
body = String(bodyData.data(), bodyData.size()).replaceWithLiteral('+', "%20");
String query = url.query();
- if (!query.isEmpty())
- query.append('&');
- query.append(body);
- url.setQuery(query);
+ if (query.isEmpty())
+ url.setQuery(body);
+ else
+ url.setQuery(query + '&' + body);
}
void FormSubmission::Attributes::parseAction(const String& action)
@@ -90,11 +92,11 @@ void FormSubmission::Attributes::parseAction(const String& action)
String FormSubmission::Attributes::parseEncodingType(const String& type)
{
- if (equalIgnoringCase(type, "multipart/form-data"))
- return "multipart/form-data";
- if (equalIgnoringCase(type, "text/plain"))
- return "text/plain";
- return "application/x-www-form-urlencoded";
+ if (equalLettersIgnoringASCIICase(type, "multipart/form-data"))
+ return ASCIILiteral("multipart/form-data");
+ if (equalLettersIgnoringASCIICase(type, "text/plain"))
+ return ASCIILiteral("text/plain");
+ return ASCIILiteral("application/x-www-form-urlencoded");
}
void FormSubmission::Attributes::updateEncodingType(const String& type)
@@ -105,7 +107,7 @@ void FormSubmission::Attributes::updateEncodingType(const String& type)
FormSubmission::Method FormSubmission::Attributes::parseMethodType(const String& type)
{
- return equalIgnoringCase(type, "post") ? FormSubmission::PostMethod : FormSubmission::GetMethod;
+ return equalLettersIgnoringASCIICase(type, "post") ? FormSubmission::Method::Post : FormSubmission::Method::Get;
}
void FormSubmission::Attributes::updateMethodType(const String& type)
@@ -113,65 +115,70 @@ void FormSubmission::Attributes::updateMethodType(const String& type)
m_method = parseMethodType(type);
}
-void FormSubmission::Attributes::copyFrom(const Attributes& other)
-{
- m_method = other.m_method;
- m_isMultiPartForm = other.m_isMultiPartForm;
-
- m_action = other.m_action;
- m_target = other.m_target;
- m_encodingType = other.m_encodingType;
- m_acceptCharset = other.m_acceptCharset;
-}
-
-inline FormSubmission::FormSubmission(Method method, const URL& action, const String& target, const String& contentType, PassRefPtr<FormState> state, PassRefPtr<FormData> data, const String& boundary, bool lockHistory, PassRefPtr<Event> event)
+inline FormSubmission::FormSubmission(Method method, const URL& action, const String& target, const String& contentType, Ref<FormState>&& state, Ref<FormData>&& data, const String& boundary, LockHistory lockHistory, Event* event)
: m_method(method)
, m_action(action)
, m_target(target)
, m_contentType(contentType)
- , m_formState(state)
- , m_formData(data)
+ , m_formState(WTFMove(state))
+ , m_formData(WTFMove(data))
, m_boundary(boundary)
, m_lockHistory(lockHistory)
, m_event(event)
{
}
-PassRefPtr<FormSubmission> FormSubmission::create(HTMLFormElement* form, const Attributes& attributes, PassRefPtr<Event> event, bool lockHistory, FormSubmissionTrigger trigger)
+static TextEncoding encodingFromAcceptCharset(const String& acceptCharset, Document& document)
{
- ASSERT(form);
+ String normalizedAcceptCharset = acceptCharset;
+ normalizedAcceptCharset.replace(',', ' ');
+
+ Vector<String> charsets;
+ normalizedAcceptCharset.split(' ', charsets);
+
+ for (auto& charset : charsets) {
+ TextEncoding encoding(charset);
+ if (encoding.isValid())
+ return encoding;
+ }
- HTMLFormControlElement* submitButton = 0;
+ return document.textEncoding();
+}
+
+Ref<FormSubmission> FormSubmission::create(HTMLFormElement& form, const Attributes& attributes, Event* event, LockHistory lockHistory, FormSubmissionTrigger trigger)
+{
+ HTMLFormControlElement* submitButton = nullptr;
if (event && event->target()) {
for (Node* node = event->target()->toNode(); node; node = node->parentNode()) {
- if (node->isElementNode() && toElement(node)->isFormControlElement()) {
- submitButton = toHTMLFormControlElement(node);
+ if (is<HTMLFormControlElement>(*node)) {
+ submitButton = downcast<HTMLFormControlElement>(node);
break;
}
}
}
- FormSubmission::Attributes copiedAttributes;
- copiedAttributes.copyFrom(attributes);
+ auto copiedAttributes = attributes;
if (submitButton) {
- String attributeValue;
- if (!(attributeValue = submitButton->getAttribute(formactionAttr)).isNull())
+ AtomicString attributeValue;
+ if (!(attributeValue = submitButton->attributeWithoutSynchronization(formactionAttr)).isNull())
copiedAttributes.parseAction(attributeValue);
- if (!(attributeValue = submitButton->getAttribute(formenctypeAttr)).isNull())
+ if (!(attributeValue = submitButton->attributeWithoutSynchronization(formenctypeAttr)).isNull())
copiedAttributes.updateEncodingType(attributeValue);
- if (!(attributeValue = submitButton->getAttribute(formmethodAttr)).isNull())
+ if (!(attributeValue = submitButton->attributeWithoutSynchronization(formmethodAttr)).isNull())
copiedAttributes.updateMethodType(attributeValue);
- if (!(attributeValue = submitButton->getAttribute(formtargetAttr)).isNull())
+ if (!(attributeValue = submitButton->attributeWithoutSynchronization(formtargetAttr)).isNull())
copiedAttributes.setTarget(attributeValue);
}
- Document& document = form->document();
- URL actionURL = document.completeURL(copiedAttributes.action().isEmpty() ? document.url().string() : copiedAttributes.action());
+ auto& document = form.document();
+ auto actionURL = document.completeURL(copiedAttributes.action().isEmpty() ? document.url().string() : copiedAttributes.action());
bool isMailtoForm = actionURL.protocolIs("mailto");
bool isMultiPartForm = false;
- String encodingType = copiedAttributes.encodingType();
+ auto encodingType = copiedAttributes.encodingType();
+
+ document.contentSecurityPolicy()->upgradeInsecureRequestIfNeeded(actionURL, ContentSecurityPolicy::InsecureRequestType::FormSubmission);
- if (copiedAttributes.method() == PostMethod) {
+ if (copiedAttributes.method() == Method::Post) {
isMultiPartForm = copiedAttributes.isMultiPartForm();
if (isMultiPartForm && isMailtoForm) {
encodingType = "application/x-www-form-urlencoded";
@@ -179,24 +186,27 @@ PassRefPtr<FormSubmission> FormSubmission::create(HTMLFormElement* form, const A
}
}
- TextEncoding dataEncoding = isMailtoForm ? UTF8Encoding() : FormDataBuilder::encodingFromAcceptCharset(copiedAttributes.acceptCharset(), document);
- RefPtr<DOMFormData> domFormData = DOMFormData::create(dataEncoding.encodingForFormSubmission());
- Vector<std::pair<String, String>> formValues;
+ auto dataEncoding = isMailtoForm ? UTF8Encoding() : encodingFromAcceptCharset(copiedAttributes.acceptCharset(), document);
+ auto domFormData = DOMFormData::create(dataEncoding.encodingForFormSubmission());
+ StringPairVector formValues;
bool containsPasswordData = false;
- for (unsigned i = 0; i < form->associatedElements().size(); ++i) {
- FormAssociatedElement& control = *form->associatedElements()[i];
- HTMLElement& element = control.asHTMLElement();
- if (!element.isDisabledFormControl())
- control.appendFormData(*domFormData, isMultiPartForm);
- if (isHTMLInputElement(element)) {
- HTMLInputElement& input = toHTMLInputElement(element);
- if (input.isTextField()) {
- formValues.append(std::pair<String, String>(input.name().string(), input.value()));
- input.addSearchResult();
+ {
+ NoEventDispatchAssertion noEventDispatchAssertion;
+
+ for (auto& control : form.associatedElements()) {
+ auto& element = control->asHTMLElement();
+ if (!element.isDisabledFormControl())
+ control->appendFormData(domFormData, isMultiPartForm);
+ if (is<HTMLInputElement>(element)) {
+ auto& input = downcast<HTMLInputElement>(element);
+ if (input.isTextField()) {
+ formValues.append({ input.name().string(), input.value() });
+ input.addSearchResult();
+ }
+ if (input.isPasswordField() && !input.value().isEmpty())
+ containsPasswordData = true;
}
- if (input.isPasswordField() && !input.value().isEmpty())
- containsPasswordData = true;
}
}
@@ -204,11 +214,11 @@ PassRefPtr<FormSubmission> FormSubmission::create(HTMLFormElement* form, const A
String boundary;
if (isMultiPartForm) {
- formData = FormData::createMultiPart(*(static_cast<FormDataList*>(domFormData.get())), domFormData->encoding(), &document);
+ formData = FormData::createMultiPart(domFormData, domFormData->encoding(), &document);
boundary = formData->boundary().data();
} else {
- formData = FormData::create(*(static_cast<FormDataList*>(domFormData.get())), domFormData->encoding(), attributes.method() == GetMethod ? FormData::FormURLEncoded : FormData::parseEncodingType(encodingType));
- if (copiedAttributes.method() == PostMethod && isMailtoForm) {
+ formData = FormData::create(domFormData, domFormData->encoding(), attributes.method() == Method::Get ? FormData::FormURLEncoded : FormData::parseEncodingType(encodingType));
+ if (copiedAttributes.method() == Method::Post && isMailtoForm) {
// Convert the form data into a string that we put into the URL.
appendMailtoPostFormDataToURL(actionURL, *formData, encodingType);
formData = FormData::create();
@@ -217,14 +227,17 @@ PassRefPtr<FormSubmission> FormSubmission::create(HTMLFormElement* form, const A
formData->setIdentifier(generateFormDataIdentifier());
formData->setContainsPasswordData(containsPasswordData);
+
String targetOrBaseTarget = copiedAttributes.target().isEmpty() ? document.baseTarget() : copiedAttributes.target();
- RefPtr<FormState> formState = FormState::create(form, formValues, &document, trigger);
- return adoptRef(new FormSubmission(copiedAttributes.method(), actionURL, targetOrBaseTarget, encodingType, formState.release(), formData.release(), boundary, lockHistory, event));
+
+ auto formState = FormState::create(form, WTFMove(formValues), document, trigger);
+
+ return adoptRef(*new FormSubmission(copiedAttributes.method(), actionURL, targetOrBaseTarget, encodingType, WTFMove(formState), formData.releaseNonNull(), boundary, lockHistory, event));
}
URL FormSubmission::requestURL() const
{
- if (m_method == FormSubmission::PostMethod)
+ if (m_method == Method::Post)
return m_action;
URL requestURL(m_action);
@@ -240,9 +253,9 @@ void FormSubmission::populateFrameLoadRequest(FrameLoadRequest& frameRequest)
if (!m_referrer.isEmpty())
frameRequest.resourceRequest().setHTTPReferrer(m_referrer);
- if (m_method == FormSubmission::PostMethod) {
+ if (m_method == Method::Post) {
frameRequest.resourceRequest().setHTTPMethod("POST");
- frameRequest.resourceRequest().setHTTPBody(m_formData);
+ frameRequest.resourceRequest().setHTTPBody(m_formData.copyRef());
// construct some user headers if necessary
if (m_boundary.isEmpty())
@@ -253,6 +266,7 @@ void FormSubmission::populateFrameLoadRequest(FrameLoadRequest& frameRequest)
frameRequest.resourceRequest().setURL(requestURL());
FrameLoader::addHTTPOriginIfNeeded(frameRequest.resourceRequest(), m_origin);
+ FrameLoader::addHTTPUpgradeInsecureRequestsIfNeeded(frameRequest.resourceRequest());
}
}