| OLD | NEW |
| 1 /* | 1 /* |
| 2 * Copyright (C) 2010 Google Inc. All rights reserved. | 2 * Copyright (C) 2010 Google Inc. All rights reserved. |
| 3 * | 3 * |
| 4 * Redistribution and use in source and binary forms, with or without | 4 * Redistribution and use in source and binary forms, with or without |
| 5 * modification, are permitted provided that the following conditions are | 5 * modification, are permitted provided that the following conditions are |
| 6 * met: | 6 * met: |
| 7 * | 7 * |
| 8 * * Redistributions of source code must retain the above copyright | 8 * * Redistributions of source code must retain the above copyright |
| 9 * notice, this list of conditions and the following disclaimer. | 9 * notice, this list of conditions and the following disclaimer. |
| 10 * * Redistributions in binary form must reproduce the above | 10 * * Redistributions in binary form must reproduce the above |
| (...skipping 11 matching lines...) Expand all Loading... |
| 22 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, | 22 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
| 23 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT | 23 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |
| 24 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | 24 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
| 25 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | 25 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
| 26 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | 26 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
| 27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | 27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
| 28 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | 28 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
| 29 */ | 29 */ |
| 30 | 30 |
| 31 #include "config.h" | 31 #include "config.h" |
| 32 #include "core/html/DOMFormData.h" | 32 #include "core/html/FormData.h" |
| 33 | 33 |
| 34 #include "core/fileapi/Blob.h" | 34 #include "core/fileapi/Blob.h" |
| 35 #include "core/fileapi/File.h" | 35 #include "core/fileapi/File.h" |
| 36 #include "core/frame/UseCounter.h" | 36 #include "core/frame/UseCounter.h" |
| 37 #include "core/html/HTMLFormElement.h" | 37 #include "core/html/HTMLFormElement.h" |
| 38 #include "wtf/text/TextEncoding.h" | 38 #include "wtf/text/TextEncoding.h" |
| 39 #include "wtf/text/WTFString.h" | 39 #include "wtf/text/WTFString.h" |
| 40 | 40 |
| 41 namespace blink { | 41 namespace blink { |
| 42 | 42 |
| 43 namespace { | 43 namespace { |
| 44 | 44 |
| 45 class DOMFormDataIterationSource final : public PairIterable<String, FormDataEnt
ryValue>::IterationSource { | 45 class FormDataIterationSource final : public PairIterable<String, FormDataEntryV
alue>::IterationSource { |
| 46 public: | 46 public: |
| 47 DOMFormDataIterationSource(DOMFormData* formData) : m_formData(formData), m_
current(0) { } | 47 FormDataIterationSource(FormData* formData) : m_formData(formData), m_curren
t(0) { } |
| 48 | 48 |
| 49 bool next(ScriptState* scriptState, String& key, FormDataEntryValue& value,
ExceptionState& exceptionState) override | 49 bool next(ScriptState* scriptState, String& key, FormDataEntryValue& value,
ExceptionState& exceptionState) override |
| 50 { | 50 { |
| 51 if (m_current >= m_formData->size()) | 51 if (m_current >= m_formData->size()) |
| 52 return false; | 52 return false; |
| 53 | 53 |
| 54 const FormDataList::Item& entry = m_formData->items()[m_current++]; | 54 const FormDataList::Item& entry = m_formData->items()[m_current++]; |
| 55 key = m_formData->decode(entry.key()); | 55 key = m_formData->decode(entry.key()); |
| 56 if (entry.isString()) { | 56 if (entry.isString()) { |
| 57 value.setUSVString(m_formData->decode(entry.data())); | 57 value.setUSVString(m_formData->decode(entry.data())); |
| 58 } else { | 58 } else { |
| 59 ASSERT(entry.isFile()); | 59 ASSERT(entry.isFile()); |
| 60 value.setFile(entry.file()); | 60 value.setFile(entry.file()); |
| 61 } | 61 } |
| 62 return true; | 62 return true; |
| 63 } | 63 } |
| 64 | 64 |
| 65 DEFINE_INLINE_VIRTUAL_TRACE() | 65 DEFINE_INLINE_VIRTUAL_TRACE() |
| 66 { | 66 { |
| 67 visitor->trace(m_formData); | 67 visitor->trace(m_formData); |
| 68 PairIterable<String, FormDataEntryValue>::IterationSource::trace(visitor
); | 68 PairIterable<String, FormDataEntryValue>::IterationSource::trace(visitor
); |
| 69 } | 69 } |
| 70 | 70 |
| 71 private: | 71 private: |
| 72 const Member<DOMFormData> m_formData; | 72 const Member<FormData> m_formData; |
| 73 size_t m_current; | 73 size_t m_current; |
| 74 }; | 74 }; |
| 75 | 75 |
| 76 } // namespace | 76 } // namespace |
| 77 | 77 |
| 78 DOMFormData::DOMFormData(const WTF::TextEncoding& encoding) | 78 FormData::FormData(const WTF::TextEncoding& encoding) |
| 79 : FormDataList(encoding) | 79 : FormDataList(encoding) |
| 80 , m_opaque(false) | 80 , m_opaque(false) |
| 81 { | 81 { |
| 82 } | 82 } |
| 83 | 83 |
| 84 DOMFormData::DOMFormData(HTMLFormElement* form) | 84 FormData::FormData(HTMLFormElement* form) |
| 85 : FormDataList(UTF8Encoding()) | 85 : FormDataList(UTF8Encoding()) |
| 86 , m_opaque(false) | 86 , m_opaque(false) |
| 87 { | 87 { |
| 88 if (!form) | 88 if (!form) |
| 89 return; | 89 return; |
| 90 | 90 |
| 91 for (unsigned i = 0; i < form->associatedElements().size(); ++i) { | 91 for (unsigned i = 0; i < form->associatedElements().size(); ++i) { |
| 92 FormAssociatedElement* element = form->associatedElements()[i]; | 92 FormAssociatedElement* element = form->associatedElements()[i]; |
| 93 if (!toHTMLElement(element)->isDisabledFormControl()) | 93 if (!toHTMLElement(element)->isDisabledFormControl()) |
| 94 element->appendFormData(*this, true); | 94 element->appendFormData(*this, true); |
| 95 } | 95 } |
| 96 } | 96 } |
| 97 | 97 |
| 98 void DOMFormData::append(const String& name, const String& value) | 98 void FormData::append(const String& name, const String& value) |
| 99 { | 99 { |
| 100 appendData(name, value); | 100 appendData(name, value); |
| 101 } | 101 } |
| 102 | 102 |
| 103 void DOMFormData::append(ExecutionContext* context, const String& name, Blob* bl
ob, const String& filename) | 103 void FormData::append(ExecutionContext* context, const String& name, Blob* blob,
const String& filename) |
| 104 { | 104 { |
| 105 if (blob) { | 105 if (blob) { |
| 106 if (blob->isFile()) { | 106 if (blob->isFile()) { |
| 107 if (filename.isNull()) | 107 if (filename.isNull()) |
| 108 UseCounter::count(context, UseCounter::FormDataAppendFile); | 108 UseCounter::count(context, UseCounter::FormDataAppendFile); |
| 109 else | 109 else |
| 110 UseCounter::count(context, UseCounter::FormDataAppendFileWithFil
ename); | 110 UseCounter::count(context, UseCounter::FormDataAppendFileWithFil
ename); |
| 111 } else { | 111 } else { |
| 112 if (filename.isNull()) | 112 if (filename.isNull()) |
| 113 UseCounter::count(context, UseCounter::FormDataAppendBlob); | 113 UseCounter::count(context, UseCounter::FormDataAppendBlob); |
| 114 else | 114 else |
| 115 UseCounter::count(context, UseCounter::FormDataAppendBlobWithFil
ename); | 115 UseCounter::count(context, UseCounter::FormDataAppendBlobWithFil
ename); |
| 116 } | 116 } |
| 117 } else { | 117 } else { |
| 118 UseCounter::count(context, UseCounter::FormDataAppendNull); | 118 UseCounter::count(context, UseCounter::FormDataAppendNull); |
| 119 } | 119 } |
| 120 appendBlob(name, blob, filename); | 120 appendBlob(name, blob, filename); |
| 121 } | 121 } |
| 122 | 122 |
| 123 void DOMFormData::deleteEntry(const String& name) | 123 void FormData::deleteEntry(const String& name) |
| 124 { | 124 { |
| 125 const CString keyData = encodeAndNormalize(name); | 125 const CString keyData = encodeAndNormalize(name); |
| 126 size_t i = 0; | 126 size_t i = 0; |
| 127 while (i < m_items.size()) { | 127 while (i < m_items.size()) { |
| 128 if (m_items[i].key() == keyData) { | 128 if (m_items[i].key() == keyData) { |
| 129 m_items.remove(i); | 129 m_items.remove(i); |
| 130 } else { | 130 } else { |
| 131 ++i; | 131 ++i; |
| 132 } | 132 } |
| 133 } | 133 } |
| 134 } | 134 } |
| 135 | 135 |
| 136 void DOMFormData::get(const String& name, FormDataEntryValue& result) | 136 void FormData::get(const String& name, FormDataEntryValue& result) |
| 137 { | 137 { |
| 138 if (m_opaque) | 138 if (m_opaque) |
| 139 return; | 139 return; |
| 140 const CString encodedName = encodeAndNormalize(name); | 140 const CString encodedName = encodeAndNormalize(name); |
| 141 for (const Item& entry : items()) { | 141 for (const Item& entry : items()) { |
| 142 if (entry.key() == encodedName) { | 142 if (entry.key() == encodedName) { |
| 143 if (entry.isString()) { | 143 if (entry.isString()) { |
| 144 result.setUSVString(decode(entry.data())); | 144 result.setUSVString(decode(entry.data())); |
| 145 } else { | 145 } else { |
| 146 ASSERT(entry.isFile()); | 146 ASSERT(entry.isFile()); |
| 147 result.setFile(entry.file()); | 147 result.setFile(entry.file()); |
| 148 } | 148 } |
| 149 return; | 149 return; |
| 150 } | 150 } |
| 151 } | 151 } |
| 152 } | 152 } |
| 153 | 153 |
| 154 HeapVector<FormDataEntryValue> DOMFormData::getAll(const String& name) | 154 HeapVector<FormDataEntryValue> FormData::getAll(const String& name) |
| 155 { | 155 { |
| 156 HeapVector<FormDataEntryValue> results; | 156 HeapVector<FormDataEntryValue> results; |
| 157 | 157 |
| 158 if (m_opaque) | 158 if (m_opaque) |
| 159 return results; | 159 return results; |
| 160 | 160 |
| 161 const CString encodedName = encodeAndNormalize(name); | 161 const CString encodedName = encodeAndNormalize(name); |
| 162 for (const Item& entry : items()) { | 162 for (const Item& entry : items()) { |
| 163 if (entry.key() != encodedName) | 163 if (entry.key() != encodedName) |
| 164 continue; | 164 continue; |
| 165 FormDataEntryValue value; | 165 FormDataEntryValue value; |
| 166 if (entry.isString()) { | 166 if (entry.isString()) { |
| 167 value.setUSVString(decode(entry.data())); | 167 value.setUSVString(decode(entry.data())); |
| 168 } else { | 168 } else { |
| 169 ASSERT(entry.isFile()); | 169 ASSERT(entry.isFile()); |
| 170 value.setFile(entry.file()); | 170 value.setFile(entry.file()); |
| 171 } | 171 } |
| 172 results.append(value); | 172 results.append(value); |
| 173 } | 173 } |
| 174 return results; | 174 return results; |
| 175 } | 175 } |
| 176 | 176 |
| 177 bool DOMFormData::has(const String& name) | 177 bool FormData::has(const String& name) |
| 178 { | 178 { |
| 179 if (m_opaque) | 179 if (m_opaque) |
| 180 return false; | 180 return false; |
| 181 const CString keyData = encodeAndNormalize(name); | 181 const CString keyData = encodeAndNormalize(name); |
| 182 for (const Item& item : items()) { | 182 for (const Item& item : items()) { |
| 183 if (item.key() == keyData) | 183 if (item.key() == keyData) |
| 184 return true; | 184 return true; |
| 185 } | 185 } |
| 186 return false; | 186 return false; |
| 187 } | 187 } |
| 188 | 188 |
| 189 void DOMFormData::set(const String& name, const String& value) | 189 void FormData::set(const String& name, const String& value) |
| 190 { | 190 { |
| 191 setEntry(Item(encodeAndNormalize(name), encodeAndNormalize(value))); | 191 setEntry(Item(encodeAndNormalize(name), encodeAndNormalize(value))); |
| 192 } | 192 } |
| 193 | 193 |
| 194 void DOMFormData::set(const String& name, Blob* blob, const String& filename) | 194 void FormData::set(const String& name, Blob* blob, const String& filename) |
| 195 { | 195 { |
| 196 setEntry(Item(encodeAndNormalize(name), blob, filename)); | 196 setEntry(Item(encodeAndNormalize(name), blob, filename)); |
| 197 } | 197 } |
| 198 | 198 |
| 199 void DOMFormData::setEntry(const Item& item) | 199 void FormData::setEntry(const Item& item) |
| 200 { | 200 { |
| 201 const CString keyData = item.key(); | 201 const CString keyData = item.key(); |
| 202 bool found = false; | 202 bool found = false; |
| 203 size_t i = 0; | 203 size_t i = 0; |
| 204 while (i < m_items.size()) { | 204 while (i < m_items.size()) { |
| 205 if (m_items[i].key() != keyData) { | 205 if (m_items[i].key() != keyData) { |
| 206 ++i; | 206 ++i; |
| 207 } else if (found) { | 207 } else if (found) { |
| 208 m_items.remove(i); | 208 m_items.remove(i); |
| 209 } else { | 209 } else { |
| 210 found = true; | 210 found = true; |
| 211 m_items[i] = item; | 211 m_items[i] = item; |
| 212 ++i; | 212 ++i; |
| 213 } | 213 } |
| 214 } | 214 } |
| 215 if (!found) | 215 if (!found) |
| 216 m_items.append(item); | 216 m_items.append(item); |
| 217 return; | 217 return; |
| 218 } | 218 } |
| 219 | 219 |
| 220 String DOMFormData::decode(const CString& data) const | 220 String FormData::decode(const CString& data) const |
| 221 { | 221 { |
| 222 return encoding().decode(data.data(), data.length()); | 222 return encoding().decode(data.data(), data.length()); |
| 223 } | 223 } |
| 224 | 224 |
| 225 PairIterable<String, FormDataEntryValue>::IterationSource* DOMFormData::startIte
ration(ScriptState*, ExceptionState&) | 225 PairIterable<String, FormDataEntryValue>::IterationSource* FormData::startIterat
ion(ScriptState*, ExceptionState&) |
| 226 { | 226 { |
| 227 if (m_opaque) | 227 if (m_opaque) |
| 228 return new DOMFormDataIterationSource(new DOMFormData(nullptr)); | 228 return new FormDataIterationSource(new FormData(nullptr)); |
| 229 | 229 |
| 230 return new DOMFormDataIterationSource(this); | 230 return new FormDataIterationSource(this); |
| 231 } | 231 } |
| 232 | 232 |
| 233 } // namespace blink | 233 } // namespace blink |
| OLD | NEW |