Skip to content

Commit 03ee519

Browse files
Implement BSON to JSON encoder that limits encoded string length (#690)
* Implement BSON to JSON encoder that limits encoded string length * CR changes to encoder opts * fix leaks in all_types test * CR fixes Co-authored-by: samantharitter <[email protected]>
1 parent 6f423a4 commit 03ee519

15 files changed

+1022
-33
lines changed
Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
:man_page: bson_as_json_with_opts
2+
3+
bson_as_json_with_opts()
4+
========================
5+
6+
Synopsis
7+
--------
8+
9+
.. code-block:: c
10+
11+
char *
12+
bson_as_json_with_opts (const bson_t *bson, size_t *length, const bson_json_opts_t *opts);
13+
14+
Parameters
15+
----------
16+
17+
* ``bson``: A :symbol:`bson_t`.
18+
* ``length``: An optional location for the length of the resulting string.
19+
* ``opts``: A :symbol:`bson_json_opts_t`.
20+
21+
Description
22+
-----------
23+
24+
The :symbol:`bson_as_json_with_opts()` encodes ``bson`` as a UTF-8 string in the `MongoDB Extended JSON format`_.
25+
26+
The caller is responsible for freeing the resulting UTF-8 encoded string by calling :symbol:`bson_free()` with the result.
27+
28+
If non-NULL, ``length`` will be set to the length of the result in bytes.
29+
30+
The ``opts`` structure is used to pass options for the encoding process. Please refer to the documentation of :symbol:`bson_json_opts_t` for more details.
31+
32+
Returns
33+
-------
34+
35+
If successful, a newly allocated UTF-8 encoded string and ``length`` is set.
36+
37+
Upon failure, NULL is returned.
38+
39+
Example
40+
-------
41+
42+
.. code-block:: c
43+
44+
bson_json_opts_t *opts = bson_json_opts_new (BSON_JSON_MODE_CANONICAL, BSON_MAX_LEN_UNLIMITED);
45+
char *str = bson_as_json_with_opts (doc, NULL, opts);
46+
printf ("%s\n", str);
47+
bson_free (str);
48+
bson_json_opts_destroy (opts);
49+
50+
51+
.. only:: html
52+
53+
.. include:: includes/seealso/bson-as-json.txt
54+
55+
.. _MongoDB Extended JSON format: https://github.com/mongodb/specifications/blob/master/source/extended-json.rst

src/libbson/doc/bson_json_mode_t.rst

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
:man_page: bson_json_mode_t
2+
3+
bson_json_mode_t
4+
================
5+
6+
BSON JSON encoding mode enumeration
7+
8+
Synopsis
9+
--------
10+
11+
.. code-block:: c
12+
13+
#include <bson/bson.h>
14+
15+
typedef enum {
16+
BSON_JSON_MODE_LEGACY,
17+
BSON_JSON_MODE_CANONICAL,
18+
BSON_JSON_MODE_RELAXED,
19+
} bson_json_mode_t;
20+
21+
Description
22+
-----------
23+
24+
The :symbol:`bson_json_mode_t` enumeration contains all available modes for encoding BSON into `MongoDB Extended JSON`_.
25+
26+
.. seealso::
27+
28+
| :symbol:`bson_as_json_with_opts()`
29+
30+
.. _MongoDB Extended JSON: https://github.com/mongodb/specifications/blob/master/source/extended-json.rst
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
:man_page: bson_json_opts_destroy
2+
3+
bson_json_opts_destroy()
4+
========================
5+
6+
Synopsis
7+
--------
8+
9+
.. code-block:: c
10+
11+
void
12+
bson_json_opts_destroy (bson_json_opts_t *opts);
13+
14+
Parameters
15+
----------
16+
17+
* ``opts``: A :symbol:`bson_json_opts_t`.
18+
19+
Description
20+
-----------
21+
22+
Destroys and releases all resources associated with ``opts``. Does nothing if ``opts`` is NULL.
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
:man_page: bson_json_opts_new
2+
3+
bson_json_opts_new()
4+
====================
5+
6+
Synopsis
7+
--------
8+
9+
.. code-block:: c
10+
11+
bson_json_opts_t *
12+
bson_json_opts_new (bson_json_mode_t mode, int32_t max_len);
13+
14+
Parameters
15+
----------
16+
17+
* ``mode``: A bson_json_mode_t.
18+
* ``max_len``: An int32_t.
19+
20+
Description
21+
-----------
22+
23+
The :symbol:`bson_json_opts_new()` function shall create a new :symbol:`bson_json_opts_t` using the mode and length supplied. The ``mode`` member is a :symbol:`bson_json_mode_t` defining the encoding mode.
24+
25+
The ``max_len`` member holds a maximum length for the resulting JSON string. Encoding will stop once the serialised string has reached this length. To encode the full BSON document, ``BSON_MAX_LEN_UNLIMITED`` can be used.
26+
27+
Returns
28+
-------
29+
30+
A newly allocated :symbol:`bson_json_opts_t`.
31+

src/libbson/doc/bson_json_opts_t.rst

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
:man_page: bson_json_opts_t
2+
3+
bson_json_opts_t
4+
================
5+
6+
BSON to JSON encoding options
7+
8+
Synopsis
9+
--------
10+
11+
.. code-block:: c
12+
13+
#include <bson/bson.h>
14+
15+
typedef struct _bson_json_opts_t bson_json_opts_t;
16+
17+
bson_json_opts_t *
18+
bson_json_opts_new (bson_json_mode_t mode, int32_t max_len);
19+
20+
void
21+
bson_json_opts_destroy (bson_json_opts_t *opts);
22+
23+
24+
Description
25+
-----------
26+
27+
The :symbol:`bson_json_opts_t` structure contains options for encoding BSON into `MongoDB Extended JSON`_.
28+
29+
The ``mode`` member is a :symbol:`bson_json_mode_t` defining the encoding mode.
30+
31+
The ``max_len`` member holds a maximum length for the resulting JSON string. Encoding will stop once the serialised string has reached this length. To encode the full BSON document, ``BSON_MAX_LEN_UNLIMITED`` can be used.
32+
33+
.. seealso::
34+
35+
| :symbol:`bson_as_json_with_opts()`
36+
37+
.. _MongoDB Extended JSON: https://github.com/mongodb/specifications/blob/master/source/extended-json.rst
38+
39+
40+
.. only:: html
41+
42+
Functions
43+
---------
44+
45+
.. toctree::
46+
:titlesonly:
47+
:maxdepth: 1
48+
49+
bson_json_opts_new
50+
bson_json_opts_destroy

src/libbson/doc/bson_t.rst

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -184,6 +184,7 @@ The :symbol:`bson_t` structure attempts to use an inline allocation within the s
184184
bson_array_as_json
185185
bson_as_canonical_extended_json
186186
bson_as_json
187+
bson_as_json_with_opts
187188
bson_as_relaxed_extended_json
188189
bson_compare
189190
bson_concat
@@ -201,6 +202,8 @@ The :symbol:`bson_t` structure attempts to use an inline allocation within the s
201202
bson_init
202203
bson_init_from_json
203204
bson_init_static
205+
bson_json_mode_t
206+
bson_json_opts_t
204207
bson_new
205208
bson_new_from_buffer
206209
bson_new_from_data

src/libbson/doc/includes/seealso/bson-as-json.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,4 +6,6 @@
66

77
| :symbol:`bson_as_json()`
88

9+
| :symbol:`bson_as_json_with_opts()`
10+
911
| :symbol:`bson_as_relaxed_extended_json()`

src/libbson/src/bson/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ set (src_libbson_src_bson_DIST_hs
2727
bson-iso8601-private.h
2828
bson-context-private.h
2929
bson-timegm-private.h
30+
bson-json-private.h
3031
forwarding/bson.h
3132
)
3233
extra_dist_generated (
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
/*
2+
* Copyright 2020 MongoDB, Inc.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
#include "bson-prelude.h"
18+
19+
#ifndef BSON_JSON_PRIVATE_H
20+
#define BSON_JSON_PRIVATE_H
21+
22+
23+
struct _bson_json_opts_t {
24+
bson_json_mode_t mode;
25+
int32_t max_len;
26+
};
27+
28+
29+
#endif /* BSON_JSON_PRIVATE_H */

src/libbson/src/bson/bson-json.c

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
#include "bson.h"
2424
#include "bson-config.h"
2525
#include "bson-json.h"
26+
#include "bson-json-private.h"
2627
#include "bson-iso8601-private.h"
2728

2829
#include "common-b64-private.h"
@@ -392,6 +393,25 @@ _noop (void)
392393
}
393394

394395

396+
397+
bson_json_opts_t *
398+
bson_json_opts_new (bson_json_mode_t mode, int32_t max_len)
399+
{
400+
bson_json_opts_t *opts;
401+
402+
opts = (bson_json_opts_t *) bson_malloc (sizeof *opts);
403+
opts->mode = mode;
404+
opts->max_len = max_len;
405+
406+
return opts;
407+
}
408+
409+
void
410+
bson_json_opts_destroy (bson_json_opts_t *opts)
411+
{
412+
bson_free (opts);
413+
}
414+
395415
static void
396416
_bson_json_read_set_error (bson_json_reader_t *reader, const char *fmt, ...)
397417
BSON_GNUC_PRINTF (2, 3);

src/libbson/src/bson/bson-json.h

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,32 @@ typedef enum {
3737
} bson_json_error_code_t;
3838

3939

40+
/**
41+
* BSON_MAX_LEN_UNLIMITED
42+
*
43+
* Denotes unlimited length limit when converting BSON to JSON.
44+
*/
45+
#define BSON_MAX_LEN_UNLIMITED -1
46+
47+
/**
48+
* bson_json_mode_t:
49+
*
50+
* This enumeration contains the different modes to serialize BSON into extended
51+
* JSON.
52+
*/
53+
typedef enum {
54+
BSON_JSON_MODE_LEGACY,
55+
BSON_JSON_MODE_CANONICAL,
56+
BSON_JSON_MODE_RELAXED,
57+
} bson_json_mode_t;
58+
59+
60+
BSON_EXPORT (bson_json_opts_t *)
61+
bson_json_opts_new (bson_json_mode_t mode, int32_t max_len);
62+
BSON_EXPORT (void)
63+
bson_json_opts_destroy (bson_json_opts_t *opts);
64+
65+
4066
typedef ssize_t (*bson_json_reader_cb) (void *handle,
4167
uint8_t *buf,
4268
size_t count);

src/libbson/src/bson/bson-types.h

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,17 @@ typedef enum {
9797
*/
9898
typedef struct _bson_context_t bson_context_t;
9999

100+
/**
101+
* bson_json_opts_t:
102+
*
103+
* This structure is used to pass options for serializing BSON into extended
104+
* JSON to the respective serialization methods.
105+
*
106+
* max_len can be either a non-negative integer, or BSON_MAX_LEN_UNLIMITED to
107+
* set no limit for serialization length.
108+
*/
109+
typedef struct _bson_json_opts_t bson_json_opts_t;
110+
100111

101112
/**
102113
* bson_t:

0 commit comments

Comments
 (0)