Skip to content

Commit 0a75bba

Browse files
davidshepherd7code-of-kpp
authored andcommitted
Fix not ignoring unknown optional parameters (as required by the spec)
See page 43 of https://smpp.org/SMPP_v3_4_Issue1_2.pdf for details.
1 parent 81f79b2 commit 0a75bba

File tree

4 files changed

+54
-6
lines changed

4 files changed

+54
-6
lines changed

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ logging.basicConfig(level='DEBUG')
2525
# Two parts, UCS2, SMS with UDH
2626
parts, encoding_flag, msg_type_flag = smpplib.gsm.make_parts(u'Привет мир!\n'*10)
2727

28-
client = smpplib.client.Client('example.com', SOMEPORTNUMBER)
28+
client = smpplib.client.Client('example.com', SOMEPORTNUMBER, allow_unknown_opt_params=True)
2929

3030
# Print when obtain message_id
3131
client.set_message_sent_handler(

smpplib/client.py

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -63,10 +63,20 @@ class Client(object):
6363
_ssl_context = None
6464
sequence_generator = None
6565

66-
def __init__(self, host, port, timeout=5, sequence_generator=None, logger_name=None, ssl_context=None):
66+
def __init__(
67+
self,
68+
host,
69+
port,
70+
timeout=5,
71+
sequence_generator=None,
72+
logger_name=None,
73+
ssl_context=None,
74+
allow_unknown_opt_params=False
75+
):
6776
self.host = host
6877
self.port = int(port)
6978
self._ssl_context = ssl_context
79+
self.allow_unknown_opt_params = allow_unknown_opt_params
7080
self.timeout = timeout
7181
self.logger = logging.getLogger(logger_name or 'smpp.Client.{}'.format(id(self)))
7282
if sequence_generator is None:
@@ -233,7 +243,11 @@ def read_pdu(self):
233243

234244
self.logger.debug('<<%s (%d bytes)', binascii.b2a_hex(raw_pdu), len(raw_pdu))
235245

236-
pdu = smpp.parse_pdu(raw_pdu, client=self)
246+
pdu = smpp.parse_pdu(
247+
raw_pdu,
248+
client=self,
249+
allow_unknown_opt_params=self.allow_unknown_opt_params
250+
)
237251

238252
self.logger.debug('Read %s PDU', pdu.command)
239253

smpplib/command.py

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -93,9 +93,11 @@ class Command(pdu.PDU):
9393

9494
params = {}
9595

96-
def __init__(self, command, need_sequence=True, **kwargs):
96+
def __init__(self, command, need_sequence=True, allow_unknown_opt_params=False, **kwargs):
9797
super(Command, self).__init__(**kwargs)
9898

99+
self.allow_unknown_opt_params = allow_unknown_opt_params
100+
99101
self.command = command
100102
if need_sequence and (kwargs.get('sequence') is None):
101103
self.sequence = self._next_seq()
@@ -328,9 +330,18 @@ def parse_optional_params(self, data):
328330

329331
while pos < dlen:
330332
type_code, pos = unpack_short(data, pos)
331-
field = get_optional_name(type_code)
332333
length, pos = unpack_short(data, pos)
333334

335+
try:
336+
field = get_optional_name(type_code)
337+
except exceptions.UnknownCommandError as e:
338+
if self.allow_unknown_opt_params:
339+
logger.warning("Unknown optional parameter type 0x%x, skipping" % type_code)
340+
pos += length
341+
continue
342+
else:
343+
raise
344+
334345
param = self.params[field]
335346
if param.type is int:
336347
data, pos = self._parse_int(field, data, pos)

tests/test_command.py

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
1-
from smpplib import consts
1+
from smpplib import consts, exceptions
22
from smpplib.command import DeliverSM
33

4+
import pytest
5+
46

57
def test_parse_deliver_sm():
68
pdu = DeliverSM('deliver_sm')
@@ -21,3 +23,24 @@ def test_parse_deliver_sm():
2123
assert pdu.source_network_type == consts.SMPP_NETWORK_TYPE_GSM
2224
assert pdu.message_state == consts.SMPP_MESSAGE_STATE_DELIVERED
2325
assert pdu.user_message_reference is None
26+
27+
28+
def test_unrecognised_optional_parameters():
29+
pdu = DeliverSM("deliver_sm", allow_unknown_opt_params=True)
30+
pdu.parse(b'\x00\x00\x00\xa8\x00\x00\x00\x05\x00\x00\x00\x00/p\xc6'
31+
b'\x9a\x00\x00\x0022549909028\x00\x01\x00\x00\x04\x00\x00'
32+
b'\x00\x00\x00\x00\x00\x00iid:795920026 sub:001 dlvrd:001 '
33+
b'submit date:200319131913 done date:200319131913 stat:DELIVRD err:000 text:'
34+
b'\x14\x03\x00\x07(null)\x00\x14\x02\x00\x04612\x00'
35+
)
36+
37+
# This is only to avoid a breaking change, at some point the other behaviour
38+
# should become the default.
39+
with pytest.raises(exceptions.UnknownCommandError):
40+
pdu2 = DeliverSM("deliver_sm")
41+
pdu2.parse(b'\x00\x00\x00\xa8\x00\x00\x00\x05\x00\x00\x00\x00/p\xc6'
42+
b'\x9a\x00\x00\x0022549909028\x00\x01\x00\x00\x04\x00\x00'
43+
b'\x00\x00\x00\x00\x00\x00iid:795920026 sub:001 dlvrd:001 '
44+
b'submit date:200319131913 done date:200319131913 stat:DELIVRD err:000 text:'
45+
b'\x14\x03\x00\x07(null)\x00\x14\x02\x00\x04612\x00'
46+
)

0 commit comments

Comments
 (0)