Skip to content

Commit 5bae13e

Browse files
committed
CDRIVER-598 check URI for bad readPreferenceTags
1 parent 6b1d188 commit 5bae13e

File tree

3 files changed

+40
-16
lines changed

3 files changed

+40
-16
lines changed

NEWS

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ New features and bug fixes:
3535
exported symbols from the internal private ABI.
3636
* mongoc no longer crashes when multi roundtrip bulk operation fails.
3737
* Added support for the new readConcernLevel "linearizable".
38+
* Clients now check for misformatted "readPreferenceTags" in URI.
3839
* New CMake option ENABLE_TRACING allows debug output, which before had only
3940
been available with "configure --enable-tracing".
4041
* Bugfix: "PossiblePrimary"-type replicas could be selected for reads

src/mongoc/mongoc-uri.c

Lines changed: 23 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -462,7 +462,7 @@ mongoc_uri_parse_auth_mechanism_properties (mongoc_uri_t *uri,
462462
return true;
463463
}
464464

465-
static void
465+
static bool
466466
mongoc_uri_parse_tags (mongoc_uri_t *uri, /* IN */
467467
const char *str) /* IN */
468468
{
@@ -476,22 +476,33 @@ mongoc_uri_parse_tags (mongoc_uri_t *uri, /* IN */
476476

477477
again:
478478
if ((keyval = scan_to_unichar(str, ',', "", &end_keyval))) {
479-
if ((key = scan_to_unichar(keyval, ':', "", &end_key))) {
480-
bson_append_utf8(&b, key, -1, end_key + 1, -1);
481-
bson_free(key);
479+
if (!(key = scan_to_unichar(keyval, ':', "", &end_key))) {
480+
bson_free (keyval);
481+
goto fail;
482482
}
483+
484+
bson_append_utf8(&b, key, -1, end_key + 1, -1);
485+
bson_free(key);
483486
bson_free(keyval);
484487
str = end_keyval + 1;
485488
goto again;
486-
} else {
487-
if ((key = scan_to_unichar(str, ':', "", &end_key))) {
488-
bson_append_utf8(&b, key, -1, end_key + 1, -1);
489-
bson_free(key);
490-
}
489+
} else if ((key = scan_to_unichar(str, ':', "", &end_key))) {
490+
bson_append_utf8(&b, key, -1, end_key + 1, -1);
491+
bson_free(key);
492+
} else if (strlen (str)) {
493+
/* we're not finished but we couldn't parse the string */
494+
goto fail;
491495
}
492496

493497
mongoc_read_prefs_add_tag(uri->read_prefs, &b);
494498
bson_destroy(&b);
499+
500+
return true;
501+
502+
fail:
503+
MONGOC_WARNING ("invalid readPreferenceTags: \"%s\"", str);
504+
bson_destroy (&b);
505+
return false;
495506
}
496507

497508

@@ -635,7 +646,9 @@ mongoc_uri_parse_option (mongoc_uri_t *uri,
635646
(0 == strcasecmp (value, "t")) ||
636647
(0 == strcmp (value, "1")));
637648
} else if (!strcasecmp(key, "readpreferencetags")) {
638-
mongoc_uri_parse_tags(uri, value);
649+
if (!mongoc_uri_parse_tags(uri, value)) {
650+
goto CLEANUP;
651+
}
639652
} else if (!strcasecmp(key, "authmechanism") ||
640653
!strcasecmp(key, "authsource")) {
641654
bson_append_utf8(&uri->credentials, key, -1, value, -1);

tests/test-mongoc-uri.c

Lines changed: 16 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -604,6 +604,7 @@ typedef struct
604604
bool parses;
605605
mongoc_read_mode_t mode;
606606
bson_t *tags;
607+
const char *log_msg;
607608
} read_prefs_test;
608609

609610

@@ -631,6 +632,8 @@ test_mongoc_uri_read_prefs (void)
631632
"0", "{", "}"
632633
);
633634

635+
const char *conflicts = "Primary read preference mode conflicts with tags";
636+
634637
const read_prefs_test tests [] = {
635638
{ "mongodb://localhost/", true, MONGOC_READ_PRIMARY, NULL },
636639
{ "mongodb://localhost/?slaveOk=false", true, MONGOC_READ_PRIMARY, NULL },
@@ -643,13 +646,19 @@ test_mongoc_uri_read_prefs (void)
643646
/* readPreference should take priority over slaveOk */
644647
{ "mongodb://localhost/?slaveOk=false&readPreference=secondary", true, MONGOC_READ_SECONDARY, NULL },
645648
/* readPreferenceTags conflict with primary mode */
646-
{ "mongodb://localhost/?readPreferenceTags=", false },
647-
{ "mongodb://localhost/?readPreference=primary&readPreferenceTags=", false },
648-
{ "mongodb://localhost/?slaveOk=false&readPreferenceTags=", false },
649+
{ "mongodb://localhost/?readPreferenceTags=", NULL, MONGOC_READ_PRIMARY, NULL, conflicts },
650+
{ "mongodb://localhost/?readPreference=primary&readPreferenceTags=", NULL, MONGOC_READ_PRIMARY, NULL, conflicts },
651+
{ "mongodb://localhost/?slaveOk=false&readPreferenceTags=", NULL, MONGOC_READ_PRIMARY, NULL, conflicts },
649652
{ "mongodb://localhost/?readPreference=secondaryPreferred&readPreferenceTags=", true, MONGOC_READ_SECONDARY_PREFERRED, tags_empty },
650653
{ "mongodb://localhost/?readPreference=secondaryPreferred&readPreferenceTags=dc:ny", true, MONGOC_READ_SECONDARY_PREFERRED, tags_dcny },
651654
{ "mongodb://localhost/?readPreference=nearest&readPreferenceTags=dc:ny&readPreferenceTags=", true, MONGOC_READ_NEAREST, tags_dcny_empty },
652655
{ "mongodb://localhost/?readPreference=nearest&readPreferenceTags=dc:ny,use:ssd&readPreferenceTags=dc:sf&readPreferenceTags=", true, MONGOC_READ_NEAREST, tags_dcnyusessd_dcsf_empty },
656+
{ "mongodb://localhost/?readPreference=nearest&readPreferenceTags=foo", false, MONGOC_READ_NEAREST, NULL,
657+
"invalid readPreferenceTags: \"foo\""},
658+
{ "mongodb://localhost/?readPreference=nearest&readPreferenceTags=foo,bar", false, MONGOC_READ_NEAREST, NULL,
659+
"invalid readPreferenceTags: \"foo,bar\""},
660+
{ "mongodb://localhost/?readPreference=nearest&readPreferenceTags=1", false, MONGOC_READ_NEAREST, NULL,
661+
"invalid readPreferenceTags: \"1\""},
653662
{ NULL }
654663
};
655664

@@ -663,9 +672,10 @@ test_mongoc_uri_read_prefs (void)
663672
ASSERT_NO_CAPTURED_LOGS (t->uri);
664673
} else {
665674
assert(!uri);
666-
ASSERT_CAPTURED_LOG (
667-
t->uri, MONGOC_LOG_LEVEL_WARNING,
668-
"Primary read preference mode conflicts with tags");
675+
if (t->log_msg) {
676+
ASSERT_CAPTURED_LOG (t->uri, MONGOC_LOG_LEVEL_WARNING, t->log_msg);
677+
}
678+
669679
continue;
670680
}
671681

0 commit comments

Comments
 (0)