diff --git a/cdr.c b/cdr.c index f00fdac..786c504 100644 --- a/cdr.c +++ b/cdr.c @@ -1711,3 +1711,20 @@ void cdr_truncate_call_id_suffix(char *callid) break; }; } + +static bool cdr_verify_field(const GString *f, size_t max) { + return !(max && f->len > max); +} + +// return false if one of the fields is too long +bool cdr_verify_fields(const cdr_entry_t *cdr) { +#define F(f, x) if (cdr_verify_field(cdr->f, x)) return false; +#define FA(f, a, x) for (unsigned int j = 0; j < a; j++) if (cdr_verify_field(cdr->f[j], x)) return false; + +#include "cdr_field_names.inc" + +#undef F +#undef FA + + return true; +} diff --git a/cdr.h b/cdr.h index 4db9e1e..085404b 100644 --- a/cdr.h +++ b/cdr.h @@ -2,6 +2,7 @@ #define _CDR_H #include "mediator.h" +#include #define MSG_INVITE "INVITE" #define MSG_BYE "BYE" @@ -64,6 +65,7 @@ int cdr_process_records(GQueue *records, uint64_t *cdr_count, struct medmysql_ba int do_intermediate); void cdr_parse_entry(med_entry_t *); void cdr_truncate_call_id_suffix(char *); +bool cdr_verify_fields(const cdr_entry_t *); #endif /* _CDR_H */ diff --git a/medmysql.c b/medmysql.c index 7ec484b..81136d8 100644 --- a/medmysql.c +++ b/medmysql.c @@ -1100,7 +1100,15 @@ int medmysql_insert_cdrs(cdr_entry_t *entries, uint64_t count, struct medmysql_b CDRPRINT("),"); const char *end_ptr = batch->cdrs.str + batch->cdrs.len; - L_DEBUG("CDR entry to be written: %.*s", (int) (end_ptr - begin_ptr), begin_ptr); + size_t cdr_len = end_ptr - begin_ptr; + L_DEBUG("CDR entry to be written: %.*s", (int) cdr_len, begin_ptr); + + if (!cdr_verify_fields(e)) { + L_WARNING("CDR field verification failed for record"); + // backtrack + batch->cdrs.len -= cdr_len; + continue; + } single_cdr *single = g_slice_alloc(sizeof(*single)); single->begin = begin_ptr; @@ -1758,7 +1766,7 @@ static int medmysql_flush_cdr_batch(struct medmysql_cdr_batch *batch) { fclose(qlog); } - if (!batch->cdrs.len) + if (!batch->num_cdrs) return 0;