Skip to content

Commit 1ffb42d

Browse files
authored
CDRIVER-4726 make delimiting slash in URI optional (#1713)
* update tests * allow for optional delimiting slash * add failing test and refactor * fix bug of ? appearing in userpass * comments * limit scope of new variables * change hostname to hosts
1 parent e346fff commit 1ffb42d

File tree

4 files changed

+65
-18
lines changed

4 files changed

+65
-18
lines changed

src/libmongoc/src/mongoc/mongoc-uri.c

Lines changed: 40 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1424,6 +1424,32 @@ mongoc_uri_parse (mongoc_uri_t *uri, const char *str, bson_error_t *error)
14241424
}
14251425

14261426
before_slash = scan_to_unichar (str, '/', "", &tmp);
1427+
if (!before_slash) {
1428+
// Handle cases of optional delimiting slash
1429+
char *userpass = NULL;
1430+
char *hosts = NULL;
1431+
1432+
// Skip any "?"s that exist in the userpass
1433+
userpass = scan_to_unichar (str, '@', "", &tmp);
1434+
if (!userpass) {
1435+
// If none found, safely check for "?" indicating beginning of options
1436+
before_slash = scan_to_unichar (str, '?', "", &tmp);
1437+
} else {
1438+
const size_t userpass_len = (size_t) (tmp - str);
1439+
// Otherwise, see if options exist after userpass and concatenate result
1440+
hosts = scan_to_unichar (tmp, '?', "", &tmp);
1441+
1442+
if (hosts) {
1443+
const size_t hosts_len = (size_t) (tmp - str) - userpass_len;
1444+
1445+
before_slash = bson_strndup (str, userpass_len + hosts_len);
1446+
}
1447+
}
1448+
1449+
bson_free (userpass);
1450+
bson_free (hosts);
1451+
}
1452+
14271453
if (!before_slash) {
14281454
before_slash = bson_strdup (str);
14291455
str += strlen (before_slash);
@@ -1438,26 +1464,31 @@ mongoc_uri_parse (mongoc_uri_t *uri, const char *str, bson_error_t *error)
14381464
BSON_ASSERT (str);
14391465

14401466
if (*str) {
1467+
// Check for valid end of hostname delimeter (skip slash if necessary)
1468+
if (*str != '/' && *str != '?') {
1469+
MONGOC_URI_ERROR (error, "%s", "Expected end of hostname delimiter");
1470+
goto error;
1471+
}
1472+
14411473
if (*str == '/') {
1474+
// Try to parse database.
14421475
str++;
14431476
if (*str) {
14441477
if (!mongoc_uri_parse_database (uri, str, &str)) {
14451478
MONGOC_URI_ERROR (error, "%s", "Invalid database name in URI");
14461479
goto error;
14471480
}
14481481
}
1482+
}
14491483

1450-
if (*str == '?') {
1451-
str++;
1452-
if (*str) {
1453-
if (!mongoc_uri_parse_options (uri, str, false /* from DNS */, error)) {
1454-
goto error;
1455-
}
1484+
if (*str == '?') {
1485+
// Try to parse options.
1486+
str++;
1487+
if (*str) {
1488+
if (!mongoc_uri_parse_options (uri, str, false /* from DNS */, error)) {
1489+
goto error;
14561490
}
14571491
}
1458-
} else {
1459-
MONGOC_URI_ERROR (error, "%s", "Expected end of hostname delimiter");
1460-
goto error;
14611492
}
14621493
}
14631494

src/libmongoc/tests/json/connection_uri/invalid-uris.json

Lines changed: 0 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -162,15 +162,6 @@
162162
"auth": null,
163163
"options": null
164164
},
165-
{
166-
"description": "Missing delimiting slash between hosts and options",
167-
"uri": "mongodb://example.com?w=1",
168-
"valid": false,
169-
"warning": null,
170-
"hosts": null,
171-
"auth": null,
172-
"options": null
173-
},
174165
{
175166
"description": "Incomplete key value pair for option",
176167
"uri": "mongodb://example.com/?w",

src/libmongoc/tests/json/connection_uri/valid-options.json

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,23 @@
2020
"options": {
2121
"authmechanism": "MONGODB-CR"
2222
}
23+
},
24+
{
25+
"description": "Missing delimiting slash between hosts and options",
26+
"uri": "mongodb://example.com?tls=true",
27+
"valid": true,
28+
"warning": false,
29+
"hosts": [
30+
{
31+
"type": "hostname",
32+
"host": "example.com",
33+
"port": null
34+
}
35+
],
36+
"auth": null,
37+
"options": {
38+
"tls": true
39+
}
2340
}
2441
]
2542
}

src/libmongoc/tests/test-mongoc-uri.c

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -255,6 +255,14 @@ test_mongoc_uri_new (void)
255255
ASSERT_CMPSTR (mongoc_uri_get_username (uri), "christian@realm");
256256
mongoc_uri_destroy (uri);
257257

258+
/* should recognize a question mark in the userpass instead of mistaking it for the beginning of options */
259+
uri = mongoc_uri_new ("mongodb://us?r:pa?s@localhost?" MONGOC_URI_AUTHMECHANISM "=SCRAM-SHA1");
260+
ASSERT (uri);
261+
ASSERT_CMPSTR (mongoc_uri_get_username (uri), "us?r");
262+
ASSERT_CMPSTR (mongoc_uri_get_password (uri), "pa?s");
263+
ASSERT_CMPSTR (mongoc_uri_get_auth_mechanism (uri), "SCRAM-SHA1");
264+
mongoc_uri_destroy (uri);
265+
258266
/* should fail on invalid escaped characters */
259267
capture_logs (true);
260268
uri = mongoc_uri_new ("mongodb://u%ser:pwd@localhost:27017");

0 commit comments

Comments
 (0)