diff options
author | Ole Troan <ot@cisco.com> | 2019-04-23 17:11:01 +0200 |
---|---|---|
committer | Andrew Yourtchenko <ayourtch@gmail.com> | 2019-04-29 12:07:02 +0000 |
commit | 9ac113815511f3ce37b56a1331d6491fc36f7db5 (patch) | |
tree | 574f66ce291ee75de2545a051be77a11bbaa43e2 /src/vpp-api | |
parent | de146e5d5f7e919b423feeff3159c4ecd564c353 (diff) |
API: Add support for limits to language.
string name [limit = 64];
Meta-data to do argument validation.
Change-Id: I1f3e0f09b2d5285224399413d25206f77bd3f4b1
Signed-off-by: Ole Troan <ot@cisco.com>
Diffstat (limited to 'src/vpp-api')
-rwxr-xr-x | src/vpp-api/python/vpp_papi/tests/test_vpp_serializer.py | 17 | ||||
-rw-r--r-- | src/vpp-api/python/vpp_papi/vpp_serializer.py | 30 | ||||
-rw-r--r-- | src/vpp-api/vapi/vapi_json_parser.py | 9 |
3 files changed, 46 insertions, 10 deletions
diff --git a/src/vpp-api/python/vpp_papi/tests/test_vpp_serializer.py b/src/vpp-api/python/vpp_papi/tests/test_vpp_serializer.py index 4fbda2a01af..ec7334712ab 100755 --- a/src/vpp-api/python/vpp_papi/tests/test_vpp_serializer.py +++ b/src/vpp-api/python/vpp_papi/tests/test_vpp_serializer.py @@ -3,12 +3,27 @@ import unittest from vpp_papi.vpp_serializer import VPPType, VPPEnumType from vpp_papi.vpp_serializer import VPPUnionType, VPPMessage -from vpp_papi.vpp_serializer import VPPTypeAlias +from vpp_papi.vpp_serializer import VPPTypeAlias, VPPSerializerValueError from socket import inet_pton, AF_INET, AF_INET6 import logging import sys from ipaddress import * +class TestLimits(unittest.TestCase): + def test_limit(self): + limited_type = VPPType('limited_type_t', + [['string', 'name', {'limit': 16}]]) + unlimited_type = VPPType('limited_type_t', + [['string', 'name']]) + + + b = limited_type.pack({'name':'foobar'}) + self.assertEqual(len(b), 10) + b = unlimited_type.pack({'name':'foobar'}) + self.assertEqual(len(b), 10) + + with self.assertRaises(VPPSerializerValueError): + b = limited_type.pack({'name':'foobar'*3}) class TestAddType(unittest.TestCase): diff --git a/src/vpp-api/python/vpp_papi/vpp_serializer.py b/src/vpp-api/python/vpp_papi/vpp_serializer.py index bd5f050bba9..d1093318ed0 100644 --- a/src/vpp-api/python/vpp_papi/vpp_serializer.py +++ b/src/vpp-api/python/vpp_papi/vpp_serializer.py @@ -96,14 +96,20 @@ class BaseTypes(object): class String(object): - def __init__(self): + def __init__(self, options): self.name = 'string' self.size = 1 self.length_field_packer = BaseTypes('u32') + self.limit = options['limit'] if 'limit' in options else None def pack(self, list, kwargs=None): if not list: return self.length_field_packer.pack(0) + b"" + if self.limit and len(list) > self.limit: + raise VPPSerializerValueError( + "Invalid argument length for: {}, {} maximum {}". + format(list, len(list), self.limit)) + return self.length_field_packer.pack(len(list)) + list.encode('utf8') def unpack(self, data, offset=0, result=None, ntc=False): @@ -120,7 +126,7 @@ class String(object): types = {'u8': BaseTypes('u8'), 'u16': BaseTypes('u16'), 'u32': BaseTypes('u32'), 'i32': BaseTypes('i32'), 'u64': BaseTypes('u64'), 'f64': BaseTypes('f64'), - 'bool': BaseTypes('bool'), 'string': String()} + 'bool': BaseTypes('bool'), 'string': String} def vpp_get_type(name): @@ -416,7 +422,15 @@ class VPPType(object): logger.debug('Unknown type {}'.format(f_type)) raise VPPSerializerValueError( 'Unknown message type {}'.format(f_type)) - if len(f) == 3: # list + + l = len(f) + options = [x for x in f if type(x) is dict] + if len(options): + self.options = options[0] + l -= 1 + else: + self.options = {} + if l == 3: # list list_elements = f[2] if list_elements == 0: p = VLAList_legacy(f_name, f_type) @@ -429,13 +443,17 @@ class VPPType(object): p = FixedList(f_name, f_type, list_elements) self.packers.append(p) size += p.size - elif len(f) == 4: # Variable length list + elif l == 4: # Variable length list length_index = self.fields.index(f[3]) p = VLAList(f_name, f_type, f[3], length_index) self.packers.append(p) else: - self.packers.append(types[f_type]) - size += types[f_type].size + if f_type == 'string': + p = types[f_type](self.options) + else: + p = types[f_type] + self.packers.append(p) + size += p.size self.size = size self.tuple = collections.namedtuple(name, self.fields, rename=True) diff --git a/src/vpp-api/vapi/vapi_json_parser.py b/src/vpp-api/vapi/vapi_json_parser.py index fda3f75d9c1..fbeb1887ac2 100644 --- a/src/vpp-api/vapi/vapi_json_parser.py +++ b/src/vpp-api/vapi/vapi_json_parser.py @@ -167,13 +167,16 @@ class Message(object): else: field_type = json_parser.lookup_type_like_id(field[0]) logger.debug("Parsing message field `%s'" % field) - if len(field) == 2: + l = len(field) + if any(type(n) is dict for n in field): + l -= 1 + if l == 2: if self.header is not None and\ self.header.has_field(field[1]): continue p = field_class(field_name=field[1], field_type=field_type) - elif len(field) == 3: + elif l == 3: if field[2] == 0: raise ParseError( "While parsing message `%s': variable length " @@ -184,7 +187,7 @@ class Message(object): field_name=field[1], field_type=field_type, array_len=field[2]) - elif len(field) == 4: + elif l == 4: nelem_field = None for f in fields: if f.name == field[3]: |