diff --git a/ChangeLog b/ChangeLog index 10249542..1d828b39 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2007-04-13 Federico Di Gregorio + + * Applied patch from David Rushby for int->size_t transition. + 2007-04-12 Federico Di Gregorio * Applied patch from Jason Erickson to fix win32 build glitches. diff --git a/psycopg/adapter_qstring.c b/psycopg/adapter_qstring.c index bb21ad84..ac2c9aa1 100644 --- a/psycopg/adapter_qstring.c +++ b/psycopg/adapter_qstring.c @@ -148,11 +148,26 @@ qstring_quote(qstringObject *self) return NULL; } - Py_BEGIN_ALLOW_THREADS; - len = qstring_escape(buffer+1, s, len, - self->conn ? ((connectionObject*)self->conn)->pgconn : NULL); - buffer[0] = '\'' ; buffer[len+1] = '\''; - Py_END_ALLOW_THREADS; + { /* Call qstring_escape with the GIL released, then reacquire the GIL + * before verifying that the results can fit into a Python string; raise + * an exception if not. */ + size_t qstring_res; + + Py_BEGIN_ALLOW_THREADS + qstring_res = qstring_escape(buffer+1, s, len, + self->conn ? ((connectionObject*)self->conn)->pgconn : NULL); + Py_END_ALLOW_THREADS + + if (qstring_res > (size_t) PY_SSIZE_T_MAX) { + PyErr_SetString(PyExc_IndexError, "PG buffer too large to fit in" + " Python buffer."); + PyMem_Free(buffer); + Py_DECREF(str); + return NULL; + } + len = (Py_ssize_t) qstring_res; + buffer[0] = '\'' ; buffer[len+1] = '\''; + } self->buffer = PyString_FromStringAndSize(buffer, len+2); PyMem_Free(buffer); diff --git a/psycopg/connection_int.c b/psycopg/connection_int.c index 5c4a02f3..be534727 100644 --- a/psycopg/connection_int.c +++ b/psycopg/connection_int.c @@ -55,7 +55,7 @@ conn_connect(connectionObject *self) PGconn *pgconn; PGresult *pgres; char *data, *tmp; - int i; + size_t i; /* we need the initial date style to be ISO, for typecasters; if the user later change it, she must know what she's doing... */ diff --git a/psycopg/connection_type.c b/psycopg/connection_type.c index 3e3448b7..4abb08d0 100644 --- a/psycopg/connection_type.c +++ b/psycopg/connection_type.c @@ -184,7 +184,7 @@ static PyObject * psyco_conn_set_client_encoding(connectionObject *self, PyObject *args) { char *buffer, *enc = NULL; - int i, j; + size_t i, j; EXC_IF_CONN_CLOSED(self); diff --git a/psycopg/cursor_type.c b/psycopg/cursor_type.c index 55924d52..6dbe846f 100644 --- a/psycopg/cursor_type.c +++ b/psycopg/cursor_type.c @@ -90,12 +90,12 @@ _mogrify(PyObject *var, PyObject *fmt, connectionObject *conn, PyObject **new) while(*c) { /* check if some crazy guy mixed formats */ if (kind == 2) { - Py_XDECREF(n); + Py_XDECREF(n); psyco_set_error(ProgrammingError, (PyObject*)conn, - "argument formats can't be mixed", NULL, NULL); + "argument formats can't be mixed", NULL, NULL); return -1; - } - kind = 1; + } + kind = 1; /* handle plain percent symbol in format string */ if (c[0] == '%' && c[1] == '%') { @@ -114,7 +114,7 @@ _mogrify(PyObject *var, PyObject *fmt, connectionObject *conn, PyObject **new) for (d = c + 2; *d && *d != ')'; d++); if (*d == ')') { - key = PyString_FromStringAndSize(c+2, d-c-2); + key = PyString_FromStringAndSize(c+2, (Py_ssize_t) (d-c-2)); value = PyObject_GetItem(var, key); /* key has refcnt 1, value the original value + 1 */ @@ -195,8 +195,8 @@ _mogrify(PyObject *var, PyObject *fmt, connectionObject *conn, PyObject **new) if (kind == 1) { Py_XDECREF(n); psyco_set_error(ProgrammingError, (PyObject*)conn, - "argument formats can't be mixed", NULL, NULL); - return -1; + "argument formats can't be mixed", NULL, NULL); + return -1; } kind = 2; @@ -653,7 +653,7 @@ _psyco_curs_buildrow_fill(cursorObject *self, PyObject *res, len = PQgetlength(self->pgres, row, i); } - Dprintf("_psyco_curs_buildrow: row %ld, element %d, len %i", + Dprintf("_psyco_curs_buildrow: row %ld, element %d, len %d", self->row, i, len); val = typecast_cast(PyTuple_GET_ITEM(self->casts, i), (char*)str, len, @@ -902,14 +902,15 @@ psyco_curs_callproc(cursorObject *self, PyObject *args, PyObject *kwargs) { char *procname = NULL, *sql = NULL; long int async = 0; - Py_ssize_t i, nparameters = 0, sl = 0; + Py_ssize_t procname_len, i, nparameters = 0, sl = 0; PyObject *parameters = NULL; PyObject *operation = NULL; PyObject *res = NULL; - if (!PyArg_ParseTuple(args, "s|Ol", &procname, ¶meters, &async)) { - return NULL; - } + if (!PyArg_ParseTuple(args, "s#|Ol", + &procname, &procname_len, ¶meters, &async + )) + { return NULL; } EXC_IF_CURS_CLOSED(self); @@ -925,7 +926,7 @@ psyco_curs_callproc(cursorObject *self, PyObject *args, PyObject *kwargs) } /* allocate some memory, build the SQL and create a PyString from it */ - sl = strlen(procname) + 17 + nparameters*3 - (nparameters ? 1 : 0); + sl = procname_len + 17 + nparameters*3 - (nparameters ? 1 : 0); sql = (char*)PyMem_Malloc(sl); if (sql == NULL) return NULL; @@ -1121,7 +1122,7 @@ psyco_curs_copy_from(cursorObject *self, PyObject *args, PyObject *kwargs) if (columns != NULL && columns != Py_None) { PyObject* collistiter = PyObject_GetIter(columns); PyObject* col; - int collistlen = 2; + Py_ssize_t collistlen = 2; Py_ssize_t colitemlen; char* colname; if (collistiter == NULL) { diff --git a/psycopg/pqpath.c b/psycopg/pqpath.c index 3e3a1d36..28cdde80 100644 --- a/psycopg/pqpath.c +++ b/psycopg/pqpath.c @@ -113,14 +113,14 @@ pq_raise(connectionObject *conn, cursorObject *curs, PyObject *exc, char *msg) /* if msg is not NULL, add it to the error message, after a '\n' */ if (msg && code) { - int len = strlen(code) + strlen(err) + strlen(msg) + 5; + size_t len = strlen(code) + strlen(err) + strlen(msg) + 5; if ((buf = PyMem_Malloc(len))) { snprintf(buf, len, "[%s] %s\n%s", code, err2, msg); psyco_set_error(exc, pgc, buf, err, code); } } else if (msg) { - int len = strlen(err) + strlen(msg) + 2; + size_t len = strlen(err) + strlen(msg) + 2; if ((buf = PyMem_Malloc(len))) { snprintf(buf, len, "%s\n%s", err2, msg); psyco_set_error(exc, pgc, buf, err, code); @@ -607,11 +607,14 @@ _pq_copy_in_v3(cursorObject *curs) if (!o || !PyString_Check(o) || (length = PyString_Size(o)) == -1) { error = 1; } - if (length == 0 || error == 1) break; + if (length == 0 || length > INT_MAX || error == 1) break; Py_BEGIN_ALLOW_THREADS; if (PQputCopyData(curs->conn->pgconn, - PyString_AS_STRING(o), length) == -1) { + PyString_AS_STRING(o), + /* Py_ssize_t->int cast was validated above: */ + (int) length + ) == -1) { error = 2; } Py_END_ALLOW_THREADS; diff --git a/psycopg/psycopgmodule.c b/psycopg/psycopgmodule.c index 73fc5c62..f1159620 100644 --- a/psycopg/psycopgmodule.c +++ b/psycopg/psycopgmodule.c @@ -89,8 +89,8 @@ PyObject *decimalType = NULL; ":return: New database connection\n" \ ":rtype: `extensions.connection`" -static int -_psyco_connect_fill_dsn(char *dsn, char *kw, char *v, int i) +static size_t +_psyco_connect_fill_dsn(char *dsn, char *kw, char *v, size_t i) { strcpy(&dsn[i], kw); i += strlen(kw); strcpy(&dsn[i], v); i += strlen(v); @@ -129,7 +129,8 @@ psyco_connect(PyObject *self, PyObject *args, PyObject *keywds) PyObject *conn = NULL, *factory = NULL; PyObject *pyport = NULL; - int idsn=-1, iport=-1; + size_t idsn=-1; + int iport=-1; char *dsn_static=NULL, *dsn_dynamic=NULL; char *database=NULL, *user=NULL, *password=NULL; char *host=NULL, *sslmode=NULL; @@ -165,7 +166,7 @@ psyco_connect(PyObject *self, PyObject *args, PyObject *keywds) PyOS_snprintf(port, 16, "%d", iport); if (dsn_static == NULL) { - int l = 45; /* len("dbname= user= password= host= port= sslmode=\0") */ + size_t l = 45; /* len("dbname= user= password= host= port= sslmode=\0") */ if (database) l += strlen(database); if (host) l += strlen(host); diff --git a/psycopg/typecast.c b/psycopg/typecast.c index f720a1a4..3af39713 100644 --- a/psycopg/typecast.c +++ b/psycopg/typecast.c @@ -40,7 +40,7 @@ skip_until_space(char *s) } static char * -skip_until_space2(char *s, int *len) +skip_until_space2(char *s, Py_ssize_t *len) { while (*len > 0 && *s && *s != ' ') { s++; (*len)--; @@ -49,12 +49,13 @@ skip_until_space2(char *s, int *len) } static int -typecast_parse_date(char* s, char** t, int* len, +typecast_parse_date(char* s, char** t, Py_ssize_t* len, int* year, int* month, int* day) { int acc = -1, cz = 0; - Dprintf("typecast_parse_date: len = %d, s = %s", *len, s); + Dprintf("typecast_parse_date: len = " FORMAT_CODE_PY_SSIZE_T ", s = %s", + *len, s); while (cz < 3 && *len > 0 && *s) { switch (*s) { @@ -84,7 +85,7 @@ typecast_parse_date(char* s, char** t, int* len, } static int -typecast_parse_time(char* s, char** t, int* len, +typecast_parse_time(char* s, char** t, Py_ssize_t* len, int* hh, int* mm, int* ss, int* us, int* tz) { int acc = -1, cz = 0; @@ -94,7 +95,8 @@ typecast_parse_time(char* s, char** t, int* len, /* sets microseconds and timezone to 0 because they may be missing */ *us = *tz = 0; - Dprintf("typecast_parse_time: len = %d, s = %s", *len, s); + Dprintf("typecast_parse_time: len = " FORMAT_CODE_PY_SSIZE_T ", s = %s", + *len, s); while (cz < 6 && *len > 0 && *s) { switch (*s) { @@ -140,8 +142,8 @@ typecast_parse_time(char* s, char** t, int* len, *tz = tzs * tzhh*60 + tzmm; - if (*us != 0.0) { - while (usd++ < 6) *us *= 10.0; + if (*us != 0) { + while (usd++ < 6) *us *= 10; } return cz; diff --git a/psycopg/typecast.h b/psycopg/typecast.h index 0e55fb8e..162cd6a4 100644 --- a/psycopg/typecast.h +++ b/psycopg/typecast.h @@ -30,7 +30,7 @@ extern "C" { #endif /* type of type-casting functions (both C and Python) */ -typedef PyObject *(*typecast_function)(char *, int len, PyObject *); +typedef PyObject *(*typecast_function)(char *, Py_ssize_t len, PyObject *); /** typecast type **/ diff --git a/psycopg/typecast_array.c b/psycopg/typecast_array.c index 383beb12..bc0d7353 100644 --- a/psycopg/typecast_array.c +++ b/psycopg/typecast_array.c @@ -24,9 +24,9 @@ /** typecast_array_cleanup - remove the horrible [...]= stuff **/ static int -typecast_array_cleanup(char **str, int *len) +typecast_array_cleanup(char **str, Py_ssize_t *len) { - int i, depth = 1; + Py_ssize_t i, depth = 1; if ((*str)[0] != '[') return -1; @@ -53,13 +53,16 @@ typecast_array_cleanup(char **str, int *len) #define ASCAN_QUOTED 4 static int -typecast_array_tokenize(char *str, int strlength, - int *pos, char** token, int *length, int *quotes) +typecast_array_tokenize(char *str, Py_ssize_t strlength, + Py_ssize_t *pos, char** token, + Py_ssize_t *length, int *quotes) { /* FORTRAN glory */ - int i, j, q, b, l, res; + Py_ssize_t i, l; + int q, b, res; - Dprintf("typecast_array_tokenize: '%s', %d/%d", + Dprintf("typecast_array_tokenize: '%s', " + FORMAT_CODE_PY_SSIZE_T "/" FORMAT_CODE_PY_SSIZE_T, &str[*pos], *pos, strlength); /* we always get called with pos pointing at the start of a token, so a @@ -122,10 +125,11 @@ typecast_array_tokenize(char *str, int strlength, if (str[*pos] == '"') { *pos += 1; l -= 2; - *quotes = 1; + *quotes = 1; } if (res == ASCAN_QUOTED) { + Py_ssize_t j; char *buffer = PyMem_Malloc(l+1); if (buffer == NULL) return ASCAN_ERROR; @@ -138,7 +142,10 @@ typecast_array_tokenize(char *str, int strlength, } *buffer = '\0'; - *length = buffer - *token; + /* The variable that was used to indicate the size of buffer is of type + * Py_ssize_t, so a subsegment of buffer couldn't possibly exceed + * PY_SSIZE_T_MAX: */ + *length = (Py_ssize_t) (buffer - *token); } else { *token = &str[*pos]; @@ -154,31 +161,35 @@ typecast_array_tokenize(char *str, int strlength, } static int -typecast_array_scan(char *str, int strlength, +typecast_array_scan(char *str, Py_ssize_t strlength, PyObject *curs, PyObject *base, PyObject *array) { - int state, quotes, length = 0, pos = 0; + int state, quotes; + Py_ssize_t length = 0, pos = 0; char *token; PyObject *stack[MAX_DIMENSIONS]; - int stack_index = 0; + size_t stack_index = 0; while (1) { token = NULL; state = typecast_array_tokenize(str, strlength, &pos, &token, &length, "es); - Dprintf("typecast_array_scan: state = %d, length = %d, token = '%s'", + Dprintf("typecast_array_scan: state = %d," + " length = " FORMAT_CODE_PY_SSIZE_T ", token = '%s'", state, length, token); if (state == ASCAN_TOKEN || state == ASCAN_QUOTED) { PyObject *obj; - if (!quotes && length == 4 - && (token[0] == 'n' || token[0] == 'N') - && (token[1] == 'u' || token[1] == 'U') - && (token[2] == 'l' || token[2] == 'L') - && (token[3] == 'l' || token[3] == 'L')) - obj = typecast_cast(base, NULL, 0, curs); - else + if (!quotes && length == 4 + && (token[0] == 'n' || token[0] == 'N') + && (token[1] == 'u' || token[1] == 'U') + && (token[2] == 'l' || token[2] == 'L') + && (token[3] == 'l' || token[3] == 'L')) + { + obj = typecast_cast(base, NULL, 0, curs); + } else { obj = typecast_cast(base, token, length, curs); + } /* before anything else we free the memory */ if (state == ASCAN_QUOTED) PyMem_Free(token); @@ -224,12 +235,13 @@ typecast_array_scan(char *str, int strlength, have to be taken on the single items **/ static PyObject * -typecast_GENERIC_ARRAY_cast(char *str, int len, PyObject *curs) +typecast_GENERIC_ARRAY_cast(char *str, Py_ssize_t len, PyObject *curs) { PyObject *obj = NULL; PyObject *base = ((typecastObject*)((cursorObject*)curs)->caster)->bcast; - Dprintf("typecast_GENERIC_ARRAY_cast: str = '%s', len = %d", str, len); + Dprintf("typecast_GENERIC_ARRAY_cast: str = '%s'," + " len = " FORMAT_CODE_PY_SSIZE_T, str, len); if (str == NULL) {Py_INCREF(Py_None); return Py_None;} if (str[0] == '[') @@ -239,7 +251,8 @@ typecast_GENERIC_ARRAY_cast(char *str, int len, PyObject *curs) return NULL; } - Dprintf("typecast_GENERIC_ARRAY_cast: str = '%s', len = %d", str, len); + Dprintf("typecast_GENERIC_ARRAY_cast: str = '%s'," + " len = " FORMAT_CODE_PY_SSIZE_T, str, len); obj = PyList_New(0); diff --git a/psycopg/typecast_basic.c b/psycopg/typecast_basic.c index e9ac7f49..5dd4fdaa 100644 --- a/psycopg/typecast_basic.c +++ b/psycopg/typecast_basic.c @@ -22,13 +22,13 @@ /** INTEGER - cast normal integers (4 bytes) to python int **/ static PyObject * -typecast_INTEGER_cast(char *s, int len, PyObject *curs) +typecast_INTEGER_cast(char *s, Py_ssize_t len, PyObject *curs) { char buffer[12]; - + if (s == NULL) {Py_INCREF(Py_None); return Py_None;} if (s[len] != '\0') { - strncpy(buffer, s, len); buffer[len] = '\0'; + strncpy(buffer, s, (size_t) len); buffer[len] = '\0'; s = buffer; } return PyInt_FromString(s, NULL, 0); @@ -37,13 +37,13 @@ typecast_INTEGER_cast(char *s, int len, PyObject *curs) /** LONGINTEGER - cast long integers (8 bytes) to python long **/ static PyObject * -typecast_LONGINTEGER_cast(char *s, int len, PyObject *curs) +typecast_LONGINTEGER_cast(char *s, Py_ssize_t len, PyObject *curs) { char buffer[24]; - + if (s == NULL) {Py_INCREF(Py_None); return Py_None;} if (s[len] != '\0') { - strncpy(buffer, s, len); buffer[len] = '\0'; + strncpy(buffer, s, (size_t) len); buffer[len] = '\0'; s = buffer; } return PyLong_FromString(s, NULL, 0); @@ -52,11 +52,11 @@ typecast_LONGINTEGER_cast(char *s, int len, PyObject *curs) /** FLOAT - cast floating point numbers to python float **/ static PyObject * -typecast_FLOAT_cast(char *s, int len, PyObject *curs) +typecast_FLOAT_cast(char *s, Py_ssize_t len, PyObject *curs) { PyObject *str = NULL, *flo = NULL; char *pend; - + if (s == NULL) {Py_INCREF(Py_None); return Py_None;} str = PyString_FromStringAndSize(s, len); flo = PyFloat_FromString(str, &pend); @@ -67,7 +67,7 @@ typecast_FLOAT_cast(char *s, int len, PyObject *curs) /** STRING - cast strings of any type to python string **/ static PyObject * -typecast_STRING_cast(char *s, int len, PyObject *curs) +typecast_STRING_cast(char *s, Py_ssize_t len, PyObject *curs) { if (s == NULL) {Py_INCREF(Py_None); return Py_None;} return PyString_FromStringAndSize(s, len); @@ -76,7 +76,7 @@ typecast_STRING_cast(char *s, int len, PyObject *curs) /** UNICODE - cast strings of any type to a python unicode object **/ static PyObject * -typecast_UNICODE_cast(char *s, int len, PyObject *curs) +typecast_UNICODE_cast(char *s, Py_ssize_t len, PyObject *curs) { PyObject *enc; @@ -91,14 +91,14 @@ typecast_UNICODE_cast(char *s, int len, PyObject *curs) PyErr_Format(InterfaceError, "can't decode into unicode string from %s", ((cursorObject*)curs)->conn->encoding); - return NULL; + return NULL; } } /** BOOLEAN - cast boolean value into right python object **/ static PyObject * -typecast_BOOLEAN_cast(char *s, int len, PyObject *curs) +typecast_BOOLEAN_cast(char *s, Py_ssize_t len, PyObject *curs) { PyObject *res; @@ -117,16 +117,16 @@ typecast_BOOLEAN_cast(char *s, int len, PyObject *curs) #ifdef HAVE_DECIMAL static PyObject * -typecast_DECIMAL_cast(char *s, int len, PyObject *curs) +typecast_DECIMAL_cast(char *s, Py_ssize_t len, PyObject *curs) { PyObject *res = NULL; char *buffer; - + if (s == NULL) {Py_INCREF(Py_None); return Py_None;} if ((buffer = PyMem_Malloc(len+1)) == NULL) PyErr_NoMemory(); - strncpy(buffer, s, len); buffer[len] = '\0'; + strncpy(buffer, s, (size_t) len); buffer[len] = '\0'; res = PyObject_CallFunction(decimalType, "s", buffer); PyMem_Free(buffer); @@ -135,7 +135,7 @@ typecast_DECIMAL_cast(char *s, int len, PyObject *curs) #else #define typecast_DECIMAL_cast typecast_FLOAT_cast #endif - + /* some needed aliases */ #define typecast_NUMBER_cast typecast_FLOAT_cast #define typecast_ROWID_cast typecast_INTEGER_cast diff --git a/psycopg/typecast_datetime.c b/psycopg/typecast_datetime.c index 81a71a46..f8b4f1fb 100644 --- a/psycopg/typecast_datetime.c +++ b/psycopg/typecast_datetime.c @@ -34,7 +34,7 @@ extern PyObject *pyDeltaTypeP; /** DATE - cast a date into a date python object **/ static PyObject * -typecast_PYDATE_cast(char *str, int len, PyObject *curs) +typecast_PYDATE_cast(char *str, Py_ssize_t len, PyObject *curs) { PyObject* obj = NULL; int n, y=0, m=0, d=0; @@ -53,7 +53,8 @@ typecast_PYDATE_cast(char *str, int len, PyObject *curs) else { n = typecast_parse_date(str, NULL, &len, &y, &m, &d); Dprintf("typecast_PYDATE_cast: " - "n = %d, len = %d, y = %d, m = %d, d = %d", + "n = %d, len = " FORMAT_CODE_PY_SSIZE_T ", " + "y = %d, m = %d, d = %d", n, len, y, m, d); if (n != 3) { PyErr_SetString(DataError, "unable to parse date"); @@ -69,7 +70,7 @@ typecast_PYDATE_cast(char *str, int len, PyObject *curs) /** DATETIME - cast a timestamp into a datetime python object **/ static PyObject * -typecast_PYDATETIME_cast(char *str, int len, PyObject *curs) +typecast_PYDATETIME_cast(char *str, Py_ssize_t len, PyObject *curs) { PyObject* obj = NULL; int n, y=0, m=0, d=0; @@ -92,7 +93,8 @@ typecast_PYDATETIME_cast(char *str, int len, PyObject *curs) Dprintf("typecast_PYDATETIME_cast: s = %s", str); n = typecast_parse_date(str, &tp, &len, &y, &m, &d); Dprintf("typecast_PYDATE_cast: tp = %p " - "n = %d, len = %d, y = %d, m = %d, d = %d", + "n = %d, len = " FORMAT_CODE_PY_SSIZE_T "," + " y = %d, m = %d, d = %d", tp, n, len, y, m, d); if (n != 3) { PyErr_SetString(DataError, "unable to parse date"); @@ -100,8 +102,9 @@ typecast_PYDATETIME_cast(char *str, int len, PyObject *curs) if (len > 0) { n = typecast_parse_time(tp, NULL, &len, &hh, &mm, &ss, &us, &tz); - Dprintf("typecast_PYDATETIME_cast: n = %d, len = %d, " - "hh = %d, mm = %d, ss = %d, us = %d, tz = %d", + Dprintf("typecast_PYDATETIME_cast: n = %d," + " len = " FORMAT_CODE_PY_SSIZE_T "," + " hh = %d, mm = %d, ss = %d, us = %d, tz = %d", n, len, hh, mm, ss, us, tz); if (n < 3 || n > 5) { PyErr_SetString(DataError, "unable to parse time"); @@ -141,7 +144,7 @@ typecast_PYDATETIME_cast(char *str, int len, PyObject *curs) /** TIME - parse time into a time object **/ static PyObject * -typecast_PYTIME_cast(char *str, int len, PyObject *curs) +typecast_PYTIME_cast(char *str, Py_ssize_t len, PyObject *curs) { PyObject* obj = NULL; int n, hh=0, mm=0, ss=0, us=0, tz=0; @@ -149,7 +152,7 @@ typecast_PYTIME_cast(char *str, int len, PyObject *curs) if (str == NULL) {Py_INCREF(Py_None); return Py_None;} n = typecast_parse_time(str, NULL, &len, &hh, &mm, &ss, &us, &tz); - Dprintf("typecast_PYTIME_cast: n = %d, len = %d, " + Dprintf("typecast_PYTIME_cast: n = %d, len = " FORMAT_CODE_PY_SSIZE_T ", " "hh = %d, mm = %d, ss = %d, us = %d, tz = %d", n, len, hh, mm, ss, us, tz); @@ -169,7 +172,7 @@ typecast_PYTIME_cast(char *str, int len, PyObject *curs) /** INTERVAL - parse an interval into a timedelta object **/ static PyObject * -typecast_PYINTERVAL_cast(char *str, int len, PyObject *curs) +typecast_PYINTERVAL_cast(char *str, Py_ssize_t len, PyObject *curs) { long years = 0, months = 0, days = 0; double hours = 0.0, minutes = 0.0, seconds = 0.0, hundredths = 0.0; diff --git a/psycopg/typecast_mxdatetime.c b/psycopg/typecast_mxdatetime.c index 52b1ce7f..85809da4 100644 --- a/psycopg/typecast_mxdatetime.c +++ b/psycopg/typecast_mxdatetime.c @@ -28,16 +28,16 @@ extern mxDateTimeModule_APIObject *mxDateTimeP; /** DATE - cast a date into mx.DateTime python object **/ static PyObject * -typecast_MXDATE_cast(char *str, int len, PyObject *curs) +typecast_MXDATE_cast(char *str, Py_ssize_t len, PyObject *curs) { int n, y=0, m=0, d=0; int hh=0, mm=0, ss=0, us=0, tz=0; char *tp = NULL; - + if (str == NULL) {Py_INCREF(Py_None); return Py_None;} - + Dprintf("typecast_MXDATE_cast: s = %s", str); - + /* check for infinity */ if (!strcmp(str, "infinity") || !strcmp(str, "-infinity")) { if (str[0] == '-') { @@ -47,24 +47,26 @@ typecast_MXDATE_cast(char *str, int len, PyObject *curs) return mxDateTimeP->DateTime_FromDateAndTime(999999,12,31, 0,0,0); } } - + n = typecast_parse_date(str, &tp, &len, &y, &m, &d); - Dprintf("typecast_MXDATE_cast: tp = %p n = %d, len = %d, " - "y = %d, m = %d, d = %d", tp, n, len, y, m, d); + Dprintf("typecast_MXDATE_cast: tp = %p n = %d," + " len = " FORMAT_CODE_PY_SSIZE_T "," + " y = %d, m = %d, d = %d", tp, n, len, y, m, d); if (n != 3) { PyErr_SetString(DataError, "unable to parse date"); } - + if (len > 0) { n = typecast_parse_time(tp, NULL, &len, &hh, &mm, &ss, &us, &tz); - Dprintf("typecast_MXDATE_cast: n = %d, len = %d, " - "hh = %d, mm = %d, ss = %d, us = %d, tz = %d", + Dprintf("typecast_MXDATE_cast: n = %d," + " len = " FORMAT_CODE_PY_SSIZE_T "," + " hh = %d, mm = %d, ss = %d, us = %d, tz = %d", n, len, hh, mm, ss, us, tz); if (n < 3 || n > 5) { PyErr_SetString(DataError, "unable to parse time"); } - } - + } + Dprintf("typecast_MXDATE_cast: fractionary seconds: %lf", (double)ss + (double)us/(double)1000000.0); return mxDateTimeP->DateTime_FromDateAndTime(y, m, d, hh, mm, @@ -74,19 +76,19 @@ typecast_MXDATE_cast(char *str, int len, PyObject *curs) /** TIME - parse time into an mx.DateTime object **/ static PyObject * -typecast_MXTIME_cast(char *str, int len, PyObject *curs) +typecast_MXTIME_cast(char *str, Py_ssize_t len, PyObject *curs) { int n, hh=0, mm=0, ss=0, us=0, tz=0; if (str == NULL) {Py_INCREF(Py_None); return Py_None;} - + Dprintf("typecast_MXTIME_cast: s = %s", str); - + n = typecast_parse_time(str, NULL, &len, &hh, &mm, &ss, &us, &tz); Dprintf("typecast_MXTIME_cast: time parsed, %d components", n); Dprintf("typecast_MXTIME_cast: hh = %d, mm = %d, ss = %d, us = %d", hh, mm, ss, us); - + if (n < 3 || n > 5) { PyErr_SetString(DataError, "unable to parse time"); return NULL; @@ -101,7 +103,7 @@ typecast_MXTIME_cast(char *str, int len, PyObject *curs) /** INTERVAL - parse an interval into an mx.DateTimeDelta **/ static PyObject * -typecast_MXINTERVAL_cast(char *str, int len, PyObject *curs) +typecast_MXINTERVAL_cast(char *str, Py_ssize_t len, PyObject *curs) { long years = 0, months = 0, days = 0, denominator = 1; double hours = 0.0, minutes = 0.0, seconds = 0.0, hundredths = 0.0; @@ -109,9 +111,9 @@ typecast_MXINTERVAL_cast(char *str, int len, PyObject *curs) int part = 0; if (str == NULL) {Py_INCREF(Py_None); return Py_None;} - + Dprintf("typecast_MXINTERVAL_cast: s = %s", str); - + while (*str) { switch (*str) { @@ -179,12 +181,12 @@ typecast_MXINTERVAL_cast(char *str, int len, PyObject *curs) Dprintf("typecast_MXINTERVAL_cast: seconds = %f", seconds); v = 0.0; part = 6; } - break; + break; default: break; } - + str++; } @@ -203,7 +205,7 @@ typecast_MXINTERVAL_cast(char *str, int len, PyObject *curs) hundredths = hundredths/denominator; Dprintf("typecast_MXINTERVAL_cast: fractions = %.20f", hundredths); } - + /* calculates seconds */ if (sign < 0.0) { seconds = - (hundredths + seconds + minutes*60 + hours*3600); @@ -214,7 +216,7 @@ typecast_MXINTERVAL_cast(char *str, int len, PyObject *curs) /* calculates days */ days += years*365 + months*30; - + Dprintf("typecast_MXINTERVAL_cast: days = %ld, seconds = %f", days, seconds); return mxDateTimeP->DateTimeDelta_FromDaysAndSeconds(days, seconds); @@ -222,7 +224,7 @@ typecast_MXINTERVAL_cast(char *str, int len, PyObject *curs) /* psycopg defaults to using mx types */ -#ifdef PSYCOPG_DEFAULT_MXDATETIME +#ifdef PSYCOPG_DEFAULT_MXDATETIME #define typecast_DATE_cast typecast_MXDATE_cast #define typecast_TIME_cast typecast_MXTIME_cast #define typecast_INTERVAL_cast typecast_MXINTERVAL_cast