Repository: pika/pika

Issue:
InvalidFieldTypeException when receiving messages with int values in headers dict
Pika throws an InvalidFieldTypeException on messages produced by haigha Python package with int values in the headers dictionary. 

Notes:
RabbitMQ can handle the message generated by _haigha_ (See attached screenshot)
Pika can process similar messages that are published by pika

An example for a failing application_headers: 
```
{'compressed': False, 'sequence': 5}
```

Stack trace:
```
File " \venv\lib\site-packages\pika\adapters\blocking_connection.py", line 1688, in _basic_consume_impl
    self._flush_output(ok_result.is_ready)
File " \venv\lib\site-packages\pika\adapters\blocking_connection.py", line 1327, in _flush_output
    self._connection._flush_output(lambda: self.is_closed, *waiters)
File " \venv\lib\site-packages\pika\adapters\blocking_connection.py", line 523, in _flush_output
    raise self._closed_result.value.error
pika.exceptions.StreamLostError: Stream connection lost: InvalidFieldTypeException
![pika + haigha messages](https://user-images.githubusercontent.com/47942606/56371619-18635680-6206-11e9-804a-fcf1a2e0d1de.PNG)

: Unsupported field kind b''
```

Attachments:
haigha_publisher.py : Publish messages that cause the error in pika
receiver_2.py: pika receiver code
publisher.py: pika publish code - receiver handles it
pika + haigha messages.PNG: A screenshot of the messages sent by haigha and pika.
[examples.zip](https://github.com/pika/pika/files/3095058/examples.zip)

The following application_header schemas were received succesfully by pika:
```
{'compressed': False, },
{'compressed': False, 'sequence': '5'},
{'compressed': False, 'sequence': None},
{'compressed': False, 'encoding': 'json'},
{'compressed': False, 'encoding': 'json', 'sequence': ''},
{'compressed': False, 'encoding': 'json', 'sequence': '5'}
```

Discussion:

Patch:
diff --git a/pika/data.py b/pika/data.py
index d4264d2..e50a7b2 100644
--- a/pika/data.py
+++ b/pika/data.py
@@ -273,9 +273,11 @@ def decode_value(encoded, offset): # pylint: disable=R0912,R0915
         offset += 4
         value = decimal.Decimal(raw) * (decimal.Decimal(10)**-decimals)
 
-    # Short String
+    # https://github.com/pika/pika/issues/1205
+    # Short Signed Int
     elif kind == b's':
-        value, offset = decode_short_string(encoded, offset)
+        value = struct.unpack_from('>h', encoded, offset)[0]
+        offset += 2
 
     # Long String
     elif kind == b'S':


Test patch:
diff --git a/tests/unit/data_tests.py b/tests/unit/data_tests.py
index fccd0a9..db8601f 100644
--- a/tests/unit/data_tests.py
+++ b/tests/unit/data_tests.py
@@ -35,16 +35,19 @@ class DataTests(unittest.TestCase):
     FIELD_TBL_ENCODED += b'\x05bytesx\x00\x00\x00\x06foobar' if PY3 else b'\x05bytesS\x00\x00\x00\x06foobar'
 
     FIELD_TBL_VALUE = OrderedDict(
-        [('array', [1, 2, 3]), ('boolval', True), ('decimal',
-                                                   decimal.Decimal('3.14')),
-         ('decimal_too', decimal.Decimal('100')), ('dictval', {
-             'foo': 'bar'
-         }), ('intval', 1), ('bigint', 2592000000), ('longval',
-                                                     long(912598613)), ('null',
-                                                                        None),
-         ('strval', 'Test'), ('timestampval',
-                              datetime.datetime(2006, 11, 21, 16, 30,
-                                                10)), ('unicode', u'utf8=✓'),
+        [
+            ('array', [1, 2, 3]),
+            ('boolval', True),
+            ('decimal', decimal.Decimal('3.14')),
+            ('decimal_too', decimal.Decimal('100')),
+            ('dictval', { 'foo': 'bar' }),
+            ('intval', 1),
+            ('bigint', 2592000000),
+            ('longval', long(912598613)),
+            ('null', None),
+            ('strval', 'Test'),
+            ('timestampval', datetime.datetime(2006, 11, 21, 16, 30, 10)),
+            ('unicode', u'utf8=✓'),
             ('bytes', b'foobar'),
         ])
 
@@ -56,6 +59,15 @@ class DataTests(unittest.TestCase):
         result = data.decode_table(input, 0)
         self.assertEqual(result, ({'bytes': b'foobar'}, 21))
 
+    # b'\x08shortints\x04\xd2'
+    # ('shortint', 1234),
+    def test_decode_shortint(self):
+        input = (
+                b'\x00\x00\x00\x01'
+                b'\x08shortints\x04\xd2'
+            )
+        result = data.decode_table(input, 0)
+        self.assertEqual(result, ({'shortint': 1234}, 16))
 
     def test_encode_table(self):
         result = []