Skip to content

Implement BSON to JSON encoder that limits encoded string length #690

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 4 commits into from
Jan 8, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
55 changes: 55 additions & 0 deletions src/libbson/doc/bson_as_json_with_opts.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
:man_page: bson_as_json_with_opts

bson_as_json_with_opts()
========================

Synopsis
--------

.. code-block:: c

char *
bson_as_json_with_opts (const bson_t *bson, size_t *length, const bson_json_opts_t *opts);

Parameters
----------

* ``bson``: A :symbol:`bson_t`.
* ``length``: An optional location for the length of the resulting string.
* ``opts``: A :symbol:`bson_json_opts_t`.

Description
-----------

The :symbol:`bson_as_json_with_opts()` encodes ``bson`` as a UTF-8 string in the `MongoDB Extended JSON format`_.

The caller is responsible for freeing the resulting UTF-8 encoded string by calling :symbol:`bson_free()` with the result.

If non-NULL, ``length`` will be set to the length of the result in bytes.

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.

Returns
-------

If successful, a newly allocated UTF-8 encoded string and ``length`` is set.

Upon failure, NULL is returned.

Example
-------

.. code-block:: c

bson_json_opts_t *opts = bson_json_opts_new (BSON_JSON_MODE_CANONICAL, BSON_MAX_LEN_UNLIMITED);
char *str = bson_as_json_with_opts (doc, NULL, opts);
printf ("%s\n", str);
bson_free (str);
bson_json_opts_destroy (opts);


.. only:: html

.. include:: includes/seealso/bson-as-json.txt

.. _MongoDB Extended JSON format: https://github.com/mongodb/specifications/blob/master/source/extended-json.rst
30 changes: 30 additions & 0 deletions src/libbson/doc/bson_json_mode_t.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
:man_page: bson_json_mode_t

bson_json_mode_t
================

BSON JSON encoding mode enumeration

Synopsis
--------

.. code-block:: c

#include <bson/bson.h>

typedef enum {
BSON_JSON_MODE_LEGACY,
BSON_JSON_MODE_CANONICAL,
BSON_JSON_MODE_RELAXED,
} bson_json_mode_t;

Description
-----------

The :symbol:`bson_json_mode_t` enumeration contains all available modes for encoding BSON into `MongoDB Extended JSON`_.

.. seealso::

| :symbol:`bson_as_json_with_opts()`

.. _MongoDB Extended JSON: https://github.com/mongodb/specifications/blob/master/source/extended-json.rst
22 changes: 22 additions & 0 deletions src/libbson/doc/bson_json_opts_destroy.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
:man_page: bson_json_opts_destroy

bson_json_opts_destroy()
========================

Synopsis
--------

.. code-block:: c

void
bson_json_opts_destroy (bson_json_opts_t *opts);

Parameters
----------

* ``opts``: A :symbol:`bson_json_opts_t`.

Description
-----------

Destroys and releases all resources associated with ``opts``. Does nothing if ``opts`` is NULL.
31 changes: 31 additions & 0 deletions src/libbson/doc/bson_json_opts_new.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
:man_page: bson_json_opts_new

bson_json_opts_new()
====================

Synopsis
--------

.. code-block:: c

bson_json_opts_t *
bson_json_opts_new (bson_json_mode_t mode, int32_t max_len);

Parameters
----------

* ``mode``: A bson_json_mode_t.
* ``max_len``: An int32_t.

Description
-----------

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.

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.

Returns
-------

A newly allocated :symbol:`bson_json_opts_t`.

50 changes: 50 additions & 0 deletions src/libbson/doc/bson_json_opts_t.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
:man_page: bson_json_opts_t

bson_json_opts_t
================

BSON to JSON encoding options

Synopsis
--------

.. code-block:: c

#include <bson/bson.h>

typedef struct _bson_json_opts_t bson_json_opts_t;

bson_json_opts_t *
bson_json_opts_new (bson_json_mode_t mode, int32_t max_len);

void
bson_json_opts_destroy (bson_json_opts_t *opts);


Description
-----------

The :symbol:`bson_json_opts_t` structure contains options for encoding BSON into `MongoDB Extended JSON`_.

The ``mode`` member is a :symbol:`bson_json_mode_t` defining the encoding mode.

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.

.. seealso::

| :symbol:`bson_as_json_with_opts()`

.. _MongoDB Extended JSON: https://github.com/mongodb/specifications/blob/master/source/extended-json.rst


.. only:: html

Functions
---------

.. toctree::
:titlesonly:
:maxdepth: 1

bson_json_opts_new
bson_json_opts_destroy
3 changes: 3 additions & 0 deletions src/libbson/doc/bson_t.rst
Original file line number Diff line number Diff line change
Expand Up @@ -184,6 +184,7 @@ The :symbol:`bson_t` structure attempts to use an inline allocation within the s
bson_array_as_json
bson_as_canonical_extended_json
bson_as_json
bson_as_json_with_opts
bson_as_relaxed_extended_json
bson_compare
bson_concat
Expand All @@ -201,6 +202,8 @@ The :symbol:`bson_t` structure attempts to use an inline allocation within the s
bson_init
bson_init_from_json
bson_init_static
bson_json_mode_t
bson_json_opts_t
bson_new
bson_new_from_buffer
bson_new_from_data
Expand Down
2 changes: 2 additions & 0 deletions src/libbson/doc/includes/seealso/bson-as-json.txt
Original file line number Diff line number Diff line change
Expand Up @@ -6,4 +6,6 @@

| :symbol:`bson_as_json()`

| :symbol:`bson_as_json_with_opts()`

| :symbol:`bson_as_relaxed_extended_json()`
1 change: 1 addition & 0 deletions src/libbson/src/bson/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ set (src_libbson_src_bson_DIST_hs
bson-iso8601-private.h
bson-context-private.h
bson-timegm-private.h
bson-json-private.h
forwarding/bson.h
)
extra_dist_generated (
Expand Down
29 changes: 29 additions & 0 deletions src/libbson/src/bson/bson-json-private.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
/*
* Copyright 2020 MongoDB, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

#include "bson-prelude.h"

#ifndef BSON_JSON_PRIVATE_H
#define BSON_JSON_PRIVATE_H


struct _bson_json_opts_t {
bson_json_mode_t mode;
int32_t max_len;
};


#endif /* BSON_JSON_PRIVATE_H */
20 changes: 20 additions & 0 deletions src/libbson/src/bson/bson-json.c
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
#include "bson.h"
#include "bson-config.h"
#include "bson-json.h"
#include "bson-json-private.h"
#include "bson-iso8601-private.h"

#include "common-b64-private.h"
Expand Down Expand Up @@ -392,6 +393,25 @@ _noop (void)
}



bson_json_opts_t *
bson_json_opts_new (bson_json_mode_t mode, int32_t max_len)
{
bson_json_opts_t *opts;

opts = (bson_json_opts_t *) bson_malloc (sizeof *opts);
opts->mode = mode;
opts->max_len = max_len;

return opts;
}

void
bson_json_opts_destroy (bson_json_opts_t *opts)
{
bson_free (opts);
}

static void
_bson_json_read_set_error (bson_json_reader_t *reader, const char *fmt, ...)
BSON_GNUC_PRINTF (2, 3);
Expand Down
26 changes: 26 additions & 0 deletions src/libbson/src/bson/bson-json.h
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,32 @@ typedef enum {
} bson_json_error_code_t;


/**
* BSON_MAX_LEN_UNLIMITED
*
* Denotes unlimited length limit when converting BSON to JSON.
*/
#define BSON_MAX_LEN_UNLIMITED -1

/**
* bson_json_mode_t:
*
* This enumeration contains the different modes to serialize BSON into extended
* JSON.
*/
typedef enum {
BSON_JSON_MODE_LEGACY,
BSON_JSON_MODE_CANONICAL,
BSON_JSON_MODE_RELAXED,
} bson_json_mode_t;


BSON_EXPORT (bson_json_opts_t *)
bson_json_opts_new (bson_json_mode_t mode, int32_t max_len);
BSON_EXPORT (void)
bson_json_opts_destroy (bson_json_opts_t *opts);


typedef ssize_t (*bson_json_reader_cb) (void *handle,
uint8_t *buf,
size_t count);
Expand Down
11 changes: 11 additions & 0 deletions src/libbson/src/bson/bson-types.h
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,17 @@ typedef enum {
*/
typedef struct _bson_context_t bson_context_t;

/**
* bson_json_opts_t:
*
* This structure is used to pass options for serializing BSON into extended
* JSON to the respective serialization methods.
*
* max_len can be either a non-negative integer, or BSON_MAX_LEN_UNLIMITED to
* set no limit for serialization length.
*/
typedef struct _bson_json_opts_t bson_json_opts_t;


/**
* bson_t:
Expand Down
Loading