Repository: vertexproject/synapse

Issue:
inet:srv4 type doesn't handle integer as string input
inet:tcp4="123456789012345" doesn't norm correctly 

Discussion:

Patch:
diff --git a/synapse/models/inet.py b/synapse/models/inet.py
index 97d9311f8..6df0a55c5 100644
--- a/synapse/models/inet.py
+++ b/synapse/models/inet.py
@@ -144,18 +144,31 @@ class Srv4Type(DataType):
         if s_compat.isstr(valu):
             return self._norm_str(valu, oldval=oldval)
 
+        if valu < 0 or valu > 281474976710655:
+            self._raiseBadValu(valu, mesg='Srv4Type integer is out of bounds')
+
         addr = valu >> 16
         port = valu & 0xffff
         return valu, {'port': port, 'ipv4': addr}
 
     def _norm_str(self, text, oldval=None):
+        if ':' not in text:
+            try:
+                valu = int(text)
+            except ValueError:
+                self._raiseBadValu(text, mesg='Srv4Type string is not a integer or a colon delimited string.')
+            return self.norm(valu)
+
         try:
             astr, pstr = text.split(':')
         except ValueError as e:
-            self._raiseBadValu(text)
+            self._raiseBadValu(text, mesg='Unable to split Srv4Type into two parts')
 
         addr = ipv4int(astr)
         port = int(pstr, 0)
+        if port < 0 or port > 65535:
+            self._raiseBadValu(text, port=port,
+                               mesg='Srv4 Port number is out of bounds')
         return (addr << 16) | port, {'port': port, 'ipv4': addr}
 
 srv6re = re.compile('^\[([a-f0-9:]+)\]:(\d+)$')


Test patch:
diff --git a/synapse/tests/test_model_inet.py b/synapse/tests/test_model_inet.py
index d36f28b0a..16418b499 100644
--- a/synapse/tests/test_model_inet.py
+++ b/synapse/tests/test_model_inet.py
@@ -123,6 +123,39 @@ class InetModelTest(SynTest):
             self.eq(t3[1].get('inet:udp4:port'), 8443)
             self.eq(t3[1].get('inet:udp4:ipv4'), core.getTypeNorm('inet:ipv4', '1.2.3.4')[0])
 
+            # 1.2.3.4:8443
+            t4 = core.formTufoByProp('inet:udp4', '1108152164603')
+            self.eq(t4[1].get('inet:udp4:port'), 8443)
+            self.eq(t4[1].get('inet:udp4:ipv4'), core.getTypeNorm('inet:ipv4', '1.2.3.4')[0])
+
+            # Ensure boundaries are observed
+            for i in ['0', 0, '0.0.0.0:0']:
+                valu, subs = core.getTypeNorm('inet:srv4', i)
+                self.eq(valu, 0)
+                self.eq(subs.get('port'), 0)
+                self.eq(subs.get('ipv4'), 0)
+
+            for i in ['281474976710655', 281474976710655, '255.255.255.255:65535']:
+                valu, subs = core.getTypeNorm('inet:srv4', i)
+                self.eq(valu, 281474976710655)
+                self.eq(subs.get('port'), 0xFFFF)
+                self.eq(subs.get('ipv4'), 0xFFFFFFFF)
+
+            # Repr works as expected
+            self.eq(core.getTypeRepr('inet:srv4', 0), '0.0.0.0:0')
+            self.eq(core.getTypeRepr('inet:srv4', 1108152164603), '1.2.3.4:8443')
+            self.eq(core.getTypeRepr('inet:srv4', 281474976710655), '255.255.255.255:65535')
+
+            # Ensure bad input fails
+            self.raises(BadTypeValu, core.getTypeNorm, 'inet:srv4', '281474976710656')
+            self.raises(BadTypeValu, core.getTypeNorm, 'inet:srv4', 281474976710656)
+            self.raises(BadTypeValu, core.getTypeNorm, 'inet:srv4', '255.255.255.255:65536')
+            self.raises(BadTypeValu, core.getTypeNorm, 'inet:srv4', '255.255.255.255:-1')
+            self.raises(BadTypeValu, core.getTypeNorm, 'inet:srv4', -1)
+            self.raises(BadTypeValu, core.getTypeNorm, 'inet:srv4', '-1')
+            self.raises(BadTypeValu, core.getTypeNorm, 'inet:srv4', 'ruh roh')
+            self.raises(BadTypeValu, core.getTypeNorm, 'inet:srv4', '1.2.3.4:8080:9090')
+
     def test_model_inet_srv6_types(self):
         with self.getRamCore() as core:
             t0 = core.formTufoByProp('inet:tcp6', '[0:0:0:0:0:0:0:1]:80')