]> arthur.barton.de Git - bup.git/blobdiff - lib/bup/_helpers.c
write_idx: make the 64-bit offset count uint32_t not int
[bup.git] / lib / bup / _helpers.c
index a6ffd322e1ea73bdafaaa9f34c0dc7e948931518..f47de73a07d0e4a2734f88caa13bb0fc392f6280 100644 (file)
@@ -175,12 +175,17 @@ static uint64_t htonll(uint64_t value)
     })
 
 
-// At the moment any code that calls INTEGER_TO_PY() will have to
-// disable -Wtautological-compare for clang.  See below.
-
-#define INTEGER_TO_PY(x) \
-    (((x) >= 0) ? PyLong_FromUnsignedLongLong(x) : PyLong_FromLongLong(x))
-
+#define INTEGER_TO_PY(x)                                                \
+    ({                                                                  \
+        _Pragma("GCC diagnostic push");                                 \
+        _Pragma("GCC diagnostic ignored \"-Wtype-limits\"");   \
+        _Pragma("clang diagnostic push");                               \
+        _Pragma("clang diagnostic ignored \"-Wtautological-compare\""); \
+        PyObject *result = ((x) >= 0) ? PyLong_FromUnsignedLongLong(x) : PyLong_FromLongLong(x); \
+        _Pragma("clang diagnostic pop");                                \
+        _Pragma("GCC diagnostic pop");                                  \
+        result;                                                         \
+    })
 
 
 #if PY_MAJOR_VERSION < 3
@@ -1082,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;
     uint32_t *fan_ptr, *crc_ptr, *ofs_ptr;
     uint64_t *ofs64_ptr;
     struct sha *sha_ptr;
@@ -1114,19 +1119,20 @@ static PyObject *write_idx(PyObject *self, PyObject *args)
     ofs64_ptr = (uint64_t *)&ofs_ptr[total];
 
     count = 0;
-    ofs64_count = 0;
+    uint32_t 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;
@@ -1577,9 +1583,6 @@ static PyObject *bup_lutimes(PyObject *self, PyObject *args)
 #endif
 
 
-#pragma clang diagnostic push
-#pragma clang diagnostic ignored "-Wtautological-compare" // For INTEGER_TO_PY().
-
 static PyObject *stat_struct_to_py(const struct stat *st,
                                    const char *filename,
                                    int fd)
@@ -1605,7 +1608,6 @@ static PyObject *stat_struct_to_py(const struct stat *st,
                          (long) BUP_STAT_CTIME_NS(st));
 }
 
-#pragma clang diagnostic pop  // ignored "-Wtautological-compare"
 
 static PyObject *bup_stat(PyObject *self, PyObject *args)
 {
@@ -2409,8 +2411,6 @@ static int setup_module(PyObject *m)
     }
 
     char *e;
-#pragma clang diagnostic push
-#pragma clang diagnostic ignored "-Wtautological-compare" // For INTEGER_TO_PY().
     {
         PyObject *value;
         value = INTEGER_TO_PY(INT_MAX);
@@ -2442,7 +2442,6 @@ static int setup_module(PyObject *m)
         Py_DECREF(value);
     }
 #endif
-#pragma clang diagnostic pop  // ignored "-Wtautological-compare"
 
     e = getenv("BUP_FORCE_TTY");
     get_state(m)->istty2 = isatty(2) || (atoi(e ? e : "0") & 2);