Skip to content
This repository was archived by the owner on Oct 13, 2020. It is now read-only.

Commit f9c179b

Browse files
committed
CDRIVER-2128 ensure regex options are sorted
Ensure that the regex option flags "ilmsux" are stored in sorted order, even when passed to bson_append_regex.
1 parent fcafbfb commit f9c179b

File tree

5 files changed

+72
-21
lines changed

5 files changed

+72
-21
lines changed

src/bson/bson-private.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,8 @@ typedef struct {
8686
BSON_STATIC_ASSERT (sizeof (bson_impl_alloc_t) <= 128);
8787

8888

89+
#define BSON_REGEX_OPTIONS_SORTED "ilmsux"
90+
8991
BSON_END_DECLS
9092

9193

src/bson/bson.c

Lines changed: 28 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1512,7 +1512,9 @@ bson_append_regex (bson_t *bson,
15121512
{
15131513
static const uint8_t type = BSON_TYPE_REGEX;
15141514
uint32_t regex_len;
1515-
uint32_t options_len;
1515+
bson_string_t *options_sorted;
1516+
const char *c;
1517+
bool r;
15161518

15171519
BSON_ASSERT (bson);
15181520
BSON_ASSERT (key);
@@ -1530,21 +1532,31 @@ bson_append_regex (bson_t *bson,
15301532
}
15311533

15321534
regex_len = (int) strlen (regex) + 1;
1533-
options_len = (int) strlen (options) + 1;
1535+
options_sorted = bson_string_new (NULL);
15341536

1535-
return _bson_append (bson,
1536-
5,
1537-
(1 + key_length + 1 + regex_len + options_len),
1538-
1,
1539-
&type,
1540-
key_length,
1541-
key,
1542-
1,
1543-
&gZero,
1544-
regex_len,
1545-
regex,
1546-
options_len,
1547-
options);
1537+
for (c = BSON_REGEX_OPTIONS_SORTED; *c; c++) {
1538+
if (strchr (options, *c)) {
1539+
bson_string_append_c (options_sorted, *c);
1540+
}
1541+
}
1542+
1543+
r = _bson_append (bson,
1544+
5,
1545+
(1 + key_length + 1 + regex_len + options_sorted->len),
1546+
1,
1547+
&type,
1548+
key_length,
1549+
key,
1550+
1,
1551+
&gZero,
1552+
regex_len,
1553+
regex,
1554+
options_sorted->len + 1,
1555+
options_sorted->str);
1556+
1557+
bson_string_free (options_sorted, true);
1558+
1559+
return r;
15481560
}
15491561

15501562

@@ -2744,7 +2756,7 @@ _bson_as_json_visit_regex (const bson_iter_t *iter,
27442756
bson_string_append (state->str, "\", \"options\" : \"");
27452757

27462758
/* sort the options */
2747-
for (c = "ilmsux"; *c; c++) {
2759+
for (c = BSON_REGEX_OPTIONS_SORTED; *c; c++) {
27482760
if (strchr (v_options, *c)) {
27492761
bson_string_append_c (state->str, *c);
27502762
}

tests/test-bcon-basic.c

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -193,10 +193,9 @@ test_regex (void)
193193
bson_init (&bcon);
194194
bson_init (&expected);
195195

196-
bson_append_regex (&expected, "foo", -1, "^foo|bar$", "i");
197-
198-
BCON_APPEND (&bcon, "foo", BCON_REGEX ("^foo|bar$", "i"));
199-
196+
/* option flags are sorted */
197+
bson_append_regex (&expected, "foo", -1, "^foo|bar$", "mis");
198+
BCON_APPEND (&bcon, "foo", BCON_REGEX ("^foo|bar$", "msi"));
200199
bson_eq_bson (&bcon, &expected);
201200

202201
bson_destroy (&bcon);

tests/test-bson-corpus.c

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -70,8 +70,11 @@ github.com/mongodb/specifications/blob/master/source/bson-corpus/bson-corpus.rst
7070
* bson_to_canonical_extended_json(dB) = cE
7171
* bson_to_relaxed_extended_json(dB) = rE (if rE exists)
7272
73+
* for dE input (if it exists):
74+
* json_to_bson(dE) = cB (unless lossy)
75+
7376
* for rE input (if it exists):
74-
bson_to_relaxed_extended_json( json_to_bson(rE) ) = rE
77+
bson_to_relaxed_extended_json(json_to_bson(rE)) = rE
7578
7679
*/
7780
static void
@@ -133,6 +136,11 @@ test_bson_corpus (test_bson_type_t *test)
133136
ASSERT_OR_PRINT (decode_dE, error);
134137
ASSERT_CMPJSON (bson_as_extended_json (decode_dE, NULL), test->cE);
135138

139+
if (!test->lossy) {
140+
compare_data (
141+
bson_get_data (decode_dE), decode_dE->len, test->cB, test->cB_len);
142+
}
143+
136144
bson_destroy (decode_dE);
137145
}
138146

tests/test-json.c

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -841,6 +841,33 @@ test_bson_json_read_legacy_regex (void)
841841
}
842842

843843

844+
static void
845+
test_bson_json_read_regex_options_order (void)
846+
{
847+
bson_t b;
848+
bson_error_t error;
849+
bool r;
850+
const char *pattern;
851+
const char *flags;
852+
853+
r = bson_init_from_json (
854+
&b, "{\"a\": {\"$regex\": \"\", \"$options\": \"ism\"}}", -1, &error);
855+
ASSERT_OR_PRINT (r, error);
856+
BCON_EXTRACT (&b, "a", BCONE_REGEX (pattern, flags));
857+
ASSERT_CMPSTR (flags, "ims");
858+
859+
bson_destroy (&b);
860+
861+
r = bson_init_from_json (
862+
&b, "{\"a\": {\"$regex\": \"\", \"$options\": \"misl\"}}", -1, &error);
863+
ASSERT_OR_PRINT (r, error);
864+
BCON_EXTRACT (&b, "a", BCONE_REGEX (pattern, flags));
865+
ASSERT_CMPSTR (flags, "ilms");
866+
867+
bson_destroy (&b);
868+
}
869+
870+
844871
static void
845872
test_bson_json_read_binary (void)
846873
{
@@ -2396,6 +2423,9 @@ test_json_install (TestSuite *suite)
23962423
suite, "/bson/json/read/dbpointer", test_bson_json_read_dbpointer);
23972424
TestSuite_Add (
23982425
suite, "/bson/json/read/legacy_regex", test_bson_json_read_legacy_regex);
2426+
TestSuite_Add (suite,
2427+
"/bson/json/read/regex_options_order",
2428+
test_bson_json_read_regex_options_order);
23992429
TestSuite_Add (suite, "/bson/json/read/binary", test_bson_json_read_binary);
24002430
TestSuite_Add (suite,
24012431
"/bson/json/read/legacy_binary",

0 commit comments

Comments
 (0)