Skip to content

Commit 00c56e7

Browse files
eramongodbkevinAlbs
authored andcommitted
CDRIVER-4166 permit NULL platform argument to mongoc_handshake_data_append() (#877)
1 parent 2f05513 commit 00c56e7

File tree

2 files changed

+139
-30
lines changed

2 files changed

+139
-30
lines changed

src/libmongoc/src/mongoc/mongoc-handshake.c

Lines changed: 26 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -473,8 +473,7 @@ _append_platform_field (bson_t *doc, const char *platform)
473473
1 +
474474

475475
/* key size */
476-
(int) strlen (HANDSHAKE_PLATFORM_FIELD) +
477-
1 +
476+
(int) strlen (HANDSHAKE_PLATFORM_FIELD) + 1 +
478477

479478
/* 4 bytes for length of string */
480479
4);
@@ -573,7 +572,6 @@ _mongoc_handshake_freeze (void)
573572
/*
574573
* free (*s) and make *s point to *s concated with suffix.
575574
* If *s is NULL it's treated like it's an empty string.
576-
* If suffix is NULL, nothing happens.
577575
*/
578576
static void
579577
_append_and_truncate (char **s, const char *suffix, int max_len)
@@ -583,14 +581,11 @@ _append_and_truncate (char **s, const char *suffix, int max_len)
583581
const int delim_len = (int) strlen (" / ");
584582
int space_for_suffix;
585583

586-
BSON_ASSERT (s);
584+
BSON_ASSERT_PARAM (s);
585+
BSON_ASSERT_PARAM (suffix);
587586

588587
prefix = old_str ? old_str : "";
589588

590-
if (!suffix) {
591-
return;
592-
}
593-
594589
space_for_suffix = max_len - (int) strlen (prefix) - delim_len;
595590

596591
if (space_for_suffix <= 0) {
@@ -628,29 +623,37 @@ mongoc_handshake_data_append (const char *driver_name,
628623
return false;
629624
}
630625

626+
BSON_ASSERT (_mongoc_handshake_get ()->platform);
627+
631628
/* allow practically any size for "platform", we'll trim it down in
632629
* _mongoc_handshake_build_doc_with_application */
633630
platform_space =
634631
HANDSHAKE_MAX_SIZE - (int) strlen (_mongoc_handshake_get ()->platform);
635632

636-
/* we check for an empty string as a special case to avoid an unnecessary
637-
* delimiter being added in front of the string by _append_and_truncate */
638-
if (strcmp (_mongoc_handshake_get ()->platform, "") == 0) {
639-
bson_free (_mongoc_handshake_get ()->platform);
640-
_mongoc_handshake_get ()->platform =
641-
bson_strdup_printf ("%.*s", platform_space, platform);
642-
} else {
643-
_append_and_truncate (
644-
&_mongoc_handshake_get ()->platform, platform, HANDSHAKE_MAX_SIZE);
633+
if (platform) {
634+
/* we check for an empty string as a special case to avoid an unnecessary
635+
* delimiter being added in front of the string by _append_and_truncate */
636+
if (_mongoc_handshake_get ()->platform[0] == '\0') {
637+
bson_free (_mongoc_handshake_get ()->platform);
638+
_mongoc_handshake_get ()->platform =
639+
bson_strdup_printf ("%.*s", platform_space, platform);
640+
} else {
641+
_append_and_truncate (
642+
&_mongoc_handshake_get ()->platform, platform, HANDSHAKE_MAX_SIZE);
643+
}
645644
}
646645

647-
_append_and_truncate (&_mongoc_handshake_get ()->driver_name,
648-
driver_name,
649-
HANDSHAKE_DRIVER_NAME_MAX);
646+
if (driver_name) {
647+
_append_and_truncate (&_mongoc_handshake_get ()->driver_name,
648+
driver_name,
649+
HANDSHAKE_DRIVER_NAME_MAX);
650+
}
650651

651-
_append_and_truncate (&_mongoc_handshake_get ()->driver_version,
652-
driver_version,
653-
HANDSHAKE_DRIVER_VERSION_MAX);
652+
if (driver_version) {
653+
_append_and_truncate (&_mongoc_handshake_get ()->driver_version,
654+
driver_version,
655+
HANDSHAKE_DRIVER_VERSION_MAX);
656+
}
654657

655658
_mongoc_handshake_freeze ();
656659
bson_mutex_unlock (&gHandshakeLock);

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

Lines changed: 113 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -174,11 +174,6 @@ test_mongoc_handshake_data_append_success (void)
174174
const char *driver_version = "version abc";
175175
const char *platform = "./configure -nottoomanyflags";
176176

177-
char big_string[HANDSHAKE_MAX_SIZE];
178-
179-
memset (big_string, 'a', HANDSHAKE_MAX_SIZE - 1);
180-
big_string[HANDSHAKE_MAX_SIZE - 1] = '\0';
181-
182177
_reset_handshake ();
183178
/* Make sure setting the handshake works */
184179
ASSERT (
@@ -187,7 +182,6 @@ test_mongoc_handshake_data_append_success (void)
187182
server = mock_server_new ();
188183
mock_server_run (server);
189184
uri = mongoc_uri_copy (mock_server_get_uri (server));
190-
mongoc_uri_set_option_as_int32 (uri, MONGOC_URI_HEARTBEATFREQUENCYMS, 500);
191185
mongoc_uri_set_option_as_utf8 (uri, MONGOC_URI_APPNAME, "testapp");
192186
pool = test_framework_client_pool_new_from_uri (uri, NULL);
193187

@@ -276,6 +270,116 @@ test_mongoc_handshake_data_append_success (void)
276270
}
277271

278272

273+
static void
274+
test_mongoc_handshake_data_append_null_args (void)
275+
{
276+
mock_server_t *server;
277+
mongoc_uri_t *uri;
278+
mongoc_client_t *client;
279+
mongoc_client_pool_t *pool;
280+
request_t *request;
281+
const bson_t *request_doc;
282+
bson_iter_t iter;
283+
bson_iter_t md_iter;
284+
bson_iter_t inner_iter;
285+
const char *val;
286+
287+
_reset_handshake ();
288+
/* Make sure setting the handshake works */
289+
ASSERT (mongoc_handshake_data_append (NULL, NULL, NULL));
290+
291+
server = mock_server_new ();
292+
mock_server_run (server);
293+
uri = mongoc_uri_copy (mock_server_get_uri (server));
294+
mongoc_uri_set_option_as_utf8 (uri, MONGOC_URI_APPNAME, "testapp");
295+
pool = test_framework_client_pool_new_from_uri (uri, NULL);
296+
297+
/* Force topology scanner to start */
298+
client = mongoc_client_pool_pop (pool);
299+
300+
request = mock_server_receives_legacy_hello (server, NULL);
301+
ASSERT (request);
302+
request_doc = request_get_doc (request, 0);
303+
ASSERT (request_doc);
304+
ASSERT (bson_has_field (request_doc, HANDSHAKE_FIELD));
305+
306+
ASSERT (bson_iter_init_find (&iter, request_doc, HANDSHAKE_FIELD));
307+
ASSERT (bson_iter_recurse (&iter, &md_iter));
308+
309+
ASSERT (bson_iter_find (&md_iter, "application"));
310+
ASSERT (BSON_ITER_HOLDS_DOCUMENT (&md_iter));
311+
ASSERT (bson_iter_recurse (&md_iter, &inner_iter));
312+
ASSERT (bson_iter_find (&inner_iter, "name"));
313+
val = bson_iter_utf8 (&inner_iter, NULL);
314+
ASSERT (val);
315+
ASSERT_CMPSTR (val, "testapp");
316+
317+
/* Make sure driver.name and driver.version and platform are all right */
318+
ASSERT (bson_iter_find (&md_iter, "driver"));
319+
ASSERT (BSON_ITER_HOLDS_DOCUMENT (&md_iter));
320+
ASSERT (bson_iter_recurse (&md_iter, &inner_iter));
321+
ASSERT (bson_iter_find (&inner_iter, "name"));
322+
ASSERT (BSON_ITER_HOLDS_UTF8 (&inner_iter));
323+
val = bson_iter_utf8 (&inner_iter, NULL);
324+
ASSERT (val);
325+
ASSERT (strstr (val, " / ") == NULL); /* No append delimiter */
326+
327+
ASSERT (bson_iter_find (&inner_iter, "version"));
328+
ASSERT (BSON_ITER_HOLDS_UTF8 (&inner_iter));
329+
val = bson_iter_utf8 (&inner_iter, NULL);
330+
ASSERT (val);
331+
ASSERT (strstr (val, " / ") == NULL); /* No append delimiter */
332+
333+
/* Check os type not empty */
334+
ASSERT (bson_iter_find (&md_iter, "os"));
335+
ASSERT (BSON_ITER_HOLDS_DOCUMENT (&md_iter));
336+
ASSERT (bson_iter_recurse (&md_iter, &inner_iter));
337+
338+
ASSERT (bson_iter_find (&inner_iter, "type"));
339+
ASSERT (BSON_ITER_HOLDS_UTF8 (&inner_iter));
340+
val = bson_iter_utf8 (&inner_iter, NULL);
341+
ASSERT (val);
342+
ASSERT (strlen (val) > 0);
343+
344+
/* Check os version valid */
345+
ASSERT (bson_iter_find (&inner_iter, "version"));
346+
ASSERT (BSON_ITER_HOLDS_UTF8 (&inner_iter));
347+
val = bson_iter_utf8 (&inner_iter, NULL);
348+
_check_os_version_valid (val);
349+
350+
/* Check os arch is valid */
351+
ASSERT (bson_iter_find (&inner_iter, "architecture"));
352+
ASSERT (BSON_ITER_HOLDS_UTF8 (&inner_iter));
353+
val = bson_iter_utf8 (&inner_iter, NULL);
354+
ASSERT (val);
355+
_check_arch_string_valid (val);
356+
357+
/* Not checking os_name, as the spec says it can be NULL. */
358+
359+
/* Check platform field ok */
360+
ASSERT (bson_iter_find (&md_iter, "platform"));
361+
ASSERT (BSON_ITER_HOLDS_UTF8 (&md_iter));
362+
val = bson_iter_utf8 (&md_iter, NULL);
363+
ASSERT (val);
364+
/* standard val are < 100, may be truncated on some platform */
365+
if (strlen (val) < 250) {
366+
/* `printf("%s", NULL)` -> "(null)" with libstdc++, libc++, and STL */
367+
ASSERT (strstr (val, "null") == NULL);
368+
}
369+
370+
mock_server_replies_simple (request, "{'ok': 1, 'isWritablePrimary': true}");
371+
request_destroy (request);
372+
373+
/* Cleanup */
374+
mongoc_client_pool_push (pool, client);
375+
mongoc_client_pool_destroy (pool);
376+
mongoc_uri_destroy (uri);
377+
mock_server_destroy (server);
378+
379+
_reset_handshake ();
380+
}
381+
382+
279383
static void
280384
_test_platform (bool platform_oversized)
281385
{
@@ -818,7 +922,6 @@ test_mongoc_handshake_race_condition (void)
818922
BSON_ASSERT (!COMMON_PREFIX (thread_create) (
819923
&threads[j], &handshake_append_worker, NULL));
820924
}
821-
822925
for (j = 0; j < 4; ++j) {
823926
COMMON_PREFIX (thread_join) (threads[j]);
824927
}
@@ -843,6 +946,9 @@ test_handshake_install (TestSuite *suite)
843946
TestSuite_AddMockServerTest (suite,
844947
"/MongoDB/handshake/success",
845948
test_mongoc_handshake_data_append_success);
949+
TestSuite_AddMockServerTest (suite,
950+
"/MongoDB/handshake/null_args",
951+
test_mongoc_handshake_data_append_null_args);
846952
TestSuite_Add (suite,
847953
"/MongoDB/handshake/big_platform",
848954
test_mongoc_handshake_big_platform);

0 commit comments

Comments
 (0)