Am 18.10.19 um 05:06 schrieb Michael Paquier: > So attached is a patch to skip trailing whitespaces as well, > which also fixes the issue with ECPG. I have refactored the parsing > logic a bit while on it. The comment at the top of parse_int_param() > needs to be reworked a bit more.
I tested this and it looks good to me. Maybe you could omit some redundant 'end' checks, as in the attached patch. Or was your intention to verify non-NULL 'end'? > Perhaps we could add directly regression > tests for libpq. I'll start a new thread about that once we are done > here, the topic is larger. We have around 650 tests on ruby-pg to ensure everything runs as expected and I always wondered how the API of libpq is being verified. -- Kind Regards, Lars Kanis
diff --git a/src/interfaces/libpq/fe-connect.c b/src/interfaces/libpq/fe-connect.c index f91f0f2..0eeabb8 100644 --- a/src/interfaces/libpq/fe-connect.c +++ b/src/interfaces/libpq/fe-connect.c @@ -1687,7 +1687,7 @@ useKeepalives(PGconn *conn) /* * Parse and try to interpret "value" as an integer value, and if successful, * store it in *result, complaining if there is any trailing garbage or an - * overflow. + * overflow. This allows any number of leading and trailing whitespaces. */ static bool parse_int_param(const char *value, int *result, PGconn *conn, @@ -1698,14 +1698,31 @@ parse_int_param(const char *value, int *result, PGconn *conn, *result = 0; + /* strtol(3) skips leading whitespaces */ errno = 0; numval = strtol(value, &end, 10); - if (errno == 0 && *end == '\0' && numval == (int) numval) - { - *result = numval; - return true; - } + /* + * If no progress was done during the parsing or an error happened, fail. + * This tests properly for overflows of the result. + */ + if (value == end || errno != 0 || numval != (int) numval) + goto error; + + /* + * Skip any trailing whitespace; if anything but whitespace remains before + * the terminating character, fail + */ + while (*end != '\0' && isspace((unsigned char) *end)) + end++; + + if (*end != '\0') + goto error; + + *result = numval; + return true; + +error: appendPQExpBuffer(&conn->errorMessage, libpq_gettext("invalid integer value \"%s\" for connection option \"%s\"\n"), value, context); @@ -2008,7 +2025,11 @@ connectDBComplete(PGconn *conn) { if (!parse_int_param(conn->connect_timeout, &timeout, conn, "connect_timeout")) + { + /* mark the connection as bad to report the parsing failure */ + conn->status = CONNECTION_BAD; return 0; + } if (timeout > 0) {