summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichael Paquier2019-10-21 02:17:13 +0000
committerMichael Paquier2019-10-21 02:17:13 +0000
commit4f4061b2dde178d2ab79d1ee3b1ae3c62c117926 (patch)
treee95cfe2074fa70f632327e2818d13c64da90f980
parentea9e06ac66d3e9584950f52878c8e4b71f963610 (diff)
Fix parsing of integer values for connection parameters in libpq
Commit e7a2217 has introduced stricter checks for integer values in connection parameters for libpq. However this failed to correctly check after trailing whitespaces, while leading whitespaces were discarded per the use of strtol(3). This fixes and refactors the parsing logic to handle both cases consistently. Note that trying to restrict the use of trailing whitespaces can easily break connection strings like in ECPG regression tests (these have allowed me to catch the parsing bug with connect_timeout). Author: Michael Paquier Reviewed-by: Lars Kanis Discussion: https://postgr.es/m/a9b4cbd7-4ecb-06b2-ebd7-1739bbff3217@greiz-reinsdorf.de Backpatch-through: 12
-rw-r--r--src/interfaces/libpq/fe-connect.c29
1 files changed, 23 insertions, 6 deletions
diff --git a/src/interfaces/libpq/fe-connect.c b/src/interfaces/libpq/fe-connect.c
index f91f0f2efe7..e02564420c1 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 && *end != '\0' && isspace((unsigned char) *end))
+ end++;
+
+ if (*end && *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);