Skip to content

Commit 7369d2e

Browse files
authored
Fix negative xsd range edge cases (#178)
The current implementation uses the `abs()` function to check that the value is inside the range. However, the range is not symmetric. For example, for a [byte](https://www.w3.org/TR/xmlschema11-2/#byte), which is between [-128, 127], the value of [maxInclusive](https://www.w3.org/TR/xmlschema11-2/#dt-maxInclusive) should be 127, and [minInclusive](https://www.w3.org/TR/xmlschema11-2/#dt-minInclusive) should be -128.
1 parent 9539172 commit 7369d2e

File tree

2 files changed

+17
-4
lines changed

2 files changed

+17
-4
lines changed

basyx/aas/model/datatypes.py

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -235,31 +235,35 @@ class Float(float):
235235
class Long(int):
236236
def __new__(cls, *args, **kwargs):
237237
res = int.__new__(cls, *args, **kwargs)
238-
if abs(res) > 2**63-1:
238+
# [-9223372036854775808, 9223372036854775807]
239+
if res > 2**63-1 or res < -2**63:
239240
raise ValueError("{} is out of the allowed range for type {}".format(res, cls.__name__))
240241
return res
241242

242243

243244
class Int(int):
244245
def __new__(cls, *args, **kwargs):
245246
res = int.__new__(cls, *args, **kwargs)
246-
if abs(res) > 2**31-1:
247+
# [-2147483648, 2147483647]
248+
if res > 2**31-1 or res < -2**31:
247249
raise ValueError("{} is out of the allowed range for type {}".format(res, cls.__name__))
248250
return res
249251

250252

251253
class Short(int):
252254
def __new__(cls, *args, **kwargs):
253255
res = int.__new__(cls, *args, **kwargs)
254-
if abs(res) > 2**15-1:
256+
# [-32768, 32767]
257+
if res > 2**15-1 or res < -2**15:
255258
raise ValueError("{} is out of the allowed range for type {}".format(res, cls.__name__))
256259
return res
257260

258261

259262
class Byte(int):
260263
def __new__(cls, *args, **kwargs):
261264
res = int.__new__(cls, *args, **kwargs)
262-
if abs(res) > 2**7-1:
265+
# [-128,127]
266+
if res > 2**7-1 or res < -2**7:
263267
raise ValueError("{} is out of the allowed range for type {}".format(res, cls.__name__))
264268
return res
265269

test/model/test_datatypes.py

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,11 +21,20 @@ def test_parse_int(self) -> None:
2121
self.assertEqual(8, model.datatypes.from_xsd("8", model.datatypes.Long))
2222
self.assertEqual(9, model.datatypes.from_xsd("9", model.datatypes.Int))
2323
self.assertEqual(10, model.datatypes.from_xsd("10", model.datatypes.Short))
24+
self.assertEqual(-123456789012345678901234567890,
25+
model.datatypes.from_xsd("-123456789012345678901234567890", model.datatypes.Integer))
26+
self.assertEqual(2147483647, model.datatypes.from_xsd("2147483647", model.datatypes.Int))
27+
self.assertEqual(-2147483648, model.datatypes.from_xsd("-2147483648", model.datatypes.Int))
28+
self.assertEqual(-32768, model.datatypes.from_xsd("-32768", model.datatypes.Short))
29+
self.assertEqual(-128, model.datatypes.from_xsd("-128", model.datatypes.Byte))
30+
self.assertEqual(-9223372036854775808,
31+
model.datatypes.from_xsd("-9223372036854775808", model.datatypes.Long))
2432

2533
def test_serialize_int(self) -> None:
2634
self.assertEqual("5", model.datatypes.xsd_repr(model.datatypes.Integer(5)))
2735
self.assertEqual("6", model.datatypes.xsd_repr(model.datatypes.Byte(6)))
2836
self.assertEqual("7", model.datatypes.xsd_repr(model.datatypes.NonNegativeInteger(7)))
37+
self.assertEqual("-128", model.datatypes.xsd_repr(model.datatypes.Byte(-128)))
2938

3039
def test_range_error(self) -> None:
3140
with self.assertRaises(ValueError) as cm:

0 commit comments

Comments
 (0)