summaryrefslogtreecommitdiff
path: root/tools
diff options
context:
space:
mode:
Diffstat (limited to 'tools')
-rw-r--r--tools/net/sunrpc/xdrgen/generators/enum.py9
-rw-r--r--tools/net/sunrpc/xdrgen/subcmds/source.py3
-rw-r--r--tools/net/sunrpc/xdrgen/templates/C/enum/decoder/enum.j211
-rw-r--r--tools/net/sunrpc/xdrgen/templates/C/enum/decoder/enum_be.j220
-rw-r--r--tools/net/sunrpc/xdrgen/xdr_ast.py6
-rw-r--r--tools/net/sunrpc/xdrgen/xdr_parse.py14
-rwxr-xr-xtools/net/sunrpc/xdrgen/xdrgen6
7 files changed, 62 insertions, 7 deletions
diff --git a/tools/net/sunrpc/xdrgen/generators/enum.py b/tools/net/sunrpc/xdrgen/generators/enum.py
index e62f715d3996..b4ed3ed6431e 100644
--- a/tools/net/sunrpc/xdrgen/generators/enum.py
+++ b/tools/net/sunrpc/xdrgen/generators/enum.py
@@ -5,6 +5,7 @@
from generators import SourceGenerator, create_jinja2_environment
from xdr_ast import _XdrEnum, public_apis, big_endian, get_header_name
+from xdr_parse import get_xdr_enum_validation
class XdrEnumGenerator(SourceGenerator):
@@ -42,7 +43,13 @@ class XdrEnumGenerator(SourceGenerator):
template = self.environment.get_template("decoder/enum_be.j2")
else:
template = self.environment.get_template("decoder/enum.j2")
- print(template.render(name=node.name))
+ print(
+ template.render(
+ name=node.name,
+ enumerators=node.enumerators,
+ validate=get_xdr_enum_validation(),
+ )
+ )
def emit_encoder(self, node: _XdrEnum) -> None:
"""Emit one encoder function for an XDR enum type"""
diff --git a/tools/net/sunrpc/xdrgen/subcmds/source.py b/tools/net/sunrpc/xdrgen/subcmds/source.py
index 08c883f547d7..6508563494fe 100644
--- a/tools/net/sunrpc/xdrgen/subcmds/source.py
+++ b/tools/net/sunrpc/xdrgen/subcmds/source.py
@@ -22,7 +22,7 @@ from xdr_ast import transform_parse_tree, _RpcProgram, Specification
from xdr_ast import _XdrAst, _XdrEnum, _XdrPointer
from xdr_ast import _XdrStruct, _XdrTypedef, _XdrUnion
-from xdr_parse import xdr_parser, set_xdr_annotate
+from xdr_parse import xdr_parser, set_xdr_annotate, set_xdr_enum_validation
from xdr_parse import make_error_handler, XdrParseError
from xdr_parse import handle_transform_error
@@ -98,6 +98,7 @@ def subcmd(args: Namespace) -> int:
"""Generate encoder and decoder functions"""
set_xdr_annotate(args.annotate)
+ set_xdr_enum_validation(not args.no_enum_validation)
parser = xdr_parser()
with open(args.filename, encoding="utf-8") as f:
source = f.read()
diff --git a/tools/net/sunrpc/xdrgen/templates/C/enum/decoder/enum.j2 b/tools/net/sunrpc/xdrgen/templates/C/enum/decoder/enum.j2
index 6482984f1cb7..735a34157fdf 100644
--- a/tools/net/sunrpc/xdrgen/templates/C/enum/decoder/enum.j2
+++ b/tools/net/sunrpc/xdrgen/templates/C/enum/decoder/enum.j2
@@ -14,6 +14,17 @@ xdrgen_decode_{{ name }}(struct xdr_stream *xdr, {{ name }} *ptr)
if (xdr_stream_decode_u32(xdr, &val) < 0)
return false;
+{% if validate and enumerators %}
+ /* Compiler may optimize to a range check for dense enums */
+ switch (val) {
+{% for e in enumerators %}
+ case {{ e.name }}:
+{% endfor %}
+ break;
+ default:
+ return false;
+ }
+{% endif %}
*ptr = val;
return true;
}
diff --git a/tools/net/sunrpc/xdrgen/templates/C/enum/decoder/enum_be.j2 b/tools/net/sunrpc/xdrgen/templates/C/enum/decoder/enum_be.j2
index 44c391c10b42..82782a510d47 100644
--- a/tools/net/sunrpc/xdrgen/templates/C/enum/decoder/enum_be.j2
+++ b/tools/net/sunrpc/xdrgen/templates/C/enum/decoder/enum_be.j2
@@ -10,5 +10,25 @@ static bool __maybe_unused
{% endif %}
xdrgen_decode_{{ name }}(struct xdr_stream *xdr, {{ name }} *ptr)
{
+{% if validate and enumerators %}
+ __be32 raw;
+ u32 val;
+
+ if (xdr_stream_decode_be32(xdr, &raw) < 0)
+ return false;
+ val = be32_to_cpu(raw);
+ /* Compiler may optimize to a range check for dense enums */
+ switch (val) {
+{% for e in enumerators %}
+ case {{ e.name }}:
+{% endfor %}
+ break;
+ default:
+ return false;
+ }
+ *ptr = raw;
+ return true;
+{% else %}
return xdr_stream_decode_be32(xdr, ptr) == 0;
+{% endif %}
}
diff --git a/tools/net/sunrpc/xdrgen/xdr_ast.py b/tools/net/sunrpc/xdrgen/xdr_ast.py
index 2b5d160a0a60..dc2fa9fd8ec2 100644
--- a/tools/net/sunrpc/xdrgen/xdr_ast.py
+++ b/tools/net/sunrpc/xdrgen/xdr_ast.py
@@ -330,8 +330,6 @@ class _XdrEnum(_XdrAst):
"""An XDR enum definition"""
name: str
- minimum: int
- maximum: int
enumerators: List[_XdrEnumerator]
def max_width(self) -> int:
@@ -572,8 +570,6 @@ class ParseToAst(Transformer):
value = children[1].value
return _XdrConstant(name, value)
- # cel: Python can compute a min() and max() for the enumerator values
- # so that the generated code can perform proper range checking.
def enum(self, children):
"""Instantiate one _XdrEnum object"""
enum_name = children[0].symbol
@@ -587,7 +583,7 @@ class ParseToAst(Transformer):
enumerators.append(_XdrEnumerator(name, value))
i = i + 2
- return _XdrEnum(enum_name, 0, 0, enumerators)
+ return _XdrEnum(enum_name, enumerators)
def fixed_length_opaque(self, children):
"""Instantiate one _XdrFixedLengthOpaque declaration object"""
diff --git a/tools/net/sunrpc/xdrgen/xdr_parse.py b/tools/net/sunrpc/xdrgen/xdr_parse.py
index 38724ad5aea2..241e96c1fdd9 100644
--- a/tools/net/sunrpc/xdrgen/xdr_parse.py
+++ b/tools/net/sunrpc/xdrgen/xdr_parse.py
@@ -13,6 +13,9 @@ from lark.exceptions import UnexpectedInput, UnexpectedToken, VisitError
# Set to True to emit annotation comments in generated source
annotate = False
+# Set to True to emit enum value validation in decoders
+enum_validation = True
+
# Map internal Lark token names to human-readable names
TOKEN_NAMES = {
"__ANON_0": "identifier",
@@ -49,6 +52,17 @@ def get_xdr_annotate() -> bool:
return annotate
+def set_xdr_enum_validation(set_it: bool) -> None:
+ """Set 'enum_validation' based on command line options"""
+ global enum_validation
+ enum_validation = set_it
+
+
+def get_xdr_enum_validation() -> bool:
+ """Return True when enum validation is enabled for decoder generation"""
+ return enum_validation
+
+
def make_error_handler(source: str, filename: str) -> Callable[[UnexpectedInput], bool]:
"""Create an error handler that reports the first parse error and aborts.
diff --git a/tools/net/sunrpc/xdrgen/xdrgen b/tools/net/sunrpc/xdrgen/xdrgen
index e22638f8324b..b2fb43f4a2ec 100755
--- a/tools/net/sunrpc/xdrgen/xdrgen
+++ b/tools/net/sunrpc/xdrgen/xdrgen
@@ -123,6 +123,12 @@ There is NO WARRANTY, to the extent permitted by law.""",
help="Generate code for client or server side",
type=str,
)
+ source_parser.add_argument(
+ "--no-enum-validation",
+ action="store_true",
+ default=False,
+ help="Disable enum value validation in decoders",
+ )
source_parser.add_argument("filename", help="File containing an XDR specification")
source_parser.set_defaults(func=source.subcmd)