PassRefPtr<FormData> FormData::decode(Decoder& decoder) { RefPtr<FormData> data = FormData::create(); if (!decoder.decodeBool(data->m_alwaysStream)) return 0; Vector<uint8_t> boundary; if (!decoder.decodeBytes(boundary)) return 0; size_t size = boundary.size(); data->m_boundary.resize(size); memcpy(data->m_boundary.data(), boundary.data(), size); uint64_t elementsSize; if (!decoder.decodeUInt64(elementsSize)) return 0; for (size_t i = 0; i < elementsSize; ++i) { FormDataElement element; if (!decodeElement(decoder, element)) return 0; data->m_elements.append(element); } bool dummy; if (!decoder.decodeBool(dummy)) return 0; if (!decoder.decodeInt64(data->m_identifier)) return 0; return data.release(); }
PassRefPtr<HistoryItem> HistoryItem::decodeBackForwardTree(const String& topURLString, const String& topTitle, const String& topOriginalURLString, Decoder& decoder) { // Since the data stream is not trusted, the decode has to be non-recursive. // We don't want bad data to cause a stack overflow. uint32_t version; if (!decoder.decodeUInt32(version)) return 0; if (version != backForwardTreeEncodingVersion) return 0; String urlString = topURLString; String title = topTitle; String originalURLString = topOriginalURLString; Vector<DecodeRecursionStackElement, 16> recursionStack; recurse: RefPtr<HistoryItem> node = create(urlString, title, 0); node->setOriginalURLString(originalURLString); title = String(); uint64_t size; if (!decoder.decodeUInt64(size)) return 0; size_t i; RefPtr<HistoryItem> child; for (i = 0; i < size; ++i) { if (!decoder.decodeString(originalURLString)) return 0; if (!decoder.decodeString(urlString)) return 0; recursionStack.append(DecodeRecursionStackElement(node.release(), i, size)); goto recurse; resume: node->m_children.append(child.release()); } if (!decoder.decodeInt64(node->m_documentSequenceNumber)) return 0; if (!decoder.decodeUInt64(size)) return 0; for (i = 0; i < size; ++i) { String state; if (!decoder.decodeString(state)) return 0; node->m_documentState.append(state); } if (!decoder.decodeString(node->m_formContentType)) return 0; bool hasFormData; if (!decoder.decodeBool(hasFormData)) return 0; if (hasFormData) { node->m_formData = FormData::decode(decoder); if (!node->m_formData) return 0; } if (!decoder.decodeInt64(node->m_itemSequenceNumber)) return 0; if (!decoder.decodeString(node->m_referrer)) return 0; int32_t x; if (!decoder.decodeInt32(x)) return 0; int32_t y; if (!decoder.decodeInt32(y)) return 0; node->m_scrollPoint = IntPoint(x, y); if (!decoder.decodeFloat(node->m_pageScaleFactor)) return 0; bool hasStateObject; if (!decoder.decodeBool(hasStateObject)) return 0; if (hasStateObject) { Vector<uint8_t> bytes; if (!decoder.decodeBytes(bytes)) return 0; node->m_stateObject = SerializedScriptValue::adopt(bytes); } if (!decoder.decodeString(node->m_target)) return 0; // Simulate recursion with our own stack. if (!recursionStack.isEmpty()) { DecodeRecursionStackElement& element = recursionStack.last(); child = node.release(); node = element.node.release(); i = element.i; size = element.size; recursionStack.removeLast(); goto resume; } return node.release(); }