Have is<>(T*) function do a null check on the pointer argument
[WebKit-https.git] / Source / WebCore / loader / FormSubmission.cpp
index 0cab710..42343b2 100644 (file)
@@ -61,30 +61,30 @@ static int64_t generateFormDataIdentifier()
     return ++nextIdentifier;
 }
 
-static void appendMailtoPostFormDataToURL(KURL& url, const FormData& data, const String& encodingType)
+static void appendMailtoPostFormDataToURL(URL& url, const FormData& data, const String& encodingType)
 {
     String body = data.flattenToString();
 
     if (equalIgnoringCase(encodingType, "text/plain")) {
         // Convention seems to be to decode, and s/&/\r\n/. Also, spaces are encoded as %20.
-        body = decodeURLEscapeSequences(body.replace('&', "\r\n").replace('+', ' ') + "\r\n");
+        body = decodeURLEscapeSequences(body.replaceWithLiteral('&', "\r\n").replace('+', ' ') + "\r\n");
     }
 
     Vector<char> bodyData;
     bodyData.append("body=", 5);
     FormDataBuilder::encodeStringAsFormData(bodyData, body.utf8());
-    body = String(bodyData.data(), bodyData.size()).replace('+', "%20");
+    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)
 {
-    // FIXME: Can we parse into a KURL?
+    // FIXME: Can we parse into a URL?
     m_action = stripLeadingAndTrailingHTMLSpaces(action);
 }
 
@@ -124,7 +124,7 @@ void FormSubmission::Attributes::copyFrom(const Attributes& other)
     m_acceptCharset = other.m_acceptCharset;
 }
 
-inline FormSubmission::FormSubmission(Method method, const KURL& 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, PassRefPtr<FormState> state, PassRefPtr<FormData> data, const String& boundary, LockHistory lockHistory, PassRefPtr<Event> event)
     : m_method(method)
     , m_action(action)
     , m_target(target)
@@ -137,33 +137,36 @@ inline FormSubmission::FormSubmission(Method method, const KURL& action, const S
 {
 }
 
-PassRefPtr<FormSubmission> FormSubmission::create(HTMLFormElement* form, const Attributes& attributes, PassRefPtr<Event> event, bool lockHistory, FormSubmissionTrigger trigger)
+PassRefPtr<FormSubmission> FormSubmission::create(HTMLFormElement* form, const Attributes& attributes, PassRefPtr<Event> event, LockHistory lockHistory, FormSubmissionTrigger trigger)
 {
     ASSERT(form);
 
     HTMLFormControlElement* submitButton = 0;
     if (event && event->target()) {
-        Node* node = event->target()->toNode();
-        if (node && node->isElementNode() && toElement(node)->isFormControlElement())
-            submitButton = static_cast<HTMLFormControlElement*>(node);
+        for (Node* node = event->target()->toNode(); node; node = node->parentNode()) {
+            if (is<HTMLFormControlElement>(*node)) {
+                submitButton = downcast<HTMLFormControlElement>(node);
+                break;
+            }
+        }
     }
 
     FormSubmission::Attributes copiedAttributes;
     copiedAttributes.copyFrom(attributes);
     if (submitButton) {
-        String attributeValue;
-        if (!(attributeValue = submitButton->getAttribute(formactionAttr)).isNull())
+        AtomicString attributeValue;
+        if (!(attributeValue = submitButton->fastGetAttribute(formactionAttr)).isNull())
             copiedAttributes.parseAction(attributeValue);
-        if (!(attributeValue = submitButton->getAttribute(formenctypeAttr)).isNull())
+        if (!(attributeValue = submitButton->fastGetAttribute(formenctypeAttr)).isNull())
             copiedAttributes.updateEncodingType(attributeValue);
-        if (!(attributeValue = submitButton->getAttribute(formmethodAttr)).isNull())
+        if (!(attributeValue = submitButton->fastGetAttribute(formmethodAttr)).isNull())
             copiedAttributes.updateMethodType(attributeValue);
-        if (!(attributeValue = submitButton->getAttribute(formtargetAttr)).isNull())
+        if (!(attributeValue = submitButton->fastGetAttribute(formtargetAttr)).isNull())
             copiedAttributes.setTarget(attributeValue);
     }
     
-    Document* document = form->document();
-    KURL actionURL = document->completeURL(copiedAttributes.action().isEmpty() ? document->url().string() : copiedAttributes.action());
+    Document& document = form->document();
+    URL actionURL = document.completeURL(copiedAttributes.action().isEmpty() ? document.url().string() : copiedAttributes.action());
     bool isMailtoForm = actionURL.protocolIs("mailto");
     bool isMultiPartForm = false;
     String encodingType = copiedAttributes.encodingType();
@@ -178,20 +181,22 @@ 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<pair<String, String> > formValues;
+    Vector<std::pair<String, String>> formValues;
 
+    bool containsPasswordData = false;
     for (unsigned i = 0; i < form->associatedElements().size(); ++i) {
-        FormAssociatedElement* control = form->associatedElements()[i];
-        HTMLElement* element = toHTMLElement(control);
-        if (!element->disabled())
-            control->appendFormData(*domFormData, isMultiPartForm);
-        if (element->hasLocalName(inputTag)) {
-            HTMLInputElement* input = static_cast<HTMLInputElement*>(control);
-            if (input->isTextField()) {
-                formValues.append(pair<String, String>(input->name().string(), input->value()));
-                if (input->isSearchField())
-                    input->addSearchResult();
+        FormAssociatedElement& control = *form->associatedElements()[i];
+        HTMLElement& element = control.asHTMLElement();
+        if (!element.isDisabledFormControl())
+            control.appendFormData(*domFormData, isMultiPartForm);
+        if (is<HTMLInputElement>(element)) {
+            HTMLInputElement& input = downcast<HTMLInputElement>(element);
+            if (input.isTextField()) {
+                formValues.append(std::pair<String, String>(input.name().string(), input.value()));
+                input.addSearchResult();
             }
+            if (input.isPasswordField() && !input.value().isEmpty())
+                containsPasswordData = true;
         }
     }
 
@@ -199,7 +204,7 @@ 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(*(static_cast<FormDataList*>(domFormData.get())), 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));
@@ -211,17 +216,18 @@ PassRefPtr<FormSubmission> FormSubmission::create(HTMLFormElement* form, const A
     }
 
     formData->setIdentifier(generateFormDataIdentifier());
-    String targetOrBaseTarget = copiedAttributes.target().isEmpty() ? document->baseTarget() : copiedAttributes.target();
-    RefPtr<FormState> formState = FormState::create(form, formValues, document->frame(), trigger);
+    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));
 }
 
-KURL FormSubmission::requestURL() const
+URL FormSubmission::requestURL() const
 {
     if (m_method == FormSubmission::PostMethod)
         return m_action;
 
-    KURL requestURL(m_action);
+    URL requestURL(m_action);
     requestURL.setQuery(m_formData->flattenToString());    
     return requestURL;
 }
@@ -239,9 +245,9 @@ void FormSubmission::populateFrameLoadRequest(FrameLoadRequest& frameRequest)
         frameRequest.resourceRequest().setHTTPBody(m_formData);
 
         // construct some user headers if necessary
-        if (m_contentType.isNull() || m_contentType == "application/x-www-form-urlencoded")
+        if (m_boundary.isEmpty())
             frameRequest.resourceRequest().setHTTPContentType(m_contentType);
-        else // contentType must be "multipart/form-data"
+        else
             frameRequest.resourceRequest().setHTTPContentType(m_contentType + "; boundary=" + m_boundary);
     }