X-Git-Url: https://arthur.barton.de/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=lib%2Fbup%2F_helpers.c;h=9078be3da723d8e7757662950a7521bdc275754f;hb=544208fae44dfeaccb626c16f3a5c387f318d08f;hp=d986895affaeda9cd117b1dc9bc909c470a25f5a;hpb=3306a802a11b8d945af081cb835bb7fe208dc84c;p=bup.git diff --git a/lib/bup/_helpers.c b/lib/bup/_helpers.c index d986895..9078be3 100644 --- a/lib/bup/_helpers.c +++ b/lib/bup/_helpers.c @@ -29,6 +29,9 @@ #ifdef HAVE_UNISTD_H #include #endif +#ifdef HAVE_SYS_TIME_H +#include +#endif #ifdef HAVE_LINUX_FS_H #include @@ -71,8 +74,10 @@ typedef struct { #if PY_MAJOR_VERSION < 3 static state_t state; # define get_state(x) (&state) +# define cstr_argf "s" #else # define get_state(x) ((state_t *) PyModule_GetState(x)) +# define cstr_argf "y" #endif // PY_MAJOR_VERSION >= 3 @@ -740,6 +745,11 @@ struct sha { unsigned char bytes[20]; }; +static inline int _cmp_sha(const struct sha *sha1, const struct sha *sha2) +{ + return memcmp(sha1->bytes, sha2->bytes, sizeof(sha1->bytes)); +} + struct idx { unsigned char *map; @@ -750,17 +760,6 @@ struct idx { int name_base; }; - -static int _cmp_sha(const struct sha *sha1, const struct sha *sha2) -{ - int i; - for (i = 0; i < sizeof(struct sha); i++) - if (sha1->bytes[i] != sha2->bytes[i]) - return sha1->bytes[i] - sha2->bytes[i]; - return 0; -} - - static void _fix_idx_order(struct idx **idxs, int *last_i) { struct idx *idx; @@ -1251,7 +1250,7 @@ static PyObject *bup_utimensat(PyObject *self, PyObject *args) PyObject *access_py, *modification_py; struct timespec ts[2]; - if (!PyArg_ParseTuple(args, "is((Ol)(Ol))i", + if (!PyArg_ParseTuple(args, "i" cstr_argf "((Ol)(Ol))i", &fd, &path, &access_py, &(ts[0].tv_nsec), @@ -1293,7 +1292,7 @@ static int bup_parse_xutimes_args(char **path, PyObject *access_py, *modification_py; long long access_us, modification_us; // POSIX guarantees tv_usec is signed. - if (!PyArg_ParseTuple(args, "s((OL)(OL))", + if (!PyArg_ParseTuple(args, cstr_argf "((OL)(OL))", path, &access_py, &access_us, &modification_py, &modification_us)) @@ -1409,7 +1408,7 @@ static PyObject *bup_stat(PyObject *self, PyObject *args) int rc; char *filename; - if (!PyArg_ParseTuple(args, "s", &filename)) + if (!PyArg_ParseTuple(args, cstr_argf, &filename)) return NULL; struct stat st; @@ -1425,7 +1424,7 @@ static PyObject *bup_lstat(PyObject *self, PyObject *args) int rc; char *filename; - if (!PyArg_ParseTuple(args, "s", &filename)) + if (!PyArg_ParseTuple(args, cstr_argf, &filename)) return NULL; struct stat st; @@ -1479,43 +1478,59 @@ static PyObject *bup_localtime(PyObject *self, PyObject *args) #ifdef BUP_MINCORE_BUF_TYPE static PyObject *bup_mincore(PyObject *self, PyObject *args) { - const char *src; - Py_ssize_t src_ssize; - Py_buffer dest; + Py_buffer src, dest; PyObject *py_src_n, *py_src_off, *py_dest_off; - if (!PyArg_ParseTuple(args, "s#OOw*O", - &src, &src_ssize, &py_src_n, &py_src_off, + + if (!PyArg_ParseTuple(args, cstr_argf "*OOw*O", + &src, &py_src_n, &py_src_off, &dest, &py_dest_off)) return NULL; - unsigned long long src_size, src_n, src_off, dest_size, dest_off; + PyObject *result = NULL; + + unsigned long long src_n, src_off, dest_off; if (!(bup_ullong_from_py(&src_n, py_src_n, "src_n") && bup_ullong_from_py(&src_off, py_src_off, "src_off") && bup_ullong_from_py(&dest_off, py_dest_off, "dest_off"))) - return NULL; + goto clean_and_return; - if (!INTEGRAL_ASSIGNMENT_FITS(&src_size, src_ssize)) - return PyErr_Format(PyExc_OverflowError, "invalid src size"); unsigned long long src_region_end; + if (!uadd(&src_region_end, src_off, src_n)) { + result = PyErr_Format(PyExc_OverflowError, "(src_off + src_n) too large"); + goto clean_and_return; + } + if (src_region_end > src.len) { + result = PyErr_Format(PyExc_OverflowError, "region runs off end of src"); + goto clean_and_return; + } - if (!uadd(&src_region_end, src_off, src_n)) - return PyErr_Format(PyExc_OverflowError, "(src_off + src_n) too large"); - if (src_region_end > src_size) - return PyErr_Format(PyExc_OverflowError, "region runs off end of src"); - - if (!INTEGRAL_ASSIGNMENT_FITS(&dest_size, dest.len)) - return PyErr_Format(PyExc_OverflowError, "invalid dest size"); - if (dest_off > dest_size) - return PyErr_Format(PyExc_OverflowError, "region runs off end of dest"); + unsigned long long dest_size; + if (!INTEGRAL_ASSIGNMENT_FITS(&dest_size, dest.len)) { + result = PyErr_Format(PyExc_OverflowError, "invalid dest size"); + goto clean_and_return; + } + if (dest_off > dest_size) { + result = PyErr_Format(PyExc_OverflowError, "region runs off end of dest"); + goto clean_and_return; + } size_t length; - if (!INTEGRAL_ASSIGNMENT_FITS(&length, src_n)) - return PyErr_Format(PyExc_OverflowError, "src_n overflows size_t"); - int rc = mincore((void *)(src + src_off), src_n, + if (!INTEGRAL_ASSIGNMENT_FITS(&length, src_n)) { + result = PyErr_Format(PyExc_OverflowError, "src_n overflows size_t"); + goto clean_and_return; + } + int rc = mincore((void *)(src.buf + src_off), src_n, (BUP_MINCORE_BUF_TYPE *) (dest.buf + dest_off)); - if (rc != 0) - return PyErr_SetFromErrno(PyExc_OSError); - return Py_BuildValue("O", Py_None); + if (rc != 0) { + result = PyErr_SetFromErrno(PyExc_OSError); + goto clean_and_return; + } + result = Py_BuildValue("O", Py_None); + + clean_and_return: + PyBuffer_Release(&src); + PyBuffer_Release(&dest); + return result; } #endif /* def BUP_MINCORE_BUF_TYPE */