]> arthur.barton.de Git - bup.git/commitdiff
write_idx: fix handling of signed/unsigned values
authorRob Browning <rlb@defaultvalue.org>
Fri, 20 Nov 2020 07:29:02 +0000 (01:29 -0600)
committerRob Browning <rlb@defaultvalue.org>
Sun, 22 Nov 2020 20:42:01 +0000 (14:42 -0600)
Coerce the incoming Py_ssize_t count directly to the required uint32_t
while checking for overflow.  The underlying problem was identified
when we hit two sign-compare warnings on (32-bit) platforms where
ssize_t is 32 bits.

Explicitly add -Wsign-comapare to CFLAGS, just to be sure it's
included.

Reported-by: Dominique Leuenberger
Signed-off-by: Rob Browning <rlb@defaultvalue.org>
Tested-by: Rob Browning <rlb@defaultvalue.org>
Makefile
lib/bup/_helpers.c

index 5e31562ae5e771387b53b231e70219cf6a9d490d..51afd1a0a722933812de191408b9af5af648ea21 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -28,7 +28,8 @@ current_sampledata := t/sampledata/var/rev/v$(sampledata_rev)
 os := $(shell ($(pf); uname | sed 's/[-_].*//') $(isok))
 os := $(call shout,$(os),Unable to determine OS)
 
-CFLAGS := -Wall -Wformat=2 -O2 -Werror -Wno-unknown-pragmas $(CFLAGS)
+CFLAGS := -O2 -Wall -Werror -Wformat=2 $(CFLAGS)
+CFLAGS := -Wno-unknown-pragmas -Wsign-compare $(CFLAGS)
 CFLAGS := -D_FILE_OFFSET_BITS=64 $(PYINCLUDE) $(CFLAGS)
 SOEXT:=.so
 
index ba8cd6035b6e8ecbf70d66b0d4175a9c3c58a068..cf31d0aac2630eb44f35398dfa66e12f058875ad 100644 (file)
@@ -1087,7 +1087,7 @@ static PyObject *write_idx(PyObject *self, PyObject *args)
     PyObject *part;
     unsigned int total = 0;
     uint32_t count;
-    int i, j, ofs64_count;
+    int i, ofs64_count;
     uint32_t *fan_ptr, *crc_ptr, *ofs_ptr;
     uint64_t *ofs64_ptr;
     struct sha *sha_ptr;
@@ -1122,16 +1122,17 @@ static PyObject *write_idx(PyObject *self, PyObject *args)
     ofs64_count = 0;
     for (i = 0; i < FAN_ENTRIES; ++i)
     {
-       Py_ssize_t plen;
        part = PyList_GET_ITEM(idx, i);
        PyList_Sort(part);
-       plen = PyList_GET_SIZE(part);
-        if (plen > UINT32_MAX || UINT32_MAX - count < plen) {
+        uint32_t plen;
+        if (!INTEGRAL_ASSIGNMENT_FITS(&plen, PyList_GET_SIZE(part))
+            || UINT32_MAX - count < plen) {
             PyErr_Format(PyExc_OverflowError, "too many objects in index part");
             goto clean_and_return;
         }
-        count += (uint32_t) plen;
+        count += plen;
        *fan_ptr++ = htonl(count);
+        uint32_t j;
         for (j = 0; j < plen; ++j)
        {
            unsigned char *sha = NULL;