示例#1
0
TEST(FormDataTest, has) {
    FormData* fd = FormData::create(UTF8Encoding());
    fd->append("name1", "value1");

    EXPECT_TRUE(fd->has("name1"));
    EXPECT_EQ(1u, fd->size());
}
示例#2
0
void ResourceRequest::doUpdatePlatformHTTPBody()
{
    CFMutableURLRequestRef cfRequest;

    RetainPtr<CFURLRef> url = ResourceRequest::url().createCFURL();
    RetainPtr<CFURLRef> firstPartyForCookies = ResourceRequest::firstPartyForCookies().createCFURL();
    if (m_cfRequest) {
        cfRequest = CFURLRequestCreateMutableCopy(0, m_cfRequest.get());
        CFURLRequestSetURL(cfRequest, url.get());
        CFURLRequestSetMainDocumentURL(cfRequest, firstPartyForCookies.get());
        CFURLRequestSetCachePolicy(cfRequest, (CFURLRequestCachePolicy)cachePolicy());
        CFURLRequestSetTimeoutInterval(cfRequest, timeoutInterval());
    } else
        cfRequest = CFURLRequestCreateMutable(0, url.get(), (CFURLRequestCachePolicy)cachePolicy(), timeoutInterval(), firstPartyForCookies.get());

    FormData* formData = httpBody();
    if (formData && !formData->isEmpty())
        WebCore::setHTTPBody(cfRequest, formData);

    if (RetainPtr<CFReadStreamRef> bodyStream = adoptCF(CFURLRequestCopyHTTPRequestBodyStream(cfRequest))) {
        // For streams, provide a Content-Length to avoid using chunked encoding, and to get accurate total length in callbacks.
        if (RetainPtr<CFStringRef> lengthString = adoptCF(static_cast<CFStringRef>(CFReadStreamCopyProperty(bodyStream.get(), formDataStreamLengthPropertyName())))) {
            CFURLRequestSetHTTPHeaderFieldValue(cfRequest, CFSTR("Content-Length"), lengthString.get());
            // Since resource request is already marked updated, we need to keep it up to date too.
            ASSERT(m_resourceRequestUpdated);
            m_httpHeaderFields.set(HTTPHeaderName::ContentLength, lengthString.get());
        }
    }

    m_cfRequest = adoptCF(cfRequest);
#if PLATFORM(COCOA)
    clearOrUpdateNSURLRequest();
#endif
}
示例#3
0
void HiddenInputType::appendToFormData(FormData& formData) const
{
    if (equalIgnoringCase(element().name(), "_charset_")) {
        formData.append(element().name(), String(formData.encoding().name()));
        return;
    }
    InputType::appendToFormData(formData);
}
示例#4
0
// This static method is called to check to see if a POST response is in
// the cache.
bool ResourceHandle::willLoadFromCache(ResourceRequest& request, Frame*)
{
    // set the cache policy correctly, copied from
    // network/mac/ResourceHandleMac.mm
    request.setCachePolicy(ReturnCacheDataDontLoad);
    FormData* formData = request.httpBody();
    return ResourceLoaderAndroid::willLoadFromCache(request.url(), formData ? formData->identifier() : 0);
}
// https://w3c.github.io/webappsec-credential-management/#passwordcredential-form-constructor
PasswordCredential* PasswordCredential::create(HTMLFormElement* form, ExceptionState& exceptionState)
{
    // Extract data from the form, then use the extracted |formData| object's
    // value to populate |data|.
    FormData* formData = FormData::create(form);
    PasswordCredentialData data;

    AtomicString idName;
    AtomicString passwordName;
    for (FormAssociatedElement* element : form->associatedElements()) {
        // If |element| isn't a "submittable element" with string data, then it
        // won't have a matching value in |formData|, and we can safely skip it.
        FileOrUSVString result;
        formData->get(element->name(), result);
        if (!result.isUSVString())
            continue;

        AtomicString autocomplete = toHTMLElement(element)->fastGetAttribute(HTMLNames::autocompleteAttr);
        if (equalIgnoringCase(autocomplete, "current-password") || equalIgnoringCase(autocomplete, "new-password")) {
            data.setPassword(result.getAsUSVString());
            passwordName = element->name();
        } else if (equalIgnoringCase(autocomplete, "photo")) {
            data.setIconURL(result.getAsUSVString());
        } else if (equalIgnoringCase(autocomplete, "name") || equalIgnoringCase(autocomplete, "nickname")) {
            data.setName(result.getAsUSVString());
        } else if (equalIgnoringCase(autocomplete, "username")) {
            data.setId(result.getAsUSVString());
            idName = element->name();
        }
    }

    // Create a PasswordCredential using the data gathered above.
    PasswordCredential* credential = PasswordCredential::create(data, exceptionState);
    if (exceptionState.hadException())
        return nullptr;
    ASSERT(credential);

    // After creating the Credential, populate its 'additionalData', 'idName', and 'passwordName' attributes.
    // If the form's 'enctype' is anything other than multipart, generate a URLSearchParams using the
    // data in |formData|.
    credential->setIdName(idName);
    credential->setPasswordName(passwordName);

    FormDataOrURLSearchParams additionalData;
    if (form->enctype() == "multipart/form-data") {
        additionalData.setFormData(formData);
    } else {
        URLSearchParams* params = URLSearchParams::create(URLSearchParamsInit());
        for (const FormData::Entry* entry : formData->entries()) {
            if (entry->isString())
                params->append(entry->name().data(), entry->value().data());
        }
        additionalData.setURLSearchParams(params);
    }

    credential->setAdditionalData(additionalData);
    return credential;
}
示例#6
0
void XSSAuditor::init()
{
    const size_t miniumLengthForSuffixTree = 512; // FIXME: Tune this parameter.
    const int suffixTreeDepth = 5;

    ASSERT(m_state == Uninitialized);
    m_state = Initial;

    if (!m_isEnabled)
        return;

    // In theory, the Document could have detached from the Frame after the
    // XSSAuditor was constructed.
    if (!m_parser->document()->frame()) {
        m_isEnabled = false;
        return;
    }

    const KURL& url = m_parser->document()->url();

    if (url.isEmpty()) {
        // The URL can be empty when opening a new browser window or calling window.open("").
        m_isEnabled = false;
        return;
    }

    if (url.protocolIsData()) {
        m_isEnabled = false;
        return;
    }

    TextResourceDecoder* decoder = m_parser->document()->decoder();
    m_decodedURL = fullyDecodeString(url.string(), decoder);
    if (m_decodedURL.find(isRequiredForInjection, 0) == notFound)
        m_decodedURL = String();

    if (DocumentLoader* documentLoader = m_parser->document()->frame()->loader()->documentLoader()) {
        DEFINE_STATIC_LOCAL(String, XSSProtectionHeader, ("X-XSS-Protection"));
        m_xssProtection = parseXSSProtectionHeader(documentLoader->response().httpHeaderField(XSSProtectionHeader));

        FormData* httpBody = documentLoader->originalRequest().httpBody();
        if (httpBody && !httpBody->isEmpty()) {
            String httpBodyAsString = httpBody->flattenToString();
            if (!httpBodyAsString.isEmpty()) {
                m_decodedHTTPBody = fullyDecodeString(httpBodyAsString, decoder);
                if (m_decodedHTTPBody.find(isRequiredForInjection, 0) == notFound)
                    m_decodedHTTPBody = String();
                if (m_decodedHTTPBody.length() >= miniumLengthForSuffixTree)
                    m_decodedHTTPBodySuffixTree = adoptPtr(new SuffixTree<ASCIICodebook>(m_decodedHTTPBody, suffixTreeDepth));
            }
        }
    }

    if (m_decodedURL.isEmpty() && m_decodedHTTPBody.isEmpty())
        m_isEnabled = false;
}
示例#7
0
  /**
   * Test a POST form transfer
   */
  static void TestNetworkPostTransfer()
  {
    // FIXME Setup a http server to serve the files
    TestManager::AssertTrue("No web server setup for the tests", false);
    return;
    
    const std::string aURL(TEST_WEB_SITE"testpostwithparam.php");
    std::string aPath = TestManager::GetInstance().getPath() + "NetworkTests/Refs/testpostwithparam.html";
    const std::string aRef(aPath);

    BIResourceHandleManager* aResourceHandleManager = getBIResourceHandleManager();
    TestManager::AssertTrue("Transfer Job Manager obtained", aResourceHandleManager != NULL);

    std::string aFileName;
    GetTemporaryUnexistingFileName("/tmp/transfer", ".txt", aFileName);

    TestResourceHandleClient aTestResourceHandleClient(aFileName);

    FormData formData;
    DeprecatedString aParams;
    aParams = "param1=toto&param2=kiki";
    formData.appendData( static_cast<const void *> (aParams.ascii()), aParams.length() );

    ResourceRequest aResourceRequest = ResourceRequest(static_cast<const KURL&> (aURL.c_str()));
    aResourceRequest.setHTTPMethod("POST");
    aResourceRequest.setHTTPReferrer(TEST_WEB_SITE);
    aResourceRequest.setHTTPBody(formData.copy());;

    RefPtr<BIResourceHandle> aResourceHandle = BIResourceHandle::create(aResourceRequest, &aTestResourceHandleClient, 0, false, false, false);

    TestManager::AssertTrue("FormData flatten", aResourceRequest.httpBody()->flattenToString() == "param1=toto&param2=kiki" );
    TestManager::AssertTrue("Form data with correct element", aResourceRequest.httpBody()->elements().size() == 1 );
    TestManager::AssertTrue("Correct Metadata", aResourceRequest.httpReferrer() == TEST_WEB_SITE );
    TestManager::AssertTrue("Correct Method", aResourceHandle->method() == "POST");

    gTransferFileCount = 1;

    // Wait for the end of the transfer.
    gTimeout = false;
    WebCore::Timer<NetworkTest> aTimeoutTimer(NULL,&NetworkTest::TimeoutCallback);
    aTimeoutTimer.startOneShot(20); // timeout in 20s

    BIEventLoop* aEventLoop = BAL::getBIEventLoop();
    BIEvent* event;
    while( gTransferFileCount && !gTimeout ) {
      aEventLoop->WaitEvent(event);
    }

    TestManager::AssertTrue("Transfer done", !gTransferFileCount );
    BALFileComparison aFileComparison;
    bool bEqual = aFileComparison.AreEqual( aFileName, aRef );
    TestManager::AssertTrue("File as expected", bEqual );

    unlink( aFileName.c_str() );
  }
示例#8
0
TEST(FormDataTest, getAll) {
    FormData* fd = FormData::create(UTF8Encoding());
    fd->append("name1", "value1");

    HeapVector<FormDataEntryValue> results = fd->getAll("name1");
    EXPECT_EQ(1u, results.size());
    EXPECT_TRUE(results[0].isUSVString());
    EXPECT_EQ("value1", results[0].getAsUSVString());

    EXPECT_EQ(1u, fd->size());
}
示例#9
0
void FileInputType::appendToFormData(FormData& formData) const {
  FileList* fileList = element().files();
  unsigned numFiles = fileList->length();
  if (numFiles == 0) {
    formData.append(element().name(), File::create(""));
    return;
  }

  for (unsigned i = 0; i < numFiles; ++i)
    formData.append(element().name(), fileList->item(i));
}
示例#10
0
TEST(FormDataTest, get) {
    FormData* fd = FormData::create(UTF8Encoding());
    fd->append("name1", "value1");

    FileOrUSVString result;
    fd->get("name1", result);
    EXPECT_TRUE(result.isUSVString());
    EXPECT_EQ("value1", result.getAsUSVString());

    const FormData::Entry& entry = *fd->entries()[0];
    EXPECT_STREQ("name1", entry.name().data());
    EXPECT_STREQ("value1", entry.value().data());
}
bool ResourceHandle::startHttp(String urlString)
{
    if (!session) {
        session = soup_session_async_new();

        soup_session_add_feature(session, SOUP_SESSION_FEATURE(getCookieJar()));

        const char* soup_debug = g_getenv("WEBKIT_SOUP_LOGGING");
        if (soup_debug) {
            int soup_debug_level = atoi(soup_debug);

            SoupLogger* logger = soup_logger_new(static_cast<SoupLoggerLogLevel>(soup_debug_level), -1);
            soup_logger_attach(logger, session);
            g_object_unref(logger);
        }
    }

    SoupMessage* msg;
    msg = soup_message_new(request().httpMethod().utf8().data(), urlString.utf8().data());
    g_signal_connect(msg, "restarted", G_CALLBACK(restartedCallback), this);

    g_signal_connect(msg, "got-headers", G_CALLBACK(gotHeadersCallback), this);
    g_signal_connect(msg, "got-chunk", G_CALLBACK(gotChunkCallback), this);

    HTTPHeaderMap customHeaders = d->m_request.httpHeaderFields();
    if (!customHeaders.isEmpty()) {
        HTTPHeaderMap::const_iterator end = customHeaders.end();
        for (HTTPHeaderMap::const_iterator it = customHeaders.begin(); it != end; ++it)
            soup_message_headers_append(msg->request_headers, it->first.utf8().data(), it->second.utf8().data());
    }

    FormData* httpBody = d->m_request.httpBody();
    if (httpBody && !httpBody->isEmpty()) {
        // Making a copy of the request body isn't the most efficient way to
        // serialize it, but by far the most simple. Dealing with individual
        // FormData elements and shared buffers should be more memory
        // efficient.
        //
        // This possibly isn't handling file uploads/attachments, for which
        // shared buffers or streaming should definitely be used.
        Vector<char> body;
        httpBody->flatten(body);
        soup_message_set_request(msg, d->m_request.httpContentType().utf8().data(),
                                 SOUP_MEMORY_COPY, body.data(), body.size());
    }

    d->m_msg = static_cast<SoupMessage*>(g_object_ref(msg));
    soup_session_queue_message(session, d->m_msg, finishedCallback, this);

    return true;
}
示例#12
0
void HTMLTextAreaElement::appendToFormData(FormData& formData) {
  if (name().isEmpty())
    return;

  document().updateStyleAndLayout();

  const String& text =
      (m_wrap == HardWrap) ? valueWithHardLineBreaks() : value();
  formData.append(name(), text);

  const AtomicString& dirnameAttrValue = fastGetAttribute(dirnameAttr);
  if (!dirnameAttrValue.isNull())
    formData.append(dirnameAttrValue, directionForFormData());
}
示例#13
0
static HTTPBody toHTTPBody(const FormData& formData)
{
    HTTPBody httpBody;

    for (const auto& formDataElement : formData.elements()) {
        HTTPBody::Element element;

        switch (formDataElement.m_type) {
        case FormDataElement::Type::Data:
            element.type = HTTPBody::Element::Type::Data;
            element.data = formDataElement.m_data;
            break;

        case FormDataElement::Type::EncodedFile:
            element.filePath = formDataElement.m_filename;
            element.fileStart = formDataElement.m_fileStart;
            if (formDataElement.m_fileLength != BlobDataItem::toEndOfFile)
                element.fileLength = formDataElement.m_fileLength;
            if (formDataElement.m_expectedFileModificationTime != invalidFileTime())
                element.expectedFileModificationTime = formDataElement.m_expectedFileModificationTime;
            break;

        case FormDataElement::Type::EncodedBlob:
            element.blobURLString = formDataElement.m_url.string();
            break;
        }

        httpBody.elements.append(WTF::move(element));
    }

    return httpBody;
}
示例#14
0
void TextFieldInputType::appendToFormData(FormData& formData) const {
  InputType::appendToFormData(formData);
  const AtomicString& dirnameAttrValue =
      element().fastGetAttribute(dirnameAttr);
  if (!dirnameAttrValue.isNull())
    formData.append(dirnameAttrValue, element().directionForFormData());
}
ResourceRequest ResourceHandleCFURLConnectionDelegate::createResourceRequest(CFURLRequestRef cfRequest, CFURLResponseRef redirectResponse)
{
    ResourceRequest request;
    CFHTTPMessageRef httpMessage = CFURLResponseGetHTTPResponse(redirectResponse);
    if (httpMessage && CFHTTPMessageGetResponseStatusCode(httpMessage) == 307) {
        RetainPtr<CFStringRef> lastHTTPMethod = m_handle->lastHTTPMethod().createCFString();
        RetainPtr<CFStringRef> newMethod = adoptCF(CFURLRequestCopyHTTPRequestMethod(cfRequest));
        if (CFStringCompareWithOptions(lastHTTPMethod.get(), newMethod.get(), CFRangeMake(0, CFStringGetLength(lastHTTPMethod.get())), kCFCompareCaseInsensitive)) {
            RetainPtr<CFMutableURLRequestRef> mutableRequest = adoptCF(CFURLRequestCreateMutableCopy(0, cfRequest));
            wkSetRequestStorageSession(m_handle->storageSession(), mutableRequest.get());
            CFURLRequestSetHTTPRequestMethod(mutableRequest.get(), lastHTTPMethod.get());

            FormData* body = m_handle->firstRequest().httpBody();
            if (!equalIgnoringCase(m_handle->firstRequest().httpMethod(), "GET") && body && !body->isEmpty())
                WebCore::setHTTPBody(mutableRequest.get(), body);

            String originalContentType = m_handle->firstRequest().httpContentType();
            if (!originalContentType.isEmpty())
                CFURLRequestSetHTTPHeaderFieldValue(mutableRequest.get(), CFSTR("Content-Type"), originalContentType.createCFString().get());

            request = mutableRequest.get();
        }
    }

    if (request.isNull())
        request = cfRequest;

    if (!request.url().protocolIs("https") && protocolIs(request.httpReferrer(), "https") && m_handle->context()->shouldClearReferrerOnHTTPSToHTTPRedirect())
        request.clearHTTPReferrer();
    return request;
}
void ArgumentCoder<ResourceRequest>::encode(ArgumentEncoder* encoder, const ResourceRequest& resourceRequest)
{
    encoder->encode(resourceRequest.url().string());
    encoder->encode(resourceRequest.httpMethod());

    const HTTPHeaderMap& headers = resourceRequest.httpHeaderFields();
    encoder->encode(headers);

    FormData* httpBody = resourceRequest.httpBody();
    encoder->encode(static_cast<bool>(httpBody));
    if (httpBody)
        encoder->encode(httpBody->flattenToString());

    encoder->encode(resourceRequest.firstPartyForCookies().string());
    encoder->encode(static_cast<uint32_t>(resourceRequest.soupMessageFlags()));
}
static CFURLRequestRef willSendRequest(CFURLConnectionRef conn, CFURLRequestRef cfRequest, CFURLResponseRef cfRedirectResponse, const void* clientInfo)
{
#if LOG_DISABLED
    UNUSED_PARAM(conn);
#endif
    ResourceHandle* handle = static_cast<ResourceHandle*>(const_cast<void*>(clientInfo));

    if (!cfRedirectResponse) {
        CFRetain(cfRequest);
        return cfRequest;
    }

    LOG(Network, "CFNet - willSendRequest(conn=%p, handle=%p) (%s)", conn, handle, handle->firstRequest().url().string().utf8().data());

    ResourceRequest request;
    if (cfRedirectResponse) {
        CFHTTPMessageRef httpMessage = CFURLResponseGetHTTPResponse(cfRedirectResponse);
        if (httpMessage && CFHTTPMessageGetResponseStatusCode(httpMessage) == 307) {
            RetainPtr<CFStringRef> lastHTTPMethod(AdoptCF, handle->lastHTTPMethod().createCFString());
            RetainPtr<CFStringRef> newMethod(AdoptCF, CFURLRequestCopyHTTPRequestMethod(cfRequest));
            if (CFStringCompareWithOptions(lastHTTPMethod.get(), newMethod.get(), CFRangeMake(0, CFStringGetLength(lastHTTPMethod.get())), kCFCompareCaseInsensitive)) {
                RetainPtr<CFMutableURLRequestRef> mutableRequest(AdoptCF, CFURLRequestCreateMutableCopy(0, cfRequest));
#if USE(CFURLSTORAGESESSIONS)
                wkSetRequestStorageSession(ResourceHandle::currentStorageSession(), mutableRequest.get());
#endif
                CFURLRequestSetHTTPRequestMethod(mutableRequest.get(), lastHTTPMethod.get());

                FormData* body = handle->firstRequest().httpBody();
                if (!equalIgnoringCase(handle->firstRequest().httpMethod(), "GET") && body && !body->isEmpty())
                    WebCore::setHTTPBody(mutableRequest.get(), body);

                String originalContentType = handle->firstRequest().httpContentType();
                RetainPtr<CFStringRef> originalContentTypeCF(AdoptCF, originalContentType.createCFString());
                if (!originalContentType.isEmpty())
                    CFURLRequestSetHTTPHeaderFieldValue(mutableRequest.get(), CFSTR("Content-Type"), originalContentTypeCF.get());

                request = mutableRequest.get();
            }
        }
    }
    if (request.isNull())
        request = cfRequest;

    // Should not set Referer after a redirect from a secure resource to non-secure one.
    if (!request.url().protocolIs("https") && protocolIs(request.httpReferrer(), "https"))
        request.clearHTTPReferrer();

    handle->willSendRequest(request, cfRedirectResponse);

    if (request.isNull())
        return 0;

    cfRequest = request.cfURLRequest();

    CFRetain(cfRequest);
    return cfRequest;
}
示例#18
0
PassRefPtr<EncodedFormData> PasswordCredential::encodeFormData(
    String& contentType) const {
  if (m_additionalData.isURLSearchParams()) {
    // If |additionalData| is a 'URLSearchParams' object, build a urlencoded
    // response.
    URLSearchParams* params = URLSearchParams::create(URLSearchParamsInit());
    URLSearchParams* additionalData = m_additionalData.getAsURLSearchParams();
    for (const auto& param : additionalData->params()) {
      const String& name = param.first;
      if (name != idName() && name != passwordName())
        params->append(name, param.second);
    }
    params->append(idName(), id());
    params->append(passwordName(), password());

    contentType =
        AtomicString("application/x-www-form-urlencoded;charset=UTF-8");

    return params->toEncodedFormData();
  }

  // Otherwise, we'll build a multipart response.
  FormData* formData = FormData::create(nullptr);
  if (m_additionalData.isFormData()) {
    FormData* additionalData = m_additionalData.getAsFormData();
    for (const FormData::Entry* entry : additionalData->entries()) {
      const String& name = formData->decode(entry->name());
      if (name == idName() || name == passwordName())
        continue;

      if (entry->blob())
        formData->append(name, entry->blob(), entry->filename());
      else
        formData->append(name, formData->decode(entry->value()));
    }
  }
  formData->append(idName(), id());
  formData->append(passwordName(), password());

  RefPtr<EncodedFormData> encodedData = formData->encodeMultiPartFormData();
  contentType = AtomicString("multipart/form-data; boundary=") +
                encodedData->boundary().data();
  return encodedData.release();
}
示例#19
0
void ArgumentCoder<ResourceRequest>::encode(ArgumentEncoder* encoder, const ResourceRequest& resourceRequest)
{
    if (kShouldSerializeWebCoreData) {
        encoder->encode(resourceRequest.url().string());
        encoder->encode(resourceRequest.httpMethod());

        const HTTPHeaderMap& headers = resourceRequest.httpHeaderFields();
        encoder->encode(headers);

        FormData* httpBody = resourceRequest.httpBody();
        encoder->encode(static_cast<bool>(httpBody));
        if (httpBody)
            encoder->encode(httpBody->flattenToString());

        encoder->encode(resourceRequest.firstPartyForCookies().string());
    }

    encodePlatformData(encoder, resourceRequest);
}
CFArrayRef arrayFromFormData(const FormData& d)
{
    size_t size = d.elements().size();
    CFMutableArrayRef a = CFArrayCreateMutable(0, d.elements().size(), &kCFTypeArrayCallBacks);
    for (size_t i = 0; i < size; ++i) {
        const FormDataElement& e = d.elements()[i];
        if (e.m_type == FormDataElement::data) {
            CFDataRef data = CFDataCreate(0, (const UInt8*)e.m_data.data(), e.m_data.size());
            CFArrayAppendValue(a, data);
            CFRelease(data);
        } else {
            ASSERT(e.m_type == FormDataElement::encodedFile);
            CFStringRef filename = e.m_filename.createCFString();
            CFArrayAppendValue(a, filename);
            CFRelease(filename);
        }
    }
    return a;
}
示例#21
0
void ArgumentCoder<ResourceRequest>::encodePlatformData(ArgumentEncoder& encoder, const ResourceRequest& resourceRequest)
{
    encoder << resourceRequest.url().string();
    encoder << resourceRequest.httpMethod();
    encoder << resourceRequest.httpHeaderFields();

    // FIXME: Do not encode HTTP message body.
    // 1. It can be large and thus costly to send across.
    // 2. It is misleading to provide a body with some requests, while others use body streams, which cannot be serialized at all.
    FormData* httpBody = resourceRequest.httpBody();
    encoder << static_cast<bool>(httpBody);
    if (httpBody)
        encoder << httpBody->flattenToString();

    encoder << resourceRequest.firstPartyForCookies().string();

    encoder << static_cast<uint32_t>(resourceRequest.soupMessageFlags());
    encoder << resourceRequest.initiatingPageID();
}
示例#22
0
void HTMLObjectElement::appendToFormData(FormData& formData)
{
    if (name().isEmpty())
        return;

    Widget* widget = pluginWidget();
    if (!widget || !widget->isPluginView())
        return;
    String value;
    if (toPluginView(widget)->getFormValue(value))
        formData.append(name(), value);
}
示例#23
0
void HTMLKeygenElement::appendToFormData(FormData& formData) {
  // Only RSA is supported at this time.
  const AtomicString& keyType = fastGetAttribute(keytypeAttr);
  if (!keyType.isNull() && !equalIgnoringCase(keyType, "rsa"))
    return;
  SecurityOrigin* topOrigin =
      document().frame()->tree().top()->securityContext()->getSecurityOrigin();
  String value = Platform::current()->signedPublicKeyAndChallengeString(
      shadowSelect()->selectedIndex(), fastGetAttribute(challengeAttr),
      document().baseURL(), KURL(KURL(), topOrigin->toString()));
  if (!value.isNull())
    formData.append(name(), value);
}
示例#24
0
static void* formCreate(CFReadStreamRef stream, void* context)
{
    FormData* formData = static_cast<FormData*>(context);

    CFSetCallBacks runLoopAndModeCallBacks = { 0, pairRetain, pairRelease, NULL, pairEqual, pairHash };

    FormStreamFields* newInfo = new FormStreamFields;
    newInfo->scheduledRunLoopPairs = CFSetCreateMutable(0, 0, &runLoopAndModeCallBacks);
    newInfo->currentStream = NULL;
    newInfo->currentData = 0;
    newInfo->formStream = stream; // Don't retain. That would create a reference cycle.

    // Append in reverse order since we remove elements from the end.
    size_t size = formData->elements().size();
    newInfo->remainingElements.reserveCapacity(size);
    for (size_t i = 0; i < size; ++i)
        newInfo->remainingElements.append(formData->elements()[size - i - 1]);

    getStreamFormDatas().set(stream, adoptRef(formData));

    return newInfo;
}
示例#25
0
void ArgumentCoder<ResourceRequest>::encode(ArgumentEncoder& encoder, const ResourceRequest& resourceRequest)
{
    if (kShouldSerializeWebCoreData) {
        encoder << resourceRequest.url().string();
        encoder << resourceRequest.httpMethod();
        encoder << resourceRequest.httpHeaderFields();

        // FIXME: Do not encode HTTP message body.
        // 1. It can be large and thus costly to send across.
        // 2. It is misleading to provide a body with some requests, while others use body streams, which cannot be serialized at all.
        FormData* httpBody = resourceRequest.httpBody();
        encoder << static_cast<bool>(httpBody);
        if (httpBody)
            encoder << httpBody->flattenToString();

        encoder << resourceRequest.firstPartyForCookies().string();
    }

#if ENABLE(CACHE_PARTITIONING)
    encoder << resourceRequest.cachePartition();
#endif

    encodePlatformData(encoder, resourceRequest);
}
示例#26
0
static void appendMailtoPostFormDataToURL(KURL& 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.replaceWithLiteral('&', "\r\n").replace('+', ' ') + "\r\n");
    }

    Vector<char> bodyData;
    bodyData.append("body=", 5);
    FormDataBuilder::encodeStringAsFormData(bodyData, body.utf8());
    body = String(bodyData.data(), bodyData.size()).replaceWithLiteral('+', "%20");

    String query = url.query();
    if (!query.isEmpty())
        query.append('&');
    query.append(body);
    url.setQuery(query);
}
示例#27
0
bool XSSAuditor::findInRequest(Frame* frame, const FindTask& task) const
{
    ASSERT(frame->document());

    if (!frame->document()->decoder()) {
        // Note, JavaScript URLs do not have a charset.
        return false;
    }

    if (task.string.isEmpty())
        return false;

    DocumentLoader *documentLoader = frame->loader()->documentLoader();
    if (!documentLoader)
        return false;

    FormData* formDataObj = documentLoader->originalRequest().httpBody();
    const bool hasFormData = formDataObj && !formDataObj->isEmpty();
    String pageURL = frame->document()->url().string();

    if (!hasFormData) {
        // We clear out our form data caches, in case we're holding onto a bunch of memory.
        m_formDataCache.clear();
        m_formDataSuffixTree.clear();
    }

    String canonicalizedString;
    if (!hasFormData && task.string.length() > 2 * pageURL.length()) {
        // Q: Why do we bother to do this check at all?
        // A: Canonicalizing large inline scripts can be expensive.  We want to
        //    reduce the size of the string before we call canonicalize below,
        //    since it could result in an unneeded allocation and memcpy.
        //
        // Q: Why do we multiply by two here?
        // A: We attempt to detect reflected XSS even when the server
        //    transforms the attacker's input with addSlashes.  The best the
        //    attacker can do get the server to inflate his/her input by a
        //    factor of two by sending " characters, which the server
        //    transforms to \".
        canonicalizedString = task.string.substring(0, 2 * pageURL.length());
    } else
        canonicalizedString = task.string;

    if (frame->document()->url().protocolIs("data"))
        return false;

    canonicalizedString = canonicalize(canonicalizedString);
    if (canonicalizedString.isEmpty())
        return false;

    if (!task.context.isEmpty())
        canonicalizedString = task.context + canonicalizedString;

    String decodedPageURL = m_pageURLCache.canonicalizeURL(pageURL, frame->document()->decoder()->encoding(), task.decodeEntities, task.decodeURLEscapeSequencesTwice);

    if (task.allowRequestIfNoIllegalURICharacters && !hasFormData && decodedPageURL.find(&isIllegalURICharacter, 0) == -1)
        return false; // Injection is impossible because the request does not contain any illegal URI characters.

    if (decodedPageURL.find(canonicalizedString, 0, false) != -1)
        return true; // We've found the string in the GET data.

    if (hasFormData) {
        String decodedFormData = m_formDataCache.canonicalizeURL(formDataObj, frame->document()->decoder()->encoding(), task.decodeEntities, task.decodeURLEscapeSequencesTwice);

        if (m_generationOfSuffixTree != m_formDataCache.generation()) {
            m_formDataSuffixTree = new SuffixTree<ASCIICodebook>(decodedFormData, 5);
            m_generationOfSuffixTree = m_formDataCache.generation();
        }

        // Try a fast-reject via the suffixTree.
        if (m_formDataSuffixTree && !m_formDataSuffixTree->mightContain(canonicalizedString))
            return false;

        if (decodedFormData.find(canonicalizedString, 0, false) != -1)
            return true; // We found the string in the POST data.
    }

    return false;
}
示例#28
0
void SubmitInputType::appendToFormData(FormData& formData) const {
  if (element().isActivatedSubmit())
    formData.append(element().name(), element().valueOrDefaultLabel());
}
示例#29
0
void InputType::appendToFormData(FormData& formData) const
{
    formData.append(element().name(), element().value());
}
示例#30
0
bool HTMLFormElement::formData(FormData &form_data) const
{
    DeprecatedCString enc_string = ""; // used for non-multipart data

    DeprecatedString str = m_acceptcharset.deprecatedString();
    str.replace(',', ' ');
    DeprecatedStringList charsets = DeprecatedStringList::split(' ', str);
    TextEncoding encoding(InvalidEncoding);
    Frame *frame = document()->frame();
    for (DeprecatedStringList::Iterator it = charsets.begin(); it != charsets.end(); ++it) {
        if ((encoding = TextEncoding((*it).latin1())).isValid())
            break;
    }

    if (!encoding.isValid()) {
        if (frame)
            encoding = TextEncoding(frame->encoding().latin1());
        else
            encoding = TextEncoding(Latin1Encoding);
    }

    for (unsigned i = 0; i < formElements.size(); ++i) {
        HTMLGenericFormElement* current = formElements[i];
        FormDataList lst(encoding);

        if (!current->disabled() && current->appendFormData(lst, m_multipart)) {
            for (DeprecatedValueListConstIterator<FormDataListItem> it = lst.begin(); it != lst.end(); ++it) {
                if (!m_multipart) {
                    // handle ISINDEX / <input name=isindex> special
                    // but only if its the first entry
                    if ( enc_string.isEmpty() && (*it).m_data == "isindex" ) {
                        ++it;
                        enc_string += encodeCString( (*it).m_data );
                    }
                    else {
                        if(!enc_string.isEmpty())
                            enc_string += '&';

                        enc_string += encodeCString((*it).m_data);
                        enc_string += "=";
                        ++it;
                        enc_string += encodeCString((*it).m_data);
                    }
                }
                else
                {
                    DeprecatedCString hstr("--");
                    hstr += m_boundary.deprecatedString().latin1();
                    hstr += "\r\n";
                    hstr += "Content-Disposition: form-data; name=\"";
                    hstr += (*it).m_data.data();
                    hstr += "\"";

                    // if the current type is FILE, then we also need to
                    // include the filename
                    if (current->hasLocalName(inputTag) &&
                        static_cast<HTMLInputElement*>(current)->inputType() == HTMLInputElement::FILE) {
                        DeprecatedString path = static_cast<HTMLInputElement*>(current)->value().deprecatedString();

                        // FIXME: This won't work if the filename includes a " mark,
                        // or control characters like CR or LF. This also does strange
                        // things if the filename includes characters you can't encode
                        // in the website's character set.
                        hstr += "; filename=\"";
                        hstr += encoding.fromUnicode(path.mid(path.findRev('/') + 1), true);
                        hstr += "\"";

                        if (!static_cast<HTMLInputElement*>(current)->value().isEmpty()) {
                            DeprecatedString mimeType = frame ? frame->mimeTypeForFileName(path).deprecatedString() : DeprecatedString();
                            if (!mimeType.isEmpty()) {
                                hstr += "\r\nContent-Type: ";
                                hstr += mimeType.ascii();
                            }
                        }
                    }

                    hstr += "\r\n\r\n";
                    ++it;

                    // append body
                    form_data.appendData(hstr.data(), hstr.length());
                    const FormDataListItem &item = *it;
                    size_t dataSize = item.m_data.size();
                    if (dataSize != 0)
                        form_data.appendData(item.m_data, dataSize - 1);
                    else if (!item.m_path.isEmpty())
                        form_data.appendFile(item.m_path);
                    form_data.appendData("\r\n", 2);
                }
            }
        }
    }


    if (m_multipart)
        enc_string = ("--" + m_boundary.deprecatedString() + "--\r\n").ascii();

    form_data.appendData(enc_string.data(), enc_string.length());
    return true;
}