Skip to content
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

Sshirokov/disable buff checks.3.0.preview #358

Draft
wants to merge 3 commits into
base: 3.0.preview
Choose a base branch
from
Draft
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
16 changes: 16 additions & 0 deletions src/nunavut/cli/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -809,6 +809,22 @@ def extension_type(raw_arg: str) -> str:
).lstrip(),
)

ln_opt_group.add_argument(
"--disable-serialization-buffer-check",
action="store_true",
help=textwrap.dedent(
"""

Instruct support header generators to disable entry buffer checks in serialization routines.
Serialization will be still safe (no buffer overflows) but it might fail during the operation
with NUNAVUT_ERROR_SERIALIZATION_BUFFER_TOO_SMALL error if provided buffer ends up being too small.
This option useful for systems with limited resources where messages are known to be small,
and smaller serialization buffers can be used (comparing to the maximum possible capacity).

"""
).lstrip(),
)

ln_opt_group.add_argument(
"--language-standard",
"-std",
Expand Down
4 changes: 4 additions & 0 deletions src/nunavut/cli/parsers.py
Original file line number Diff line number Diff line change
Expand Up @@ -366,6 +366,10 @@ def _create_language_options(cls, args: argparse.Namespace) -> Dict[str, Any]:
True if args.enable_override_variable_array_capacity else DefaultValue(False)
)

language_options["disable_serialization_buffer_check"] = (
True if args.disable_serialization_buffer_check else DefaultValue(False)
)

if args.language_standard is not None:
language_options["std"] = args.language_standard

Expand Down
7 changes: 6 additions & 1 deletion src/nunavut/lang/c/templates/serialization.j2
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
{# ----------------------------------------------------------------------------------------------------------------- #}
{% macro _serialize_impl(t) %}
const {{ typename_unsigned_length }} capacity_bytes = *inout_buffer_size_bytes;
{%- if not options.disable_serialization_buffer_check %}
{%- if options.enable_override_variable_array_capacity %}
#ifndef {{ t | full_reference_name }}_DISABLE_SERIALIZATION_BUFFER_CHECK_
{% endif %}
Expand All @@ -37,6 +38,7 @@
}
{%- if options.enable_override_variable_array_capacity %}
#endif
{% endif %}
{% endif %}
// Notice that fields that are not an integer number of bytes long may overrun the space allocated for them
// in the serialization buffer up to the next byte boundary. This is by design and is guaranteed to be safe.
Expand Down Expand Up @@ -116,8 +118,11 @@
{{ assert('offset_bits % 8U == 0U') }}
{% endif %}
{# NOTICE: If this is a delimited type, we will be requiring the buffer to be at least extent-sized.
# This is a bit wasteful because when serializing we can often use a smaller buffer. #}
# This is a bit wasteful because when serializing we can often use a smaller buffer.
# `disable_serialization_buffer_check` option allows to avoid such waste for variable length arrays. #}
{% if not (t is VariableLengthArrayType and options.disable_serialization_buffer_check) %}
{{ assert('(offset_bits + %dULL) <= (capacity_bytes * 8U)'|format(t.bit_length_set.max)) }}
{% endif %}

{% if t is VoidType %} {{- _serialize_void(t, offset) }}
{% elif t is BooleanType %} {{- _serialize_boolean(t, reference, offset) }}
Expand Down
11 changes: 7 additions & 4 deletions src/nunavut/lang/cpp/templates/serialization.j2
Original file line number Diff line number Diff line change
Expand Up @@ -23,17 +23,18 @@
{# ----------------------------------------------------------------------------------------------------------------- #}
{% macro _serialize_impl(t) %}

const {{ typename_unsigned_length }} capacity_bits = out_buffer.size();

{%- if not options.disable_serialization_buffer_check %}
{%- if options.enable_override_variable_array_capacity %}
#ifndef {{ t | full_macro_name }}_DISABLE_SERIALIZATION_BUFFER_CHECK_
{% endif %}
const {{ typename_unsigned_length }} capacity_bits = out_buffer.size();
if ((static_cast<{{ typename_unsigned_bit_length }}>(capacity_bits)) < {{ t.inner_type.bit_length_set.max }}UL)
{
return -nunavut::support::Error::SerializationBufferTooSmall;
}
{%- if options.enable_override_variable_array_capacity %}
#endif // ndef {{ t | full_macro_name }}_DISABLE_SERIALIZATION_BUFFER_CHECK_
{% endif %}
{% endif %}

// Notice that fields that are not an integer number of bytes long may overrun the space allocated for them
Expand Down Expand Up @@ -113,8 +114,10 @@
{{ assert('out_buffer.offset_alings_to_byte()') }}
{% endif %}
{# NOTICE: If this is a delimited type, we will be requiring the buffer to be at least extent-sized.
# This is a bit wasteful because when serializing we can often use a smaller buffer. #}
{% if t.bit_length_set.max > 0 %}
# This is a bit wasteful because when serializing we can often use a smaller buffer.
# `disable_serialization_buffer_check` option allows to avoid such waste for variable length arrays. #}
{% if (t.bit_length_set.max > 0) and
not (t is VariableLengthArrayType and options.disable_serialization_buffer_check) %}
{{ assert('%dULL <= out_buffer.size()'|format(t.bit_length_set.max)) }}
{% endif %}

Expand Down
2 changes: 2 additions & 0 deletions src/nunavut/lang/properties.json
Original file line number Diff line number Diff line change
Expand Up @@ -249,6 +249,7 @@
"omit_serialization_support": false,
"enable_serialization_asserts": false,
"enable_override_variable_array_capacity": false,
"disable_serialization_buffer_check": false,
"cast_format": "(({type}) {value})"
}
},
Expand Down Expand Up @@ -505,6 +506,7 @@
"omit_serialization_support": false,
"enable_serialization_asserts": false,
"enable_override_variable_array_capacity": false,
"disable_serialization_buffer_check": false,
"std": "c++14",
"std_flavor": "std",
"cast_format": "static_cast<{type}>({value})",
Expand Down
3 changes: 3 additions & 0 deletions test/gentest_nnvg/templates/Any.j2
Original file line number Diff line number Diff line change
Expand Up @@ -12,4 +12,7 @@
{%- if options.enable_override_variable_array_capacity is defined %},
"enable_override_variable_array_capacity": {{ options.enable_override_variable_array_capacity | ln.js.to_true_or_false }}
{% endif %}
{%- if options.disable_serialization_buffer_check is defined %},
"disable_serialization_buffer_check": {{ options.disable_serialization_buffer_check | ln.js.to_true_or_false }}
{% endif %}
}
Loading