void TestKeePass2Format::initTestCase()
{
    QVERIFY(Crypto::init());

    // read raw XML database
    bool hasError;
    QString errorString;
    m_xmlDb = readXml(QString(KEEPASSX_TEST_DATA_DIR).append("/NewDatabase.xml"), true, hasError, errorString);
    if (hasError) {
        QFAIL(qPrintable(QString("Error while reading XML: ").append(errorString)));
    }
    QVERIFY(m_xmlDb.data());

    // construct and write KDBX to buffer
    auto key = QSharedPointer<CompositeKey>::create();
    key->addKey(QSharedPointer<PasswordKey>::create("test"));

    m_kdbxSourceDb = QSharedPointer<Database>::create();
    m_kdbxSourceDb->setKey(key);
    m_kdbxSourceDb->metadata()->setName("TESTDB");
    Group* group = m_kdbxSourceDb->rootGroup();
    group->setUuid(QUuid::createUuid());
    group->setNotes("I'm a note!");
    auto entry = new Entry();
    entry->setPassword(QString::fromUtf8("\xc3\xa4\xa3\xb6\xc3\xbc\xe9\x9b\xbb\xe7\xb4\x85"));
    entry->setUuid(QUuid::createUuid());
    entry->attributes()->set("test", "protectedTest", true);
    QVERIFY(entry->attributes()->isProtected("test"));
    entry->attachments()->set("myattach.txt", QByteArray("this is an attachment"));
    entry->attachments()->set("aaa.txt", QByteArray("also an attachment"));
    entry->setGroup(group);
    auto groupNew = new Group();
    groupNew->setUuid(QUuid::createUuid());
    groupNew->setName("TESTGROUP");
    groupNew->setNotes("I'm a sub group note!");
    groupNew->setParent(group);

    m_kdbxTargetBuffer.open(QBuffer::ReadWrite);
    writeKdbx(&m_kdbxTargetBuffer, m_kdbxSourceDb.data(), hasError, errorString);
    if (hasError) {
        QFAIL(qPrintable(QString("Error while writing database: ").append(errorString)));
    }

    // call sub class init method
    initTestCaseImpl();
}
Ejemplo n.º 2
0
void Attachments::remove()
{
  QListWidgetItem *listItem = attList->currentItem();
  if( !listItem || !item ) return;

  delete listItem;

  item->setAttachments( attachments() );
}
Ejemplo n.º 3
0
QVariant NewsFeedModel::data(const QModelIndex &index, int role) const
{
    int row = index.row();

    auto news = m_newsList.at(row);
    switch (role) {
    case TypeRole:
        return news.type();
    case PostIdRole:
        return news.postId();
        break;
    case SourceRole: {
        int source = news.sourceId();
        return qVariantFromValue(findContact(source));
    }
    case DateRole:
        return news.date();
    case BodyRole:
        return news.body();
    case AttachmentsRole:
        return vk::Attachment::toVariantMap(news.attachments());
    case LikesRole:
        return news.likes();
    case RepostsRole:
        return news.reposts();
    case CommentsRole:
        return news.property("comments");
    case OwnerNameRole: {
        int ownerId = news.property("copy_owner_id").toInt();
        if (ownerId) {
            auto contact = findContact(ownerId);
            return contact->name();
        }
        return QVariant();
    }
    case SourcePhotoRole: {
        if (auto contact = findContact(news.sourceId()))
            return contact->photoSource();
        break;
    }
    case SourceNameRole: {
        if (auto contact = findContact(news.sourceId()))
            return contact->name();
        break;
    }
    case LikesCount: {
        return news.likes().value("count").toInt();
    }
    case CommentsCount:
        return news.property("comments").toMap().value("count").toInt();
    default:
        break;
    }
    return QVariant::Invalid;
}
Ejemplo n.º 4
0
nsresult nsEudoraCompose::GetLocalAttachments(nsIArray **aArray)
{
  /*
  nsIURI      *url = nullptr;
  */
  nsresult rv;
  nsCOMPtr<nsIMutableArray> attachments (do_CreateInstance(NS_ARRAY_CONTRACTID, &rv));
  NS_ENSURE_SUCCESS(rv, rv);
  NS_IF_ADDREF(*aArray = attachments);
  int32_t count = 0;
  if (m_pAttachments)
    count = m_pAttachments->Length();
  if (!count)
    return NS_OK;

  nsCString urlStr;
  ImportAttachment * pAttach;

  for (int32_t i = 0; i < count; i++) {
    nsCOMPtr<nsIMsgAttachedFile> a(do_CreateInstance(NS_MSGATTACHEDFILE_CONTRACTID, &rv));
    NS_ENSURE_SUCCESS(rv, rv);
    // nsMsgNewURL(&url, "file://C:/boxster.jpg");
    // a[i].orig_url = url;

    pAttach = m_pAttachments->ElementAt(i);
    nsCOMPtr<nsIFile> tmpFile = do_QueryInterface(pAttach->pAttachment);
    a->SetTmpFile(tmpFile);
    urlStr.Adopt(0);

    nsCOMPtr <nsIURI> uri;
    nsresult rv = NS_NewFileURI(getter_AddRefs(uri), pAttach->pAttachment);
    NS_ENSURE_SUCCESS(rv, rv);
    uri->GetSpec(urlStr);
    if (urlStr.IsEmpty())
      return NS_ERROR_FAILURE;

    nsCOMPtr<nsIURI> origUrl;
    rv = m_pIOService->NewURI(urlStr, nullptr, nullptr, getter_AddRefs(origUrl));
    NS_ENSURE_SUCCESS(rv, rv);
    a->SetOrigUrl(origUrl);
    a->SetType(nsDependentCString(pAttach->mimeType));
    a->SetRealName(nsDependentCString(pAttach->description));
    a->SetEncoding(NS_LITERAL_CSTRING(ENCODING_BINARY));
    attachments->AppendElement(a, false);
  }
  return NS_OK;
}
Ejemplo n.º 5
0
void Attachments::add()
{
  if( !item ) return;

  AttDialog dialog;
  int result = dialog.exec();

  if( result == QDialog::Rejected
      //|| dialog.name().isEmpty()
      || dialog.uri().isEmpty()
    ) return;

  QListWidgetItem *item = new QListWidgetItem( attList );
  item->setText( !dialog.name().isEmpty() ? dialog.name() : dialog.uri() );
  item->setToolTip( dialog.uri() );
  item->setData( URI_ROLE, dialog.uri() );

  this->item->setAttachments( attachments() );
}
Ejemplo n.º 6
0
nsresult CMapiMessage::GetAttachments(nsIArray **aArray)
{
  nsresult rv;
  nsCOMPtr<nsIMutableArray> attachments (do_CreateInstance(NS_ARRAY_CONTRACTID, &rv));
  NS_ENSURE_SUCCESS(rv, rv);
  NS_IF_ADDREF(*aArray = attachments);

  for (std::vector<attach_data*>::const_iterator it = m_stdattachments.begin();
       it != m_stdattachments.end(); it++) {
    nsCOMPtr<nsIMsgAttachedFile> a(do_CreateInstance(NS_MSGATTACHEDFILE_CONTRACTID, &rv));
    NS_ENSURE_SUCCESS(rv, rv);
    a->SetOrigUrl((*it)->orig_url);
    a->SetTmpFile((*it)->tmp_file);
    a->SetEncoding(nsDependentCString((*it)->encoding));
    a->SetRealName(nsDependentCString((*it)->real_name));
    a->SetType(nsDependentCString((*it)->type));
    attachments->AppendElement(a, false);
  }
  return rv;
}
Ejemplo n.º 7
0
VKAPI_ATTR VkResult VKAPI_CALL vkCreateRenderPass(
    VkDevice device, const VkRenderPassCreateInfo *pCreateInfo,
    const VkAllocationCallbacks *pAllocator, VkRenderPass *pRenderPass) {
  VkRenderPassCreateInfo intercepted = *pCreateInfo;
  std::vector<VkAttachmentDescription> attachments(
      pCreateInfo->attachmentCount);

  for (size_t i = 0; i < pCreateInfo->attachmentCount; ++i) {
    attachments[i] = pCreateInfo->pAttachments[i];
    if (attachments[i].initialLayout == VK_IMAGE_LAYOUT_PRESENT_SRC_KHR) {
      attachments[i].initialLayout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
    }
    if (attachments[i].finalLayout == VK_IMAGE_LAYOUT_PRESENT_SRC_KHR) {
      attachments[i].finalLayout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
    }
  }
  PFN_vkCreateRenderPass func =
      GetGlobalContext().GetDeviceData(device)->vkCreateRenderPass;

  return func(device, &intercepted, pAllocator, pRenderPass);
}
void TestKeePass2Format::testKdbxDeviceFailure()
{
    auto key = QSharedPointer<CompositeKey>::create();
    key->addKey(QSharedPointer<PasswordKey>::create("test"));
    QScopedPointer<Database> db(new Database());
    db->setKey(key);
    // Disable compression so we write a predictable number of bytes.
    db->setCompressionAlgorithm(Database::CompressionNone);

    auto entry = new Entry();
    entry->setParent(db->rootGroup());
    QByteArray attachment(4096, 'Z');
    entry->attachments()->set("test", attachment);

    FailDevice failDevice(512);
    QVERIFY(failDevice.open(QIODevice::WriteOnly));
    bool hasError;
    QString errorString;
    writeKdbx(&failDevice, db.data(), hasError, errorString);
    QVERIFY(hasError);
    QCOMPARE(errorString, QString("FAILDEVICE"));
}
Ejemplo n.º 9
0
QMessageId addMessage(const Parameters &params)
{
    QString parentAccountName(params["parentAccountName"]);
    QString parentFolderPath(params["parentFolderPath"]);
    QString to(params["to"]);
    QString from(params["from"]);
    QString cc(params["cc"]);
    QString bcc(params["bcc"]);
    QString date(params["date"]);
    QString receivedDate(params["receivedDate"]);
    QString subject(params["subject"]);
    QString text(params["text"]);
    QString mimeType(params["mimeType"]);
    QString attachments(params["attachments"]);
    QString priority(params["priority"]);
    QString size(params["size"]);
    QString type(params["type"]);
    QString read(params["status-read"]);
    QString hasAttachments(params["status-hasAttachments"]);

    QMessageManager mgr;

    if (!to.isEmpty() && !from.isEmpty() && !date.isEmpty() && !subject.isEmpty() &&
            !parentAccountName.isEmpty() && !parentFolderPath.isEmpty()) {
        // Find the named account
        QMessageAccountIdList accountIds(mgr.queryAccounts(QMessageAccountFilter::byName(parentAccountName)));
        if (accountIds.count() == 1) {
            // Find the specified folder
            QMessageFolderFilter filter(QMessageFolderFilter::byPath(parentFolderPath, QMessageDataComparator::Equal) & QMessageFolderFilter::byParentAccountId(accountIds.first()));
            QMessageFolderIdList folderIds(mgr.queryFolders(filter));
            if (folderIds.count() == 1) {
                QMessage message;
                QMessagePrivate *p = MapiSession::privateMessage(message);

                message.setParentAccountId(accountIds.first());
                p->_parentFolderId = folderIds.first();

                QMessage::StatusFlags flags(0);
                if (read.toLower() == "true") {
                    flags |= QMessage::Read;
                }
                if (hasAttachments.toLower() == "true") {
                    flags |= QMessage::HasAttachments;
                }
                message.setStatus(flags);

                QList<QMessageAddress> toList;
                foreach (const QString &addr, to.split(",", QString::SkipEmptyParts)) {
                    toList.append(QMessageAddress(QMessageAddress::Email, addr.trimmed()));
                }
                message.setTo(toList);

                QList<QMessageAddress> ccList;
                foreach (const QString &addr, cc.split(",", QString::SkipEmptyParts)) {
                    ccList.append(QMessageAddress(QMessageAddress::Email, addr.trimmed()));
                }
                if (!ccList.isEmpty()) {
                    message.setCc(ccList);
                }

                QList<QMessageAddress> bccList;
                foreach (const QString &addr, bcc.split(",")) {
                    if (!addr.isEmpty()) {
                        bccList.append(QMessageAddress(QMessageAddress::Email, addr.trimmed()));
                    }
                }
                message.setBcc(bccList);

                message.setFrom(QMessageAddress(QMessageAddress::Email, from));
                message.setSubject(subject);

                QDateTime dt(QDateTime::fromString(date, Qt::ISODate));
                dt.setTimeSpec(Qt::UTC);
                message.setDate(dt);

                if (type.isEmpty()) {
                    message.setType(QMessage::Email);
                } else {
                    if (type.toLower() == "mms") {
                        message.setType(QMessage::Mms);
                    } else if (type.toLower() == "sms") {
                        message.setType(QMessage::Sms);
                    } else if (type.toLower() == "instantmessage") {
                        message.setType(QMessage::InstantMessage);
                    } else {
                        message.setType(QMessage::Email);
                    }
                }

                if (!receivedDate.isEmpty()) {
                    QDateTime dt(QDateTime::fromString(receivedDate, Qt::ISODate));
                    dt.setTimeSpec(Qt::UTC);
                    message.setReceivedDate(dt);
                }

                if (!priority.isEmpty()) {
                    if (priority.toLower() == "high") {
                        message.setPriority(QMessage::HighPriority);
                    } else if (priority.toLower() == "low") {
                        message.setPriority(QMessage::LowPriority);
                    }
                }

                if (!text.isEmpty()) {
                    message.setBody(text, mimeType.toAscii());
                }

                if (!attachments.isEmpty()) {
                    qDebug() << attachments;
                    message.appendAttachments(attachments.split("\n"));
                } else {
                    qDebug() << "Support: No attchments";
                }

                if (!size.isEmpty()) {
                    p->_size = size.toUInt();
                }

                if (!mgr.addMessage(&message)) {
                    qWarning() << "Unable to addMessage:" << to << from << date << subject;
                } else {
                    return message.id();
                }
            } else {
Ejemplo n.º 10
0
bool Connection::processMessage()
{
    if (m_readBufferSize < sizeof(MessageInfo))
        return false;

    uint8_t* messageData = m_readBuffer.data();
    MessageInfo messageInfo;
    memcpy(&messageInfo, messageData, sizeof(messageInfo));
    messageData += sizeof(messageInfo);

    size_t messageLength = sizeof(MessageInfo) + messageInfo.attachmentCount() * sizeof(AttachmentInfo) + (messageInfo.isMessageBodyIsOutOfLine() ? 0 : messageInfo.bodySize());
    if (m_readBufferSize < messageLength)
        return false;

    size_t attachmentFileDescriptorCount = 0;
    size_t attachmentCount = messageInfo.attachmentCount();
    std::unique_ptr<AttachmentInfo[]> attachmentInfo;

    if (attachmentCount) {
        attachmentInfo = std::make_unique<AttachmentInfo[]>(attachmentCount);
        memcpy(attachmentInfo.get(), messageData, sizeof(AttachmentInfo) * attachmentCount);
        messageData += sizeof(AttachmentInfo) * attachmentCount;

        for (size_t i = 0; i < attachmentCount; ++i) {
            switch (attachmentInfo[i].getType()) {
            case Attachment::MappedMemoryType:
            case Attachment::SocketType:
                if (!attachmentInfo[i].isNull())
                    attachmentFileDescriptorCount++;
                break;
            case Attachment::Uninitialized:
            default:
                ASSERT_NOT_REACHED();
                break;
            }
        }

        if (messageInfo.isMessageBodyIsOutOfLine())
            attachmentCount--;
    }

    Vector<Attachment> attachments(attachmentCount);
    AttachmentResourceGuard<Vector<Attachment>, Vector<Attachment>::iterator> attachementDisposer(attachments);
    RefPtr<WebKit::SharedMemory> oolMessageBody;

    size_t fdIndex = 0;
    for (size_t i = 0; i < attachmentCount; ++i) {
        int fd = -1;
        switch (attachmentInfo[i].getType()) {
        case Attachment::MappedMemoryType:
            if (!attachmentInfo[i].isNull())
                fd = m_fileDescriptors[fdIndex++];
            attachments[attachmentCount - i - 1] = Attachment(fd, attachmentInfo[i].getSize());
            break;
        case Attachment::SocketType:
            if (!attachmentInfo[i].isNull())
                fd = m_fileDescriptors[fdIndex++];
            attachments[attachmentCount - i - 1] = Attachment(fd);
            break;
        case Attachment::Uninitialized:
            attachments[attachmentCount - i - 1] = Attachment();
        default:
            break;
        }
    }

    if (messageInfo.isMessageBodyIsOutOfLine()) {
        ASSERT(messageInfo.bodySize());

        if (attachmentInfo[attachmentCount].isNull()) {
            ASSERT_NOT_REACHED();
            return false;
        }

        WebKit::SharedMemory::Handle handle;
        handle.adoptFromAttachment(m_fileDescriptors[attachmentFileDescriptorCount - 1], attachmentInfo[attachmentCount].getSize());

        oolMessageBody = WebKit::SharedMemory::create(handle, WebKit::SharedMemory::ReadOnly);
        if (!oolMessageBody) {
            ASSERT_NOT_REACHED();
            return false;
        }
    }

    ASSERT(attachments.size() == (messageInfo.isMessageBodyIsOutOfLine() ? messageInfo.attachmentCount() - 1 : messageInfo.attachmentCount()));

    uint8_t* messageBody = messageData;
    if (messageInfo.isMessageBodyIsOutOfLine())
        messageBody = reinterpret_cast<uint8_t*>(oolMessageBody->data());

    auto decoder = std::make_unique<MessageDecoder>(DataReference(messageBody, messageInfo.bodySize()), std::move(attachments));

    processIncomingMessage(std::move(decoder));

    if (m_readBufferSize > messageLength) {
        memmove(m_readBuffer.data(), m_readBuffer.data() + messageLength, m_readBufferSize - messageLength);
        m_readBufferSize -= messageLength;
    } else
        m_readBufferSize = 0;

    if (attachmentFileDescriptorCount) {
        if (m_fileDescriptorsSize > attachmentFileDescriptorCount) {
            size_t fileDescriptorsLength = attachmentFileDescriptorCount * sizeof(int);
            memmove(m_fileDescriptors.data(), m_fileDescriptors.data() + fileDescriptorsLength, m_fileDescriptorsSize - fileDescriptorsLength);
            m_fileDescriptorsSize -= fileDescriptorsLength;
        } else
            m_fileDescriptorsSize = 0;
    }


    return true;
}
Ejemplo n.º 11
0
agpu_framebuffer *_agpu_framebuffer::create(agpu_device *device, agpu_uint width, agpu_uint height, agpu_uint colorCount, agpu_texture_view_description* colorViews, agpu_texture_view_description* depthStencilView)
{
    agpu_framebuffer *result = nullptr;
    
    // Attachments
    std::vector<VkAttachmentDescription> attachments(colorCount + (depthStencilView != nullptr ? 1 : 0));
    for (agpu_uint i = 0; i < colorCount; ++i)
    {
        auto view = &colorViews[i];
        auto &attachment = attachments[i];
        if (!view || !view->texture)
            return nullptr;

        attachment.format = mapTextureFormat(view->format);
        attachment.samples = VK_SAMPLE_COUNT_1_BIT;
        attachment.loadOp = VK_ATTACHMENT_LOAD_OP_LOAD;
        attachment.storeOp = VK_ATTACHMENT_STORE_OP_STORE;
        attachment.stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE;
        attachment.stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE;
        attachment.initialLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
        attachment.finalLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
    }

    if (depthStencilView != nullptr)
    {
        if (!depthStencilView->texture)
            return nullptr;

        auto &attachment = attachments.back();
        attachment.format = mapTextureFormat(depthStencilView->format);
        attachment.samples = VK_SAMPLE_COUNT_1_BIT;
        attachment.loadOp = VK_ATTACHMENT_LOAD_OP_LOAD;
        attachment.storeOp = VK_ATTACHMENT_STORE_OP_STORE;
        attachment.stencilLoadOp = VK_ATTACHMENT_LOAD_OP_LOAD;
        attachment.stencilStoreOp = VK_ATTACHMENT_STORE_OP_STORE;
        attachment.initialLayout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL;
        attachment.finalLayout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL;
    }

    // Color reference
    std::vector<VkAttachmentReference> colorReference(colorCount);
    for (agpu_uint i = 0; i < colorCount; ++i)
    {
        colorReference[i].attachment = i;
        colorReference[i].layout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
    }

    // Depth reference
    VkAttachmentReference depthReference;
    memset(&depthReference, 0, sizeof(depthReference));
    depthReference.attachment = colorCount;
    depthReference.layout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL;

    // Sub pass
    VkSubpassDescription subpass;
    memset(&subpass, 0, sizeof(subpass));
    subpass.pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS;
    subpass.colorAttachmentCount = colorCount;
    subpass.pColorAttachments = &colorReference[0];
    subpass.pDepthStencilAttachment = &depthReference;
    if (!depthStencilView)
        subpass.pDepthStencilAttachment = nullptr;

    // Render pass
    VkRenderPassCreateInfo renderPassCreateInfo;
    memset(&renderPassCreateInfo, 0, sizeof(renderPassCreateInfo));
    renderPassCreateInfo.sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO;
    renderPassCreateInfo.attachmentCount = attachments.size();
    renderPassCreateInfo.pAttachments = &attachments[0];
    renderPassCreateInfo.subpassCount = 1;
    renderPassCreateInfo.pSubpasses = &subpass;

    VkRenderPass renderPass;
    auto error = vkCreateRenderPass(device->device, &renderPassCreateInfo, nullptr, &renderPass);
    if (error)
        return nullptr;

    // Create the framebuffer
    std::vector<VkImageView> attachmentViews(attachments.size());
    for (agpu_uint i = 0; i < colorCount; ++i)
    {
        auto view = agpu_texture::createImageView(device, &colorViews[i]);
        if (!view)
            goto failure;

        attachmentViews[i] = view;
    }

    if (depthStencilView)
    {
        auto view = agpu_texture::createImageView(device, depthStencilView);
        if (!view)
            goto failure;
        attachmentViews.back() = view;
    }

    VkFramebufferCreateInfo createInfo;
    memset(&createInfo, 0, sizeof(createInfo));
    createInfo.sType = VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO;
    createInfo.attachmentCount = attachmentViews.size();
    createInfo.pAttachments = &attachmentViews[0];
    createInfo.renderPass = renderPass;
    createInfo.width = width;
    createInfo.height = height;
    createInfo.layers = 1;

    VkFramebuffer framebuffer;
    error = vkCreateFramebuffer(device->device, &createInfo, nullptr, &framebuffer);
    if (error)
        goto failure;

    result = new agpu_framebuffer(device);
    result->colorCount = colorCount;
    result->hasDepthStencil = depthStencilView != nullptr;

    result->width = width;
    result->height = height;
    result->renderPass = renderPass;
    result->framebuffer = framebuffer;
    result->attachmentViews = attachmentViews;
    result->attachmentTextures.resize(attachmentViews.size());
    for (agpu_uint i = 0; i < colorCount; ++i)
    {
        auto texture = colorViews[i].texture;
        texture->retain();
        result->attachmentTextures[i] = texture;
    }

    if (depthStencilView)
    {
        auto texture = depthStencilView->texture;
        texture->retain();
        result->attachmentTextures.back() = texture;
    }

    return result;

failure:
    vkDestroyRenderPass(device->device, renderPass, nullptr);
    for (auto view : attachmentViews)
    {
        if (view)
            vkDestroyImageView(device->device, view, nullptr);
    }

    return nullptr;
}
Ejemplo n.º 12
0
QByteArray QxtMailMessage::rfc2822() const
{
    // Use quoted-printable if requested
	bool useQuotedPrintable = (extraHeader(QStringLiteral("Content-Transfer-Encoding")).toLower() == QLatin1String("quoted-printable"));
    // Use base64 if requested
	bool useBase64 = (extraHeader(QStringLiteral("Content-Transfer-Encoding")).toLower() == QLatin1String("base64"));
    // Check to see if plain text is ASCII-clean; assume it isn't if QP or base64 was requested
    QTextCodec* latin1 = QTextCodec::codecForName("latin1");
    bool bodyIsAscii = latin1->canEncode(body()) && !useQuotedPrintable && !useBase64;

    QHash<QString, QxtMailAttachment> attach = attachments();
    QByteArray rv;

	if (!sender().isEmpty() && !hasExtraHeader(QStringLiteral("From")))
    {
		rv += qxt_fold_mime_header(QStringLiteral("From"), sender(), latin1);
    }

    if (!qxt_d->rcptTo.isEmpty())
    {
		rv += qxt_fold_mime_header(QStringLiteral("To"), qxt_d->rcptTo.join(QStringLiteral(", ")), latin1);
    }

    if (!qxt_d->rcptCc.isEmpty())
    {
		rv += qxt_fold_mime_header(QStringLiteral("Cc"), qxt_d->rcptCc.join(QStringLiteral(", ")), latin1);
    }

    if (!subject().isEmpty())
    {
		rv += qxt_fold_mime_header(QStringLiteral("Subject"), subject(), latin1);
    }

    if (!bodyIsAscii)
    {
		if (!hasExtraHeader(QStringLiteral("MIME-Version")) && !attach.count())
            rv += "MIME-Version: 1.0\r\n";

        // If no transfer encoding has been requested, guess.
        // Heuristic: If >20% of the first 100 characters aren't
        // 7-bit clean, use base64, otherwise use Q-P.
        if(!bodyIsAscii && !useQuotedPrintable && !useBase64)
        {
            QString b = body();
            int nonAscii = 0;
            int ct = b.length();
            for (int i = 0; i < ct && i < 100; i++)
            {
				if (QXT_MUST_QP(b[i])) nonAscii++;
			}
            useQuotedPrintable = !(nonAscii > 20);
            useBase64 = !useQuotedPrintable;
        }
    }

    if (attach.count())
    {
        if (qxt_d->boundary.isEmpty())
            qxt_d->boundary = QUuid::createUuid().toString().toLatin1().replace("{", "").replace("}", "");
		if (!hasExtraHeader(QStringLiteral("MIME-Version")))
            rv += "MIME-Version: 1.0\r\n";
		if (!hasExtraHeader(QStringLiteral("Content-Type")))
            rv += "Content-Type: multipart/mixed; boundary=" + qxt_d->boundary + "\r\n";
    }
	else if (!bodyIsAscii && !hasExtraHeader(QStringLiteral("Content-Transfer-Encoding")))
    {
        if (!useQuotedPrintable)
        {
            // base64
            rv += "Content-Transfer-Encoding: base64\r\n";
        }
        else
        {
            // quoted-printable
            rv += "Content-Transfer-Encoding: quoted-printable\r\n";
        }
    }

    for(const QString& r: qxt_d->extraHeaders.keys())
    {
		if ((r.toLower() == QLatin1String("content-type") || r.toLower() == QLatin1String("content-transfer-encoding")) && attach.count())
        {
            // Since we're in multipart mode, we'll be outputting this later
            continue;
        }
		rv += qxt_fold_mime_header(r, extraHeader(r), latin1);
    }

    rv += "\r\n";

    if (attach.count())
    {
        // we're going to have attachments, so output the lead-in for the message body
        rv += "This is a message with multiple parts in MIME format.\r\n";
        rv += "--" + qxt_d->boundary + "\r\nContent-Type: ";
		if (hasExtraHeader(QStringLiteral("Content-Type")))
			rv += extraHeader(QStringLiteral("Content-Type")).toLatin1() + "\r\n";
        else
            rv += "text/plain; charset=UTF-8\r\n";
		if (hasExtraHeader(QStringLiteral("Content-Transfer-Encoding")))
        {
			rv += "Content-Transfer-Encoding: " + extraHeader(QStringLiteral("Content-Transfer-Encoding")).toLatin1() + "\r\n";
        }
        else if (!bodyIsAscii)
        {
            if (!useQuotedPrintable)
            {
                // base64
                rv += "Content-Transfer-Encoding: base64\r\n";
            }
            else
            {
                // quoted-printable
                rv += "Content-Transfer-Encoding: quoted-printable\r\n";
            }
        }
        rv += "\r\n";
    }

    if (bodyIsAscii)
    {
        QByteArray b = latin1->fromUnicode(body());
        int len = b.length();
        QByteArray line = "";
        QByteArray word = "";
        for (int i = 0; i < len; i++)
        {
            if (b[i] == '\n' || b[i] == '\r')
            {
                if (line.isEmpty()) 
                {
                    line = word;
                    word = "";
                }
                else if (line.length() + word.length() + 1 <= 78)
                {
                    line = line + ' ' + word;
                    word = "";
                }
                if(line[0] == '.')
                    rv += ".";
                rv += line + "\r\n";
                if ((b[i+1] == '\n' || b[i+1] == '\r') && b[i] != b[i+1])
                {
                    // If we're looking at a CRLF pair, skip the second half
                    i++;
                }
                line = word;
            }
            else if (b[i] == ' ')
            {
                if (line.length() + word.length() + 1 > 78)
                {
                    if(line[0] == '.')
                        rv += ".";
                    rv += line + "\r\n";
                    line = word;
                }
                else if (line.isEmpty())
                {
                    line = word;
                }
                else
                {
                    line = line + ' ' + word;
                }
                word = "";
            }
            else
            {
                word += b[i];
            }
        }
        if (line.length() + word.length() + 1 > 78)
        {
            if(line[0] == '.')
                rv += ".";
            rv += line + "\r\n";
            line = word;
        }
        else if (!word.isEmpty())
        {
            line += ' ' + word;
        }
        if(!line.isEmpty()) {
            if(line[0] == '.')
                rv += ".";
            rv += line + "\r\n";
        }
    }
    else if (useQuotedPrintable)
    {
        QByteArray b = body().toUtf8();
        int ct = b.length();
        QByteArray line;
        for (int i = 0; i < ct; i++)
        {
            if(b[i] == '\n' || b[i] == '\r')
            {
                if(line[0] == '.')
                    rv += ".";
                rv += line + "\r\n";
                line = "";
                if ((b[i+1] == '\n' || b[i+1] == '\r') && b[i] != b[i+1])
                {
                    // If we're looking at a CRLF pair, skip the second half
                    i++;
                }
            }
            else if (line.length() > 74)
            {
                rv += line + "=\r\n";
                line = "";
            }
            if (QXT_MUST_QP(b[i]))
            {
                line += "=" + b.mid(i, 1).toHex().toUpper();
            }
            else
            {
                line += b[i];
            }
        }
        if(!line.isEmpty()) {
            if(line[0] == '.')
                rv += ".";
            rv += line + "\r\n";
        }
    }
    else /* base64 */
    {
        QByteArray b = body().toUtf8().toBase64();
        int ct = b.length();
        for (int i = 0; i < ct; i += 78)
        {
            rv += b.mid(i, 78) + "\r\n";
        }
    }

    if (attach.count())
    {
        for(const QString& filename: attach.keys())
        {
            rv += "--" + qxt_d->boundary + "\r\n";
			rv += qxt_fold_mime_header(QStringLiteral("Content-Disposition"), QDir(filename).dirName(), latin1, "attachment; filename=");
            rv += attach[filename].mimeData();
        }
        rv += "--" + qxt_d->boundary + "--\r\n";
    }

    return rv;
}
/**
 * Test for catching mapping errors with duplicate attachments.
 */
void TestKeePass2Format::testDuplicateAttachments()
{
    auto db = QSharedPointer<Database>::create();
    db->setKey(QSharedPointer<CompositeKey>::create());

    const QByteArray attachment1("abc");
    const QByteArray attachment2("def");
    const QByteArray attachment3("ghi");

    auto entry1 = new Entry();
    entry1->setGroup(db->rootGroup());
    entry1->setUuid(QUuid::fromRfc4122("aaaaaaaaaaaaaaaa"));
    entry1->attachments()->set("a", attachment1);

    auto entry2 = new Entry();
    entry2->setGroup(db->rootGroup());
    entry2->setUuid(QUuid::fromRfc4122("bbbbbbbbbbbbbbbb"));
    entry2->attachments()->set("b1", attachment1);
    entry2->beginUpdate();
    entry2->attachments()->set("b2", attachment1);
    entry2->endUpdate();
    entry2->beginUpdate();
    entry2->attachments()->set("b3", attachment2);
    entry2->endUpdate();
    entry2->beginUpdate();
    entry2->attachments()->set("b4", attachment2);
    entry2->endUpdate();

    auto entry3 = new Entry();
    entry3->setGroup(db->rootGroup());
    entry3->setUuid(QUuid::fromRfc4122("cccccccccccccccc"));
    entry3->attachments()->set("c1", attachment2);
    entry3->attachments()->set("c2", attachment2);
    entry3->attachments()->set("c3", attachment3);

    QBuffer buffer;
    buffer.open(QBuffer::ReadWrite);

    bool hasError = false;
    QString errorString;
    writeKdbx(&buffer, db.data(), hasError, errorString);
    if (hasError) {
        QFAIL(qPrintable(QString("Error while writing database: %1").arg(errorString)));
    }

    buffer.seek(0);
    readKdbx(&buffer, QSharedPointer<CompositeKey>::create(), db, hasError, errorString);
    if (hasError) {
        QFAIL(qPrintable(QString("Error while reading database: %1").arg(errorString)));
    }

    QCOMPARE(db->rootGroup()->entries()[0]->attachments()->value("a"), attachment1);

    QCOMPARE(db->rootGroup()->entries()[1]->attachments()->value("b1"), attachment1);
    QCOMPARE(db->rootGroup()->entries()[1]->attachments()->value("b2"), attachment1);
    QCOMPARE(db->rootGroup()->entries()[1]->attachments()->value("b3"), attachment2);
    QCOMPARE(db->rootGroup()->entries()[1]->attachments()->value("b4"), attachment2);
    QCOMPARE(db->rootGroup()->entries()[1]->historyItems()[0]->attachments()->value("b1"), attachment1);
    QCOMPARE(db->rootGroup()->entries()[1]->historyItems()[1]->attachments()->value("b1"), attachment1);
    QCOMPARE(db->rootGroup()->entries()[1]->historyItems()[1]->attachments()->value("b2"), attachment1);
    QCOMPARE(db->rootGroup()->entries()[1]->historyItems()[2]->attachments()->value("b1"), attachment1);
    QCOMPARE(db->rootGroup()->entries()[1]->historyItems()[2]->attachments()->value("b2"), attachment1);
    QCOMPARE(db->rootGroup()->entries()[1]->historyItems()[2]->attachments()->value("b3"), attachment2);

    QCOMPARE(db->rootGroup()->entries()[2]->attachments()->value("c1"), attachment2);
    QCOMPARE(db->rootGroup()->entries()[2]->attachments()->value("c2"), attachment2);
    QCOMPARE(db->rootGroup()->entries()[2]->attachments()->value("c3"), attachment3);
}
Ejemplo n.º 14
0
void GrVkRenderPass::init(const GrVkGpu* gpu,
                          const LoadStoreOps& colorOp,
                          const LoadStoreOps& resolveOp,
                          const LoadStoreOps& stencilOp) {
    uint32_t numAttachments = fAttachmentsDescriptor.fAttachmentCount;
    // Attachment descriptions to be set on the render pass
    SkTArray<VkAttachmentDescription> attachments(numAttachments);
    attachments.reset(numAttachments);
    memset(attachments.begin(), 0, numAttachments * sizeof(VkAttachmentDescription));

    // Refs to attachments on the render pass (as described by teh VkAttachmentDescription above),
    // that are used by the subpass.
    VkAttachmentReference colorRef;
    VkAttachmentReference resolveRef;
    VkAttachmentReference stencilRef;
    uint32_t currentAttachment = 0;

    // Go through each of the attachment types (color, resolve, stencil) and set the necessary
    // on the various Vk structs.
    VkSubpassDescription subpassDesc;
    memset(&subpassDesc, 0, sizeof(VkSubpassDescription));
    subpassDesc.flags = 0;
    subpassDesc.pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS;
    subpassDesc.inputAttachmentCount = 0;
    subpassDesc.pInputAttachments = nullptr;
    if (fAttachmentFlags & kColor_AttachmentFlag) {
        // set up color attachment
        fAttachmentsDescriptor.fColor.fLoadStoreOps = colorOp;
        setup_vk_attachment_description(&attachments[currentAttachment],
                                        fAttachmentsDescriptor.fColor,
                                        VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL);
        // setup subpass use of attachment
        colorRef.attachment = currentAttachment++;
        colorRef.layout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
        subpassDesc.colorAttachmentCount = 1;
    } else {
        // I don't think there should ever be a time where we don't have a color attachment
        SkASSERT(false);
        colorRef.attachment = VK_ATTACHMENT_UNUSED;
        colorRef.layout = VK_IMAGE_LAYOUT_UNDEFINED;
        subpassDesc.colorAttachmentCount = 0;
    }
    subpassDesc.pColorAttachments = &colorRef;

    if (fAttachmentFlags & kResolve_AttachmentFlag) {
        // set up resolve attachment
        fAttachmentsDescriptor.fResolve.fLoadStoreOps = resolveOp;
        setup_vk_attachment_description(&attachments[currentAttachment],
                                        fAttachmentsDescriptor.fResolve,
                                        VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL);
        // setup subpass use of attachment
        resolveRef.attachment = currentAttachment++;
        // I'm really not sure what the layout should be for the resolve textures.
        resolveRef.layout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
        subpassDesc.pResolveAttachments = &resolveRef;
    } else {
        subpassDesc.pResolveAttachments = nullptr;
    }

    if (fAttachmentFlags & kStencil_AttachmentFlag) {
        // set up stencil attachment
        fAttachmentsDescriptor.fStencil.fLoadStoreOps = stencilOp;
        setup_vk_attachment_description(&attachments[currentAttachment],
                                        fAttachmentsDescriptor.fStencil,
                                        VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL);
        // setup subpass use of attachment
        stencilRef.attachment = currentAttachment++;
        stencilRef.layout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL;
    } else {
        stencilRef.attachment = VK_ATTACHMENT_UNUSED;
        stencilRef.layout = VK_IMAGE_LAYOUT_UNDEFINED;
    }
    subpassDesc.pDepthStencilAttachment = &stencilRef;

    subpassDesc.preserveAttachmentCount = 0;
    subpassDesc.pPreserveAttachments = nullptr;

    SkASSERT(numAttachments == currentAttachment);

    // Create the VkRenderPass compatible with the attachment descriptions above
    VkRenderPassCreateInfo createInfo;
    memset(&createInfo, 0, sizeof(VkRenderPassCreateInfo));
    createInfo.sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO;
    createInfo.pNext = nullptr;
    createInfo.flags = 0;
    createInfo.attachmentCount = numAttachments;
    createInfo.pAttachments = attachments.begin();
    createInfo.subpassCount = 1;
    createInfo.pSubpasses = &subpassDesc;
    createInfo.dependencyCount = 0;
    createInfo.pDependencies = nullptr;

    GR_VK_CALL_ERRCHECK(gpu->vkInterface(), CreateRenderPass(gpu->device(),
                                                             &createInfo,
                                                             nullptr,
                                                             &fRenderPass));
}