static int
dbox_attachment_file_get_stream_from(struct dbox_file *file,
const char *ext_refs,
- struct istream **stream)
+ struct istream **stream,
+ const char **error_r)
{
ARRAY_TYPE(mail_attachment_extref) extrefs_arr;
ARRAY_DEFINE(streams, struct istream *);
unsigned int i;
int ret = 1;
+ *error_r = NULL;
+
t_array_init(&extrefs_arr, 16);
if (!dbox_attachment_parse_extref_real(ext_refs, pool_datastack_create(),
- &extrefs_arr))
+ &extrefs_arr)) {
+ *error_r = "Broken ext-refs string";
return 0;
+ }
psize = dbox_file_get_plaintext_size(file);
t_array_init(&streams, 8);
array_append(&streams, &input, 1);
i_stream_seek(*stream, (*stream)->v_offset + part_size);
if ((*stream)->v_offset + part_size > psize) {
- /* extrefs point outside message */
+ *error_r = t_strdup_printf(
+ "ext-refs point outside message "
+ "(%"PRIuUOFF_T" + %"PRIuUOFF_T" > %"PRIuUOFF_T")",
+ (*stream)->v_offset, part_size, psize);
ret = 0;
}
last_voffset += part_size;
}
if (psize != (*stream)->v_offset) {
- if (psize < (*stream)->v_offset) {
- /* extrefs point outside message */
+ if ((*stream)->v_offset > psize) {
+ *error_r = t_strdup_printf(
+ "ext-refs point outside message "
+ "(%"PRIuUOFF_T" > %"PRIuUOFF_T")",
+ (*stream)->v_offset, psize);
ret = 0;
} else {
uoff_t trailer_size = psize - (*stream)->v_offset;
int dbox_attachment_file_get_stream(struct dbox_file *file,
struct istream **stream)
{
- const char *ext_refs;
+ const char *ext_refs, *error;
int ret;
/* need to read metadata in case there are external references */
/* we have external references. */
T_BEGIN {
ret = dbox_attachment_file_get_stream_from(file, ext_refs,
- stream);
+ stream, &error);
+ if (ret == 0) {
+ dbox_file_set_corrupted(file,
+ "Corrupted ext-refs metadata %s: %s",
+ ext_refs, error);
+ }
} T_END;
- if (ret == 0) {
- dbox_file_set_corrupted(file, "Ext refs metadata corrupted: %s",
- ext_refs);
- }
return ret;
}