diff --git a/src/interfaces/libpq/fe-connect.c b/src/interfaces/libpq/fe-connect.c index 64787bea511..61c025ff3bf 100644 --- a/src/interfaces/libpq/fe-connect.c +++ b/src/interfaces/libpq/fe-connect.c @@ -6763,9 +6763,9 @@ conninfo_uri_parse_params(char *params, static char * conninfo_uri_decode(const char *str, PQExpBuffer errorMessage) { - char *buf; - char *p; - const char *q = str; + char *buf; /* result */ + char *p; /* output location */ + const char *q = str; /* input location */ buf = malloc(strlen(str) + 1); if (buf == NULL) @@ -6775,13 +6775,23 @@ conninfo_uri_decode(const char *str, PQExpBuffer errorMessage) } p = buf; + /* skip leading whitespaces */ + for (const char *s = q; *s == ' '; s++) + { + q++; + continue; + } + for (;;) { if (*q != '%') { - /* copy and check for NUL terminator */ - if (!(*(p++) = *(q++))) - break; + /* if found a whitespace or NUL, the string ends */ + if (*q == ' ' || *q == '\0') + goto end; + + /* copy character */ + *(p++) = *(q++); } else { @@ -6817,6 +6827,26 @@ conninfo_uri_decode(const char *str, PQExpBuffer errorMessage) } } +end: + + /* skip trailing whitespaces */ + for (const char *s = q; *s == ' '; s++) + { + q++; + continue; + } + + /* Not at the end of the string yet? Fail. */ + if (*q != '\0') + { + libpq_append_error(errorMessage, "trailing data found: \"%s\"", str); + free(buf); + return NULL; + } + + /* Copy NUL terminator */ + *p = '\0'; + return buf; } diff --git a/src/interfaces/libpq/t/001_uri.pl b/src/interfaces/libpq/t/001_uri.pl index 49ea5377e03..27cf67ae800 100644 --- a/src/interfaces/libpq/t/001_uri.pl +++ b/src/interfaces/libpq/t/001_uri.pl @@ -86,6 +86,24 @@ my @tests = ( q{user='uri-user' host='host' (inet)}, q{}, ], + [ + # Leading and trailing spaces, works. + q{postgresql://host? user = uri-user & port = 12345 }, + q{user='uri-user' host='host' port='12345' (inet)}, + q{}, + ], + [ + # Trailing data in parameter. + q{postgresql://host? user user = uri & port = 12345 12 }, + q{}, + q{libpq_uri_regress: trailing data found: " user user "}, + ], + [ + # Trailing data in value. + q{postgresql://host? user = uri-user & port = 12345 12 }, + q{}, + q{libpq_uri_regress: trailing data found: " 12345 12 "}, + ], [ q{postgresql://host?}, q{host='host' (inet)}, q{}, ], [ q{postgresql://[::1]:12345/db},