This is an automated email from the ASF dual-hosted git repository.
Arsnael pushed a commit to branch 3.9.x
in repository https://gitbox.apache.org/repos/asf/james-project.git
The following commit(s) were added to refs/heads/3.9.x by this push:
new c00729db6f [FIX] Handle partial rows in attachmentV2
c00729db6f is described below
commit c00729db6fbf9af2cded18cbf30df57b442c27cb
Author: Benoit TELLIER <[email protected]>
AuthorDate: Mon Aug 17 20:23:14 2026 +0700
[FIX] Handle partial rows in attachmentV2
(cherry picked from commit 98c4277affb947b7b844d7fa47418dcfe863cf8b)
---
.../mailbox/cassandra/mail/CassandraAttachmentDAOV2.java | 16 +++++++++++++++-
1 file changed, 15 insertions(+), 1 deletion(-)
diff --git
a/mailbox/cassandra/src/main/java/org/apache/james/mailbox/cassandra/mail/CassandraAttachmentDAOV2.java
b/mailbox/cassandra/src/main/java/org/apache/james/mailbox/cassandra/mail/CassandraAttachmentDAOV2.java
index 2a1b9f0e27..4ee7978409 100644
---
a/mailbox/cassandra/src/main/java/org/apache/james/mailbox/cassandra/mail/CassandraAttachmentDAOV2.java
+++
b/mailbox/cassandra/src/main/java/org/apache/james/mailbox/cassandra/mail/CassandraAttachmentDAOV2.java
@@ -48,6 +48,8 @@ import org.apache.james.mailbox.model.ContentType;
import org.apache.james.mailbox.model.MessageId;
import org.apache.james.mailbox.model.StringBackedAttachmentId;
import org.apache.james.util.DurationParser;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
import com.datastax.oss.driver.api.core.CqlSession;
import com.datastax.oss.driver.api.core.cql.PreparedStatement;
@@ -59,6 +61,7 @@ import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;
public class CassandraAttachmentDAOV2 {
+ private static final Logger LOGGER =
LoggerFactory.getLogger(CassandraAttachmentDAOV2.class);
private static final Optional<Duration> TTL =
Optional.ofNullable(System.getProperty("james.jmap.attachment.ttl", null))
.map(DurationParser::parse);
@@ -135,6 +138,14 @@ public class CassandraAttachmentDAOV2 {
attachment.getSize());
}
+ private static boolean isWellFormed(Row row, AttachmentId attachmentId) {
+ if (row.getString(ID) == null || row.getString(BLOB_ID) == null) {
+ LOGGER.warn("Ignoring partially written attachment row {}",
attachmentId.getId());
+ return false;
+ }
+ return true;
+ }
+
private static DAOAttachment fromRow(Row row, BlobId.Factory
blobIfFactory) {
MessageId messageId =
CassandraMessageId.Factory.of(row.getUuid(MESSAGE_ID));
@@ -204,6 +215,7 @@ public class CassandraAttachmentDAOV2 {
return cassandraAsyncExecutor.executeSingleRow(
selectStatement.bind()
.setUuid(ID_AS_UUID, attachmentId.asUUID()))
+ .filter(row -> isWellFormed(row, attachmentId))
.map(row -> CassandraAttachmentDAOV2.fromRow(row, blobIdFactory));
}
@@ -227,6 +239,8 @@ public class CassandraAttachmentDAOV2 {
public Flux<BlobId> listBlobs() {
return cassandraAsyncExecutor.executeRows(listBlobs.bind())
- .map(row -> blobIdFactory.parse(row.getString(BLOB_ID)));
+ .map(row -> row.getString(BLOB_ID))
+ .filter(Objects::nonNull)
+ .map(blobIdFactory::parse);
}
}
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]