Upstream version 9.38.198.0
[platform/framework/web/crosswalk.git] / src / components / autofill / content / renderer / form_autofill_util.cc
index 995bb06..29b6009 100644 (file)
@@ -25,9 +25,9 @@
 #include "third_party/WebKit/public/web/WebExceptionCode.h"
 #include "third_party/WebKit/public/web/WebFormControlElement.h"
 #include "third_party/WebKit/public/web/WebFormElement.h"
-#include "third_party/WebKit/public/web/WebFrame.h"
 #include "third_party/WebKit/public/web/WebInputElement.h"
 #include "third_party/WebKit/public/web/WebLabelElement.h"
+#include "third_party/WebKit/public/web/WebLocalFrame.h"
 #include "third_party/WebKit/public/web/WebNode.h"
 #include "third_party/WebKit/public/web/WebNodeList.h"
 #include "third_party/WebKit/public/web/WebOptionElement.h"
@@ -67,17 +67,17 @@ enum FieldFilterMask {
 
 bool IsOptionElement(const WebElement& element) {
   CR_DEFINE_STATIC_LOCAL(WebString, kOption, ("option"));
-  return element.hasTagName(kOption);
+  return element.hasHTMLTagName(kOption);
 }
 
 bool IsScriptElement(const WebElement& element) {
   CR_DEFINE_STATIC_LOCAL(WebString, kScript, ("script"));
-  return element.hasTagName(kScript);
+  return element.hasHTMLTagName(kScript);
 }
 
 bool IsNoScriptElement(const WebElement& element) {
   CR_DEFINE_STATIC_LOCAL(WebString, kNoScript, ("noscript"));
-  return element.hasTagName(kNoScript);
+  return element.hasHTMLTagName(kNoScript);
 }
 
 bool HasTagName(const WebNode& node, const blink::WebString& tag) {
@@ -273,7 +273,7 @@ base::string16 InferLabelFromListItem(const WebFormControlElement& element) {
   WebNode parent = element.parentNode();
   CR_DEFINE_STATIC_LOCAL(WebString, kListItem, ("li"));
   while (!parent.isNull() && parent.isElementNode() &&
-         !parent.to<WebElement>().hasTagName(kListItem)) {
+         !parent.to<WebElement>().hasHTMLTagName(kListItem)) {
     parent = parent.parentNode();
   }
 
@@ -293,7 +293,7 @@ base::string16 InferLabelFromTableColumn(const WebFormControlElement& element) {
   CR_DEFINE_STATIC_LOCAL(WebString, kTableCell, ("td"));
   WebNode parent = element.parentNode();
   while (!parent.isNull() && parent.isElementNode() &&
-         !parent.to<WebElement>().hasTagName(kTableCell)) {
+         !parent.to<WebElement>().hasHTMLTagName(kTableCell)) {
     parent = parent.parentNode();
   }
 
@@ -322,7 +322,7 @@ base::string16 InferLabelFromTableRow(const WebFormControlElement& element) {
   CR_DEFINE_STATIC_LOCAL(WebString, kTableRow, ("tr"));
   WebNode parent = element.parentNode();
   while (!parent.isNull() && parent.isElementNode() &&
-         !parent.to<WebElement>().hasTagName(kTableRow)) {
+         !parent.to<WebElement>().hasHTMLTagName(kTableRow)) {
     parent = parent.parentNode();
   }
 
@@ -389,7 +389,7 @@ base::string16 InferLabelFromDefinitionList(
   CR_DEFINE_STATIC_LOCAL(WebString, kDefinitionData, ("dd"));
   WebNode parent = element.parentNode();
   while (!parent.isNull() && parent.isElementNode() &&
-         !parent.to<WebElement>().hasTagName(kDefinitionData))
+         !parent.to<WebElement>().hasHTMLTagName(kDefinitionData))
     parent = parent.parentNode();
 
   if (parent.isNull() || !HasTagName(parent, kDefinitionData))
@@ -448,6 +448,13 @@ void GetOptionStringsFromElement(const WebSelectElement& select_element,
   option_values->clear();
   option_contents->clear();
   WebVector<WebElement> list_items = select_element.listItems();
+
+  // Constrain the maximum list length to prevent a malicious site from DOS'ing
+  // the browser, without entirely breaking autocomplete for some extreme
+  // legitimate sites: http://crbug.com/49332 and http://crbug.com/363094
+  if (list_items.size() > kMaxListSize)
+    return;
+
   option_values->reserve(list_items.size());
   option_contents->reserve(list_items.size());
   for (size_t i = 0; i < list_items.size(); ++i) {
@@ -530,22 +537,22 @@ void FillFormField(const FormFieldData& data,
   if (data.value.empty())
     return;
 
+  if (!data.is_autofilled)
+    return;
+
   field->setAutofilled(true);
 
   WebInputElement* input_element = toWebInputElement(field);
-  if (IsTextInput(input_element) || IsMonthInput(input_element)) {
-    // If the maxlength attribute contains a negative value, maxLength()
-    // returns the default maxlength value.
-    input_element->setValue(
-        data.value.substr(0, input_element->maxLength()), true);
-  } else if (IsTextAreaElement(*field) || IsSelectElement(*field)) {
-    if (field->value() != data.value) {
-      field->setValue(data.value);
-      field->dispatchFormControlChangeEvent();
-    }
-  } else {
-    DCHECK(IsCheckableElement(input_element));
+  if (IsCheckableElement(input_element)) {
     input_element->setChecked(data.is_checked, true);
+  } else {
+    base::string16 value = data.value;
+    if (IsTextInput(input_element) || IsMonthInput(input_element)) {
+      // If the maxlength attribute contains a negative value, maxLength()
+      // returns the default maxlength value.
+      value = value.substr(0, input_element->maxLength());
+    }
+    field->setValue(value, true);
   }
 
   if (is_initiating_node &&
@@ -567,6 +574,9 @@ void PreviewFormField(const FormFieldData& data,
   if (data.value.empty())
     return;
 
+  if (!data.is_autofilled)
+    return;
+
   // Preview input, textarea and select fields. For input fields, excludes
   // checkboxes and radio buttons, as there is no provision for
   // setSuggestedCheckedValue in WebInputElement.
@@ -799,19 +809,17 @@ void WebFormControlElementToFormField(const WebFormControlElement& element,
 
   base::string16 value = element.value();
 
-  if (IsSelectElement(element)) {
+  if (IsSelectElement(element) && (extract_mask & EXTRACT_OPTION_TEXT)) {
     const WebSelectElement select_element = element.toConst<WebSelectElement>();
     // Convert the |select_element| value to text if requested.
-    if (extract_mask & EXTRACT_OPTION_TEXT) {
-      WebVector<WebElement> list_items = select_element.listItems();
-      for (size_t i = 0; i < list_items.size(); ++i) {
-        if (IsOptionElement(list_items[i])) {
-          const WebOptionElement option_element =
-              list_items[i].toConst<WebOptionElement>();
-          if (option_element.value() == value) {
-            value = option_element.text();
-            break;
-          }
+    WebVector<WebElement> list_items = select_element.listItems();
+    for (size_t i = 0; i < list_items.size(); ++i) {
+      if (IsOptionElement(list_items[i])) {
+        const WebOptionElement option_element =
+            list_items[i].toConst<WebOptionElement>();
+        if (option_element.value() == value) {
+          value = option_element.text();
+          break;
         }
       }
     }
@@ -844,7 +852,6 @@ bool WebFormElementToFormData(
     return false;
 
   form->name = GetFormIdentifier(form_element);
-  form->method = form_element.method();
   form->origin = frame->document().url();
   form->action = frame->document().completeURL(form_element.action());
   form->user_submitted = form_element.wasUserSubmitted();
@@ -901,7 +908,7 @@ bool WebFormElementToFormData(
   // element's name as a key into the <name, FormFieldData> map to find the
   // previously created FormFieldData and set the FormFieldData's label to the
   // label.firstChild().nodeValue() of the label element.
-  WebElementCollection labels = form_element.getElementsByTagName(kLabel);
+  WebElementCollection labels = form_element.getElementsByHTMLTagName(kLabel);
   DCHECK(!labels.isNull());
   for (WebElement item = labels.firstItem(); !item.isNull();
        item = labels.nextItem()) {