Skip to content

Commit

Permalink
Handle reserved abort source (#563)
Browse files Browse the repository at this point in the history
  • Loading branch information
scaramallion committed Dec 16, 2020
1 parent 167f4f6 commit a369615
Show file tree
Hide file tree
Showing 7 changed files with 56 additions and 22 deletions.
1 change: 1 addition & 0 deletions docs/changelog/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ Release Notes
.. toctree::
:maxdepth: 1

v1.5.4
v1.5.3
v1.5.2
v1.5.1
Expand Down
10 changes: 10 additions & 0 deletions docs/changelog/v1.5.4.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
.. _v1.5.4:

1.5.4
=====

Fixes
.....

* Fixed not handling an A-ABORT with a reserved (``0x01``) 'source' value
(:issue:`561`)
2 changes: 1 addition & 1 deletion pynetdicom/_version.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
import re


__version__ = '1.5.3'
__version__ = '1.5.4'


VERSION_PATTERN = r"""
Expand Down
12 changes: 6 additions & 6 deletions pynetdicom/pdu.py
Original file line number Diff line number Diff line change
Expand Up @@ -1906,15 +1906,15 @@ def to_primitive(self):
"""
from pynetdicom.pdu_primitives import A_ABORT, A_P_ABORT

# User initiated abort
if self.source == 0x00:
if self.source == 0x02:
# User provider primitive abort
primitive = A_P_ABORT()
primitive.provider_reason = self.reason_diagnostic
else:
# User initiated abort and undefined abort source
primitive = A_ABORT()
primitive.abort_source = self.source

# User provider primitive abort
elif self.source == 0x02:
primitive = A_P_ABORT()
primitive.provider_reason = self.reason_diagnostic

return primitive

Expand Down
21 changes: 8 additions & 13 deletions pynetdicom/pdu_primitives.py
Original file line number Diff line number Diff line change
Expand Up @@ -836,13 +836,13 @@ class A_ABORT(object):
"""

def __init__(self):
self.abort_source = None
self._abort_source = None

@property
def abort_source(self):
"""Return the *Abort Source*."""
if self._abort_source is None:
LOGGER.error("A_ABORT.abort_source parameter not set")
LOGGER.error("A_ABORT.abort_source value not set")
raise ValueError("A_ABORT.abort_source value not set")

return self._abort_source
Expand All @@ -851,15 +851,12 @@ def abort_source(self):
def abort_source(self, value):
"""Set the Abort Source."""
# pylint: disable=attribute-defined-outside-init
if value in [0, 2]:
if value in [0, 1, 2, None]:
self._abort_source = value
elif value is None:
self._abort_source = None
else:
LOGGER.error("Attempted to set A_ABORT.abort_source to an "
"invalid value")
raise ValueError("Attempted to set A_ABORT.abort_source to an "
"invalid value")
msg = "Invalid A-ABORT 'source' value '{}'".format(value)
LOGGER.error(msg)
raise ValueError(msg)


class A_P_ABORT(object):
Expand Down Expand Up @@ -899,7 +896,7 @@ class A_P_ABORT(object):
* DICOM Standard, Part 8, :dcm:`Section 7.4<part08/sect_7.4.html>`
"""
def __init__(self):
self.provider_reason = None
self._provider_reason = None

@property
def provider_reason(self):
Expand All @@ -914,10 +911,8 @@ def provider_reason(self):
def provider_reason(self, value):
"""Set the Provider Reason."""
# pylint: disable=attribute-defined-outside-init
if value in [0, 1, 2, 4, 5, 6]:
if value in [0, 1, 2, 4, 5, 6, None]:
self._provider_reason = value
elif value is None:
self._provider_reason = None
else:
msg = (
"Attempted to set A_P_ABORT.provider_reason to an invalid "
Expand Down
28 changes: 27 additions & 1 deletion pynetdicom/tests/test_assoc.py
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@
from pynetdicom.pdu_primitives import (
UserIdentityNegotiation, SOPClassExtendedNegotiation,
SOPClassCommonExtendedNegotiation, SCP_SCU_RoleSelectionNegotiation,
AsynchronousOperationsWindowNegotiation, A_ASSOCIATE,
AsynchronousOperationsWindowNegotiation, A_ASSOCIATE
)
from pynetdicom.sop_class import (
VerificationSOPClass,
Expand Down Expand Up @@ -580,6 +580,32 @@ def handle_req(event):

scp.shutdown()

def test_unknown_abort_source(self):
"""Test an unknown abort source handled correctly #561"""
def handle_req(event):
pdu = b"\x07\x00\x00\x00\x00\x04\x00\x00\x01\x00"
event.assoc.dul.socket.send(pdu)
# Give the requestor time to process the message before killing
# the connection
time.sleep(0.1)

self.ae = ae = AE()
ae.acse_timeout = 5
ae.dimse_timeout = 5
ae.network_timeout = 5
ae.add_supported_context(VerificationSOPClass)

hh = [(evt.EVT_REQUESTED, handle_req)]

scp = ae.start_server(('', 11112), block=False, evt_handlers=hh)

ae.add_requested_context(VerificationSOPClass)
assoc = ae.associate('localhost', 11112)
assert not assoc.is_established
assert assoc.is_aborted

scp.shutdown()


class TestCStoreSCP(object):
"""Tests for Association._c_store_scp()."""
Expand Down
4 changes: 3 additions & 1 deletion pynetdicom/tests/test_primitives.py
Original file line number Diff line number Diff line change
Expand Up @@ -1013,6 +1013,8 @@ def test_assignment(self):
primitive = A_ABORT()
primitive.abort_source = 0
assert primitive.abort_source == 0
primitive.abort_source = 1
assert primitive.abort_source == 1
primitive.abort_source = 2
assert primitive.abort_source == 2

Expand All @@ -1021,7 +1023,7 @@ def test_exceptions(self):
primitive = A_ABORT()

with pytest.raises(ValueError):
primitive.abort_source = 1
primitive.abort_source = 3

with pytest.raises(ValueError):
primitive.abort_source
Expand Down

0 comments on commit a369615

Please sign in to comment.