Index: Modules/bsddbmodule.c =================================================================== --- Modules/bsddbmodule.c (révision 83197) +++ Modules/bsddbmodule.c (copie de travail) @@ -675,10 +675,52 @@ &bsddb_as_mapping, /*tp_as_mapping*/ }; +#define FILENAME_STR(file) (file != NULL ? PyString_AS_STRING(file) : NULL) + +static int +parse_filename(PyObject* arg, void* addr) +{ + PyObject *output = NULL; + PyObject **filename = addr; + Py_ssize_t size; + void *data; + if (arg == Py_None) { + *filename = NULL; + return 1; + } + if (PyString_Check(arg)) { + output = arg; + Py_INCREF(output); + } + else { + arg = PyUnicode_FromObject(arg); + if (!arg) + return 0; + output = PyUnicode_AsEncodedString(arg, Py_FileSystemDefaultEncoding, NULL); + Py_DECREF(arg); + if (!output) + return 0; + if (!PyString_Check(output)) { + Py_DECREF(output); + PyErr_SetString(PyExc_TypeError, "encoder failed to return bytes"); + return 0; + } + } + size = PyString_GET_SIZE(output); + data = PyString_AS_STRING(output); + if (size != strlen(data)) { + PyErr_SetString(PyExc_TypeError, "embedded NUL character"); + Py_DECREF(output); + return 0; + } + *filename = output; + return 1; +} + static PyObject * bsdhashopen(PyObject *self, PyObject *args) { - char *file; + PyObject *file; char *flag = NULL; int flags = O_RDONLY; int mode = 0666; @@ -688,9 +730,10 @@ int cachesize = 0; int hash = 0; /* XXX currently ignored */ int lorder = 0; + PyObject *obj; - if (!PyArg_ParseTuple(args, "z|siiiiiii:hashopen", - &file, &flag, &mode, + if (!PyArg_ParseTuple(args, "O&|siiiiiii:hashopen", + parse_filename, &file, &flag, &mode, &bsize, &ffactor, &nelem, &cachesize, &hash, &lorder)) return NULL; @@ -707,6 +750,7 @@ else { PyErr_SetString(BsddbError, "Flag should begin with 'r', 'w', 'c' or 'n'"); + Py_XDECREF(file); return NULL; } if (flag[1] == 'l') { @@ -718,18 +762,21 @@ #else PyErr_SetString(BsddbError, "locking not supported on this platform"); + Py_XDECREF(file); return NULL; #endif } } - return newdbhashobject(file, flags, mode, - bsize, ffactor, nelem, cachesize, hash, lorder); + obj = newdbhashobject(FILENAME_STR(file), flags, mode, + bsize, ffactor, nelem, cachesize, hash, lorder); + Py_XDECREF(file); + return obj; } static PyObject * bsdbtopen(PyObject *self, PyObject *args) { - char *file; + PyObject *file; char *flag = NULL; int flags = O_RDONLY; int mode = 0666; @@ -739,9 +786,10 @@ int btflags = 0; unsigned int psize = 0; int lorder = 0; + PyObject *obj; - if (!PyArg_ParseTuple(args, "z|siiiiiii:btopen", - &file, &flag, &mode, + if (!PyArg_ParseTuple(args, "O&|siiiiiii:btopen", + parse_filename, &file, &flag, &mode, &btflags, &cachesize, &maxkeypage, &minkeypage, &psize, &lorder)) return NULL; @@ -758,6 +806,7 @@ else { PyErr_SetString(BsddbError, "Flag should begin with 'r', 'w', 'c' or 'n'"); + Py_XDECREF(file); return NULL; } if (flag[1] == 'l') { @@ -769,19 +818,22 @@ #else PyErr_SetString(BsddbError, "locking not supported on this platform"); + Py_XDECREF(file); return NULL; #endif } } - return newdbbtobject(file, flags, mode, - btflags, cachesize, maxkeypage, minkeypage, - psize, lorder); + obj = newdbbtobject(FILENAME_STR(file), flags, mode, + btflags, cachesize, maxkeypage, minkeypage, + psize, lorder); + Py_XDECREF(file); + return obj; } static PyObject * bsdrnopen(PyObject *self, PyObject *args) { - char *file; + PyObject *file; char *flag = NULL; int flags = O_RDONLY; int mode = 0666; @@ -792,9 +844,10 @@ size_t reclen = 0; char *bval = ""; char *bfname = NULL; + PyObject *obj; - if (!PyArg_ParseTuple(args, "z|siiiiiiss:rnopen", - &file, &flag, &mode, + if (!PyArg_ParseTuple(args, "O&|siiiiiiss:rnopen", + parse_filename, &file, &flag, &mode, &rnflags, &cachesize, &psize, &lorder, &reclen, &bval, &bfname)) return NULL; @@ -812,6 +865,7 @@ else { PyErr_SetString(BsddbError, "Flag should begin with 'r', 'w', 'c' or 'n'"); + Py_XDECREF(file); return NULL; } if (flag[1] == 'l') { @@ -823,17 +877,21 @@ #else PyErr_SetString(BsddbError, "locking not supported on this platform"); + Py_XDECREF(file); return NULL; #endif } else if (flag[1] != '\0') { PyErr_SetString(BsddbError, "Flag char 2 should be 'l' or absent"); + Py_XDECREF(file); return NULL; } } - return newdbrnobject(file, flags, mode, rnflags, cachesize, - psize, lorder, reclen, bval[0], bfname); + obj = newdbrnobject(FILENAME_STR(file), flags, mode, rnflags, cachesize, + psize, lorder, reclen, bval[0], bfname); + Py_XDECREF(file); + return obj; } static PyMethodDef bsddbmodule_methods[] = {