diff --git a/psycopg/connection_int.c b/psycopg/connection_int.c index 4c12e1d7..7375da3b 100644 --- a/psycopg/connection_int.c +++ b/psycopg/connection_int.c @@ -250,19 +250,21 @@ conn_get_standard_conforming_strings(PGconn *pgconn) /* Remove irrelevant chars from encoding name and turn it uppercase. * - * Return a buffer allocated on Python heap, - * NULL and set an exception on error. + * Return a buffer allocated on Python heap into 'clean' and return 0 on + * success, otherwise return -1 and set an exception. */ -static char * -clean_encoding_name(const char *enc) +CPYCHECKER_NEGATIVE_RESULT_SETS_EXCEPTION +static int +clear_encoding_name(const char *enc, char **clean) { const char *i = enc; - char *rv, *j; + char *j, *buf; + int rv = -1; /* convert to upper case and remove '-' and '_' from string */ - if (!(j = rv = PyMem_Malloc(strlen(enc) + 1))) { + if (!(j = buf = PyMem_Malloc(strlen(enc) + 1))) { PyErr_NoMemory(); - return NULL; + goto exit; } while (*i) { @@ -275,25 +277,29 @@ clean_encoding_name(const char *enc) } *j = '\0'; - Dprintf("clean_encoding_name: %s -> %s", enc, rv); + Dprintf("clear_encoding_name: %s -> %s", enc, buf); + *clean = buf; + rv = 0; +exit: return rv; } /* Convert a PostgreSQL encoding to a Python codec. * - * Return a new copy of the codec name allocated on the Python heap, - * NULL with exception in case of error. + * Set 'codec' to a new copy of the codec name allocated on the Python heap. + * Return 0 in case of success, else -1 and set an exception. * * 'enc' should be already normalized (uppercase, no - or _). */ -static char * -conn_encoding_to_codec(const char *enc) +CPYCHECKER_NEGATIVE_RESULT_SETS_EXCEPTION +static int +conn_encoding_to_codec(const char *enc, char **codec) { char *tmp; Py_ssize_t size; PyObject *pyenc = NULL; - char *rv = NULL; + int rv = -1; /* Find the Py codec name from the PG encoding */ if (!(pyenc = PyDict_GetItemString(psycoEncodings, enc))) { @@ -313,7 +319,7 @@ conn_encoding_to_codec(const char *enc) } /* have our own copy of the python codec name */ - rv = psycopg_strdup(tmp, size); + rv = psycopg_strdup(codec, tmp, size); exit: Py_XDECREF(pyenc); @@ -343,12 +349,12 @@ conn_read_encoding(connectionObject *self, PGconn *pgconn) goto exit; } - if (!(enc = clean_encoding_name(tmp))) { + if (0 > clear_encoding_name(tmp, &enc)) { goto exit; } /* Look for this encoding in Python codecs. */ - if (!(codec = conn_encoding_to_codec(enc))) { + if (0 > conn_encoding_to_codec(enc, &codec)) { goto exit; } @@ -1141,8 +1147,8 @@ conn_set_client_encoding(connectionObject *self, const char *enc) if (strcmp(self->encoding, enc) == 0) return 0; /* We must know what python codec this encoding is. */ - if (!(clean_enc = clean_encoding_name(enc))) { goto exit; } - if (!(codec = conn_encoding_to_codec(clean_enc))) { goto exit; } + if (0 > clear_encoding_name(enc, &clean_enc)) { goto exit; } + if (0 > conn_encoding_to_codec(clean_enc, &codec)) { goto exit; } Py_BEGIN_ALLOW_THREADS; pthread_mutex_lock(&self->lock); diff --git a/psycopg/psycopg.h b/psycopg/psycopg.h index 60f01b12..0eec1385 100644 --- a/psycopg/psycopg.h +++ b/psycopg/psycopg.h @@ -127,7 +127,7 @@ HIDDEN void psyco_set_error(PyObject *exc, cursorObject *curs, const char *msg, HIDDEN char *psycopg_escape_string(PyObject *conn, const char *from, Py_ssize_t len, char *to, Py_ssize_t *tolen); HIDDEN char *psycopg_escape_identifier_easy(const char *from, Py_ssize_t len); -HIDDEN char *psycopg_strdup(const char *from, Py_ssize_t len); +HIDDEN int psycopg_strdup(char **to, const char *from, Py_ssize_t len); HIDDEN int psycopg_is_text_file(PyObject *f); CPYCHECKER_STEALS_REFERENCE_TO_ARG(1) diff --git a/psycopg/utils.c b/psycopg/utils.c index 4f40cc82..9ae710df 100644 --- a/psycopg/utils.c +++ b/psycopg/utils.c @@ -113,20 +113,20 @@ psycopg_escape_identifier_easy(const char *from, Py_ssize_t len) * Allocate a new buffer on the Python heap containing the new string. * 'len' is optional: if 0 the length is calculated. * - * Return NULL and set an exception in case of error. + * Store the return in 'to' and return 0 in case of success, else return -1 + * and raise an exception. */ -char * -psycopg_strdup(const char *from, Py_ssize_t len) +CPYCHECKER_NEGATIVE_RESULT_SETS_EXCEPTION +int +psycopg_strdup(char **to, const char *from, Py_ssize_t len) { - char *rv; - if (!len) { len = strlen(from); } - if (!(rv = PyMem_Malloc(len + 1))) { + if (!(*to = PyMem_Malloc(len + 1))) { PyErr_NoMemory(); - return NULL; + return -1; } - strcpy(rv, from); - return rv; + strcpy(*to, from); + return 0; } /* Ensure a Python object is a bytes string.