Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion REUSE.toml
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,7 @@ SPDX-FileCopyrightText = "2022 Nextcloud GmbH and Nextcloud contributors"
SPDX-License-Identifier = "AGPL-3.0-or-later"

[[annotations]]
path = ["src/tests/data/user@imap.localhost.chain.p12", "src/tests/data/user@imap.localhost.crt", "src/tests/data/user@imap.localhost.key", "src/tests/data/user@imap.localhost.p12", "tests/data/smime-certs/cn-only@imap.localhost.crt", "tests/data/smime-certs/cn-only@imap.localhost.key", "tests/data/smime-certs/imap.localhost.ca.crt", "tests/data/smime-certs/domain.tld.ca.crt", "tests/data/smime-certs/user@domain.tld.crt", "tests/data/smime-certs/user@domain.tld.key", "tests/data/smime-certs/user@imap.localhost.crt", "tests/data/smime-certs/user@imap.localhost.key", "tests/data/decrypted-message-body.txt", "tests/data/decrypted-signed-opaque-message-body.txt", "tests/data/encrypted-message.txt", "tests/data/encrypted-signed-opaque-message.txt", "tests/data/sieve-vacation-cleaned.sieve", "tests/data/sieve-vacation-off.sieve", "tests/data/sieve-vacation-on-no-end-date.sieve", "tests/data/sieve-vacation-on-no-tz.sieve", "tests/data/sieve-vacation-on-special-chars-message.sieve", "tests/data/sieve-vacation-on-special-chars-subject.sieve", "tests/data/sieve-vacation-on-subject-placeholder.sieve", "tests/data/sieve-vacation-on.sieve", "tests/data/signed-message.txt", "tests/data/signed-opaque-message.txt"]
path = ["src/tests/data/user@imap.localhost.chain.p12", "src/tests/data/user@imap.localhost.crt", "src/tests/data/user@imap.localhost.key", "src/tests/data/user@imap.localhost.p12", "tests/data/smime-certs/cn-only@imap.localhost.crt", "tests/data/smime-certs/cn-only@imap.localhost.key", "tests/data/smime-certs/imap.localhost.ca.crt", "tests/data/smime-certs/domain.tld.ca.crt", "tests/data/smime-certs/user@domain.tld.crt", "tests/data/smime-certs/user@domain.tld.key", "tests/data/smime-certs/user@imap.localhost.crt", "tests/data/smime-certs/user@imap.localhost.key", "tests/data/decrypted-message-body.txt", "tests/data/decrypted-signed-opaque-message-body.txt", "tests/data/encrypted-message.txt", "tests/data/encrypted-signed-opaque-message.txt", "tests/data/nobody-message.txt", "tests/data/sieve-vacation-cleaned.sieve", "tests/data/sieve-vacation-off.sieve", "tests/data/sieve-vacation-on-no-end-date.sieve", "tests/data/sieve-vacation-on-no-tz.sieve", "tests/data/sieve-vacation-on-special-chars-message.sieve", "tests/data/sieve-vacation-on-special-chars-subject.sieve", "tests/data/sieve-vacation-on-subject-placeholder.sieve", "tests/data/sieve-vacation-on.sieve", "tests/data/signed-message.txt", "tests/data/signed-opaque-message.txt"]
precedence = "aggregate"
SPDX-FileCopyrightText = "2023 Nextcloud GmbH and Nextcloud contributors"
SPDX-License-Identifier = "AGPL-3.0-or-later"
Expand Down
2 changes: 2 additions & 0 deletions lib/IMAP/ImapMessageFetcher.php
Original file line number Diff line number Diff line change
Expand Up @@ -217,6 +217,8 @@ public function fetchMessage(?Horde_Imap_Client_Data_Fetch $fetch = null): IMAPM
$bodyPartId = $structure->findBody();
if (!is_null($bodyPartId)) {
$this->getPart($structure[$bodyPartId], $bodyPartId, $isEncrypted || $isSigned);
} else {
$this->getPart($structure, '1', $isEncrypted || $isSigned);
}
}
} elseif (is_null($fetch)) {
Expand Down
21 changes: 21 additions & 0 deletions tests/Integration/IMAP/ImapMessageFetcherIntegrationTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -231,4 +231,25 @@ public function testFetchMessageWithOpaqueSignedMessage(): void {
$this->assertTrue($message->isSigned());
$this->assertTrue($message->isSignatureValid());
}

public function testFetchMessageWithoutBody(): void {
$mimeMessage = file_get_contents(__DIR__ . '/../../data/nobody-message.txt');
$uid = $this->saveMimeMessage('INBOX', $mimeMessage);
$fetcher = $this->fetcherFactory
->build(
$uid,
'INBOX',
$this->getTestClient(),
$this->account->getUserId()
)
->withBody(true);

$message = $fetcher->fetchMessage();

$this->assertFalse($message->isEncrypted());
$this->assertCount(1, $message->attachments);
$attachment = $message->attachments[0];
$this->assertEquals('attach.zip', $attachment['fileName']);
$this->assertSame('application/zip', $attachment['mime']);
}
}
24 changes: 24 additions & 0 deletions tests/data/nobody-message.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
Return-Path: <debug@imap.localhost>
Delivered-To: user@imap.localhost
Received: from 0531f16fe281
by 0531f16fe281 (Dovecot) with LMTP id doHuJnh71GVlNwEAcWVang
for <user@imap.localhost>; Fri, 3 Jul 2026 00:35:01 +0000
Received: from anton.vpn (unknown [172.17.0.1])
by 0531f16fe281 (Postfix) with ESMTP id 636C81E56
for <user@imap.localhost>; Fri, 3 Jul 2026 00:35:01 +0000 (UTC)
From: debug@imap.localhost
To: user@imap.localhost
Cc:
Subject: Just a file
Message-ID: <20240220101506.Horde.UpbNuMMPVearQMy_n71Hu7U@anton.vpn>
User-Agent: Horde Application Framework 5
Date: Fri, 3 Jul 2026 00:35:01 +0000
Content-Type: application/zip; name=attach.zip
MIME-Version: 1.0
Content-Disposition: attachment; filename=attach.zip
Content-Transfer-Encoding: base64

UEsDBAoAAAAAAC8E41wWNZYxBgAAAAYAAAAJABwAaGVsbG8udHh0VVQJAAM650ZqTedGanV4CwAB
BOgDAAAE6AMAAEhlbGxvClBLAQIeAwoAAAAAAC8E41wWNZYxBgAAAAYAAAAJABgAAAAAAAEAAAC0
gQAAAABoZWxsby50eHRVVAUAAzrnRmp1eAsAAQToAwAABOgDAABQSwUGAAAAAAEAAQBPAAAASQAA
AAAA
Loading