summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKevin McCarthy <kevin@8t8.us>2021-09-23 14:58:54 -0700
committerKevin McCarthy <kevin@8t8.us>2021-09-23 14:58:54 -0700
commitd0d40a33f1400269251d06c56ef331482c6b99be (patch)
treea2586f36617eb51f6aac7fc2c227d5ea6b196c14
parent4153ae9614739821a99b20d744c5a333ec344f73 (diff)
Don't use subtraction for qsort numeric value comparisons.
Subtraction can overflow, resulting in incorrect sorts. This is especially a concern for the date and size sorting, whose fields are greater than an 'int' size. The index values should be okay, but it's better to be consistent and avoid any possible issues. Define a macro, mutt_numeric_cmp(), that uses direct comparison rather than subtraction.
-rw-r--r--imap/imap.c6
-rw-r--r--lib.h2
-rw-r--r--sort.c12
-rw-r--r--thread.c11
4 files changed, 15 insertions, 16 deletions
diff --git a/imap/imap.c b/imap/imap.c
index a419abb6..14407b0f 100644
--- a/imap/imap.c
+++ b/imap/imap.c
@@ -1135,11 +1135,7 @@ static int compare_uid (const void *a, const void *b)
HEADER **pa = (HEADER **) a;
HEADER **pb = (HEADER **) b;
- if (HEADER_DATA(*pa)->uid < HEADER_DATA(*pb)->uid)
- return -1;
- if (HEADER_DATA(*pa)->uid > HEADER_DATA(*pb)->uid)
- return 1;
- return 0;
+ return mutt_numeric_cmp (HEADER_DATA(*pa)->uid, HEADER_DATA(*pb)->uid);
}
/* Note: headers must be in SORT_UID. See imap_exec_msgset for args.
diff --git a/lib.h b/lib.h
index e0ddb4b4..47f0d833 100644
--- a/lib.h
+++ b/lib.h
@@ -90,6 +90,8 @@
# define MAX(a,b) ((a) < (b) ? (b) : (a))
# define MIN(a,b) ((a) < (b) ? (a) : (b))
+#define mutt_numeric_cmp(a,b) ((a) < (b) ? -1 : ((a) > (b) ? 1 : 0))
+
/* Use this with care. If the compiler can't see the array
* definition, it obviously won't produce a correct result. */
#define mutt_array_size(x) (sizeof (x) / sizeof ((x)[0]))
diff --git a/sort.c b/sort.c
index f801860b..1c5ee2ce 100644
--- a/sort.c
+++ b/sort.c
@@ -33,21 +33,21 @@ static int compare_score (const void *a, const void *b)
{
HEADER **pa = (HEADER **) a;
HEADER **pb = (HEADER **) b;
- return (*pb)->score - (*pa)->score; /* note that this is reverse */
+ return mutt_numeric_cmp ((*pb)->score, (*pa)->score); /* note that this is reverse */
}
static int compare_size (const void *a, const void *b)
{
HEADER **pa = (HEADER **) a;
HEADER **pb = (HEADER **) b;
- return (*pa)->content->length - (*pb)->content->length;
+ return mutt_numeric_cmp ((*pa)->content->length, (*pb)->content->length);
}
static int compare_date_sent (const void *a, const void *b)
{
HEADER **pa = (HEADER **) a;
HEADER **pb = (HEADER **) b;
- return (*pa)->date_sent - (*pb)->date_sent;
+ return mutt_numeric_cmp ((*pa)->date_sent, (*pb)->date_sent);
}
static int compare_subject (const void *a, const void *b)
@@ -115,7 +115,7 @@ static int compare_date_received (const void *a, const void *b)
{
HEADER **pa = (HEADER **) a;
HEADER **pb = (HEADER **) b;
- return (*pa)->received - (*pb)->received;
+ return mutt_numeric_cmp ((*pa)->received, (*pb)->received);
}
static int compare_order (const void *a, const void *b)
@@ -123,7 +123,7 @@ static int compare_order (const void *a, const void *b)
HEADER **ha = (HEADER **) a;
HEADER **hb = (HEADER **) b;
- return (*ha)->index - (*hb)->index;
+ return mutt_numeric_cmp ((*ha)->index, (*hb)->index);
}
static int compare_spam (const void *a, const void *b)
@@ -251,7 +251,7 @@ static int compare_unthreaded (const void *a, const void *b)
if (rc)
return (SortAux & SORT_REVERSE) ? -rc : rc;
- rc = (*((HEADER **)a))->index - (*((HEADER **)b))->index;
+ rc = mutt_numeric_cmp ((*((HEADER **)a))->index, (*((HEADER **)b))->index);
if (rc)
return (Sort & SORT_REVERSE) ? -rc : rc;
diff --git a/thread.c b/thread.c
index 19866aca..ddd1c7c1 100644
--- a/thread.c
+++ b/thread.c
@@ -594,7 +594,8 @@ static int compare_aux_threads (const void *a, const void *b)
if (rc)
return (SortAux & SORT_REVERSE) ? -rc : rc;
- rc = (*((THREAD **)a))->sort_aux_key->index - (*((THREAD **)b))->sort_aux_key->index;
+ rc = mutt_numeric_cmp ((*((THREAD **)a))->sort_aux_key->index,
+ (*((THREAD **)b))->sort_aux_key->index);
if (rc)
return (SortAux & SORT_REVERSE) ? -rc : rc;
@@ -622,7 +623,7 @@ static int compare_aux_sortkeys (const void *a, const void *b)
if (rc)
return rc;
- return (*((HEADER **)a))->index - (*((HEADER **)b))->index;
+ return mutt_numeric_cmp ((*((HEADER **)a))->index, (*((HEADER **)b))->index);
}
static int compare_root_threads (const void *a, const void *b)
@@ -652,8 +653,8 @@ static int compare_root_threads (const void *a, const void *b)
if (rc)
return reverse ? -rc : rc;
- rc = (*((THREAD **)a))->sort_group_key->index -
- (*((THREAD **)b))->sort_group_key->index;
+ rc = mutt_numeric_cmp ((*((THREAD **)a))->sort_group_key->index,
+ (*((THREAD **)b))->sort_group_key->index);
if (rc)
return reverse ? -rc : rc;
@@ -686,7 +687,7 @@ static int compare_group_sortkeys (const void *a, const void *b)
if (rc)
return rc;
- return (*((HEADER **)a))->index - (*((HEADER **)b))->index;
+ return mutt_numeric_cmp ((*((HEADER **)a))->index, (*((HEADER **)b))->index);
}
THREAD *mutt_sort_subthreads (THREAD *thread, int init)