Skip to content

Commit bb9526c

Browse files
galon1kevinAlbs
authored andcommitted
CDRIVER-4499 Set bson_error when hello response is malformed (#1129)
CDRIVER-4499 add bson_set_error to invalid types in handle hello
1 parent fa176a5 commit bb9526c

File tree

2 files changed

+68
-27
lines changed

2 files changed

+68
-27
lines changed

src/libmongoc/src/mongoc/mongoc-server-description.c

Lines changed: 34 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -601,33 +601,33 @@ mongoc_server_description_handle_hello (mongoc_server_description_t *sd,
601601
* MUST treat this an authentication error." */
602602
sd->error.domain = MONGOC_ERROR_CLIENT;
603603
sd->error.code = MONGOC_ERROR_CLIENT_AUTHENTICATE;
604-
goto failure;
604+
GOTO (authfailure);
605605
}
606606
} else if (strcmp ("isWritablePrimary", bson_iter_key (&iter)) == 0 ||
607607
strcmp (HANDSHAKE_RESPONSE_LEGACY_HELLO,
608608
bson_iter_key (&iter)) == 0) {
609609
if (!BSON_ITER_HOLDS_BOOL (&iter))
610-
goto failure;
610+
GOTO (typefailure);
611611
is_primary = bson_iter_bool (&iter);
612612
} else if (strcmp ("helloOk", bson_iter_key (&iter)) == 0) {
613613
if (!BSON_ITER_HOLDS_BOOL (&iter))
614-
goto failure;
614+
GOTO (typefailure);
615615
sd->hello_ok = bson_iter_bool (&iter);
616616
} else if (strcmp ("me", bson_iter_key (&iter)) == 0) {
617617
if (!BSON_ITER_HOLDS_UTF8 (&iter))
618-
goto failure;
618+
GOTO (typefailure);
619619
sd->me = bson_iter_utf8 (&iter, NULL);
620620
} else if (strcmp ("maxMessageSizeBytes", bson_iter_key (&iter)) == 0) {
621621
if (!BSON_ITER_HOLDS_INT32 (&iter))
622-
goto failure;
622+
GOTO (typefailure);
623623
sd->max_msg_size = bson_iter_int32 (&iter);
624624
} else if (strcmp ("maxBsonObjectSize", bson_iter_key (&iter)) == 0) {
625625
if (!BSON_ITER_HOLDS_INT32 (&iter))
626-
goto failure;
626+
GOTO (typefailure);
627627
sd->max_bson_obj_size = bson_iter_int32 (&iter);
628628
} else if (strcmp ("maxWriteBatchSize", bson_iter_key (&iter)) == 0) {
629629
if (!BSON_ITER_HOLDS_INT32 (&iter))
630-
goto failure;
630+
GOTO (typefailure);
631631
sd->max_write_batch_size = bson_iter_int32 (&iter);
632632
} else if (strcmp ("logicalSessionTimeoutMinutes",
633633
bson_iter_key (&iter)) == 0) {
@@ -637,72 +637,72 @@ mongoc_server_description_handle_hello (mongoc_server_description_t *sd,
637637
/* this arises executing standard JSON tests */
638638
sd->session_timeout_minutes = MONGOC_NO_SESSIONS;
639639
} else {
640-
goto failure;
640+
GOTO (typefailure);
641641
}
642642
} else if (strcmp ("minWireVersion", bson_iter_key (&iter)) == 0) {
643643
if (!BSON_ITER_HOLDS_INT32 (&iter))
644-
goto failure;
644+
GOTO (typefailure);
645645
sd->min_wire_version = bson_iter_int32 (&iter);
646646
} else if (strcmp ("maxWireVersion", bson_iter_key (&iter)) == 0) {
647647
if (!BSON_ITER_HOLDS_INT32 (&iter))
648-
goto failure;
648+
GOTO (typefailure);
649649
sd->max_wire_version = bson_iter_int32 (&iter);
650650
} else if (strcmp ("msg", bson_iter_key (&iter)) == 0) {
651651
const char *msg;
652652
if (!BSON_ITER_HOLDS_UTF8 (&iter))
653-
goto failure;
653+
GOTO (typefailure);
654654
msg = bson_iter_utf8 (&iter, NULL);
655655
if (msg && 0 == strcmp (msg, "isdbgrid")) {
656656
is_shard = true;
657657
}
658658
} else if (strcmp ("setName", bson_iter_key (&iter)) == 0) {
659659
if (!BSON_ITER_HOLDS_UTF8 (&iter))
660-
goto failure;
660+
GOTO (typefailure);
661661
sd->set_name = bson_iter_utf8 (&iter, NULL);
662662
} else if (strcmp ("setVersion", bson_iter_key (&iter)) == 0) {
663663
mongoc_server_description_set_set_version (sd,
664664
bson_iter_as_int64 (&iter));
665665
} else if (strcmp ("electionId", bson_iter_key (&iter)) == 0) {
666666
if (!BSON_ITER_HOLDS_OID (&iter))
667-
goto failure;
667+
GOTO (typefailure);
668668
mongoc_server_description_set_election_id (sd, bson_iter_oid (&iter));
669669
} else if (strcmp ("secondary", bson_iter_key (&iter)) == 0) {
670670
if (!BSON_ITER_HOLDS_BOOL (&iter))
671-
goto failure;
671+
GOTO (typefailure);
672672
is_secondary = bson_iter_bool (&iter);
673673
} else if (strcmp ("hosts", bson_iter_key (&iter)) == 0) {
674674
if (!BSON_ITER_HOLDS_ARRAY (&iter))
675-
goto failure;
675+
GOTO (typefailure);
676676
bson_iter_array (&iter, &len, &bytes);
677677
bson_destroy (&sd->hosts);
678678
BSON_ASSERT (bson_init_static (&sd->hosts, bytes, len));
679679
} else if (strcmp ("passives", bson_iter_key (&iter)) == 0) {
680680
if (!BSON_ITER_HOLDS_ARRAY (&iter))
681-
goto failure;
681+
GOTO (typefailure);
682682
bson_iter_array (&iter, &len, &bytes);
683683
bson_destroy (&sd->passives);
684684
BSON_ASSERT (bson_init_static (&sd->passives, bytes, len));
685685
} else if (strcmp ("arbiters", bson_iter_key (&iter)) == 0) {
686686
if (!BSON_ITER_HOLDS_ARRAY (&iter))
687-
goto failure;
687+
GOTO (typefailure);
688688
bson_iter_array (&iter, &len, &bytes);
689689
bson_destroy (&sd->arbiters);
690690
BSON_ASSERT (bson_init_static (&sd->arbiters, bytes, len));
691691
} else if (strcmp ("primary", bson_iter_key (&iter)) == 0) {
692692
if (!BSON_ITER_HOLDS_UTF8 (&iter))
693-
goto failure;
693+
GOTO (typefailure);
694694
sd->current_primary = bson_iter_utf8 (&iter, NULL);
695695
} else if (strcmp ("arbiterOnly", bson_iter_key (&iter)) == 0) {
696696
if (!BSON_ITER_HOLDS_BOOL (&iter))
697-
goto failure;
697+
GOTO (typefailure);
698698
is_arbiter = bson_iter_bool (&iter);
699699
} else if (strcmp ("isreplicaset", bson_iter_key (&iter)) == 0) {
700700
if (!BSON_ITER_HOLDS_BOOL (&iter))
701-
goto failure;
701+
GOTO (typefailure);
702702
is_replicaset = bson_iter_bool (&iter);
703703
} else if (strcmp ("tags", bson_iter_key (&iter)) == 0) {
704704
if (!BSON_ITER_HOLDS_DOCUMENT (&iter))
705-
goto failure;
705+
GOTO (typefailure);
706706
bson_iter_document (&iter, &len, &bytes);
707707
bson_destroy (&sd->tags);
708708
BSON_ASSERT (bson_init_static (&sd->tags, bytes, len));
@@ -713,21 +713,21 @@ mongoc_server_description_handle_hello (mongoc_server_description_t *sd,
713713
!bson_iter_recurse (&iter, &child) ||
714714
!bson_iter_find (&child, "lastWriteDate") ||
715715
!BSON_ITER_HOLDS_DATE_TIME (&child)) {
716-
goto failure;
716+
GOTO (typefailure);
717717
}
718718

719719
sd->last_write_date_ms = bson_iter_date_time (&child);
720720
} else if (strcmp ("compression", bson_iter_key (&iter)) == 0) {
721721
if (!BSON_ITER_HOLDS_ARRAY (&iter))
722-
goto failure;
722+
GOTO (typefailure);
723723
bson_iter_array (&iter, &len, &bytes);
724724
bson_destroy (&sd->compressors);
725725
BSON_ASSERT (bson_init_static (&sd->compressors, bytes, len));
726726
} else if (strcmp ("topologyVersion", bson_iter_key (&iter)) == 0) {
727727
bson_t incoming_topology_version;
728728

729729
if (!BSON_ITER_HOLDS_DOCUMENT (&iter)) {
730-
goto failure;
730+
GOTO (typefailure);
731731
}
732732

733733
bson_iter_document (&iter, &len, &bytes);
@@ -737,11 +737,11 @@ mongoc_server_description_handle_hello (mongoc_server_description_t *sd,
737737
bson_destroy (&incoming_topology_version);
738738
} else if (strcmp ("serviceId", bson_iter_key (&iter)) == 0) {
739739
if (!BSON_ITER_HOLDS_OID (&iter))
740-
goto failure;
740+
GOTO (typefailure);
741741
bson_oid_copy_unsafe (bson_iter_oid (&iter), &sd->service_id);
742742
} else if (strcmp ("connectionId", bson_iter_key (&iter)) == 0) {
743743
if (!BSON_ITER_HOLDS_INT (&iter))
744-
goto failure;
744+
GOTO (typefailure);
745745
sd->server_connection_id = bson_iter_as_int64 (&iter);
746746
}
747747
}
@@ -787,7 +787,14 @@ mongoc_server_description_handle_hello (mongoc_server_description_t *sd,
787787

788788
EXIT;
789789

790-
failure:
790+
typefailure:
791+
bson_set_error (&sd->error,
792+
MONGOC_ERROR_STREAM,
793+
MONGOC_ERROR_STREAM_INVALID_TYPE,
794+
"unexpected type %s for field %s in hello response",
795+
_mongoc_bson_type_to_str (bson_iter_type (&iter)),
796+
bson_iter_key (&iter));
797+
authfailure:
791798
sd->type = MONGOC_SERVER_UNKNOWN;
792799
sd->round_trip_time_msec = MONGOC_RTT_UNSET;
793800

src/libmongoc/tests/test-mongoc-server-description.c

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -417,6 +417,37 @@ test_server_description_connection_id (void)
417417
mongoc_server_description_cleanup (&sd);
418418
}
419419

420+
static void
421+
test_server_description_hello_type_error (void)
422+
{
423+
mongoc_server_description_t sd;
424+
bson_error_t error;
425+
const char *hello =
426+
"{"
427+
" 'ok' : { '$numberInt' : '1' },"
428+
" 'ismaster' : true,"
429+
" 'maxBsonObjectSize' : { '$numberInt' : '16777216' },"
430+
" 'maxMessageSizeBytes' : { '$numberInt' : '48000000'},"
431+
" 'maxWriteBatchSize' : { '$numberLong' : '565160423'},"
432+
" 'logicalSessionTimeoutMinutes' : { '$numberInt' : '30'},"
433+
" 'connectionId' : { '$numberLong' : '565160423'},"
434+
" 'minWireVersion' : { '$numberInt' : '0'},"
435+
" 'maxWireVersion' : { '$numberInt' : '15'},"
436+
" 'readOnly' : true"
437+
"}";
438+
mongoc_server_description_init (&sd, "host:1234", 1);
439+
memset (&error, 0, sizeof (bson_error_t));
440+
mongoc_server_description_handle_hello (&sd, tmp_bson (hello), 0, &error);
441+
BSON_ASSERT (sd.type == MONGOC_SERVER_UNKNOWN);
442+
BSON_ASSERT (sd.error.code == MONGOC_ERROR_STREAM_INVALID_TYPE);
443+
ASSERT_ERROR_CONTAINS (sd.error,
444+
MONGOC_ERROR_STREAM,
445+
MONGOC_ERROR_STREAM_INVALID_TYPE,
446+
"unexpected type");
447+
448+
mongoc_server_description_cleanup (&sd);
449+
}
450+
420451
void
421452
test_server_description_install (TestSuite *suite)
422453
{
@@ -442,4 +473,7 @@ test_server_description_install (TestSuite *suite)
442473
TestSuite_Add (suite,
443474
"/server_description/connection_id",
444475
test_server_description_connection_id);
476+
TestSuite_Add (suite,
477+
"/server_description/hello_type_error",
478+
test_server_description_hello_type_error);
445479
}

0 commit comments

Comments
 (0)