summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--export.c23
1 files changed, 22 insertions, 1 deletions
diff --git a/export.c b/export.c
index 3e1b2dc..3786220 100644
--- a/export.c
+++ b/export.c
@@ -138,6 +138,25 @@ static void exportFetchParts(
 	}
 }
 
+static void checkBodyParts(const struct BodyPart *structure, struct Data body) {
+	if (structure->multipart) {
+		struct List list = dataCheck(body, List).list;
+		if (list.len < structure->parts.len) {
+			errx(EX_PROTOCOL, "missing body parts");
+		}
+		for (size_t i = 0; i < structure->parts.len; ++i) {
+			checkBodyParts(&structure->parts.ptr[i], list.ptr[i]);
+		}
+	} else if (
+		structure->message.structure &&
+		structure->message.structure->multipart
+	) {
+		checkBodyParts(structure->message.structure, body);
+	} else if (body.type != String) {
+		errx(EX_PROTOCOL, "missing body part");
+	}
+}
+
 bool exportData(FILE *imap, enum Atom tag, struct List items) {
 	uint32_t uid = 0;
 	struct Envelope envelope = {0};
@@ -202,6 +221,9 @@ bool exportData(FILE *imap, enum Atom tag, struct List items) {
 	if (!structure.subtype) {
 		errx(EX_PROTOCOL, "missing BODYSTRUCTURE data item");
 	}
+	if (bodyParts.type == List) {
+		checkBodyParts(&structure, bodyParts);
+	}
 
 	if (bodyHeader.type == String && bodyText.type == String) {
 		exportMbox(uid, &envelope, bodyHeader.string, bodyText.string);
@@ -211,7 +233,6 @@ bool exportData(FILE *imap, enum Atom tag, struct List items) {
 	if (!structure.multipart) {
 		exportAtom(uid, &envelope, &structure, bodyText);
 	} else if (bodyParts.type == List) {
-		// TODO: Validate that bodyParts is parallel to structure.
 		exportAtom(uid, &envelope, &structure, bodyParts);
 	} else {
 		fetch = true;