This is an automated email from the ASF dual-hosted git repository.
astitcher pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/qpid-proton.git
The following commit(s) were added to refs/heads/main by this push:
new c80482bf6 PROTON-2873: Fix decoding of dispositions in transfer frames
c80482bf6 is described below
commit c80482bf61bbddabe4064a70c67a691e34179237
Author: Andrew Stitcher <[email protected]>
AuthorDate: Tue Mar 18 17:18:56 2025 -0400
PROTON-2873: Fix decoding of dispositions in transfer frames
There was a bug that decoded dispositions in transfer frames and
disposition frames differently.
---
c/src/core/transport.c | 30 +++++++++++++-----------------
c/tools/codec-generator/specs.json | 9 +++++----
python/tests/proton_tests/engine.py | 14 +++++++-------
3 files changed, 25 insertions(+), 28 deletions(-)
diff --git a/c/src/core/transport.c b/c/src/core/transport.c
index 24a2a4d6f..6f633511e 100644
--- a/c/src/core/transport.c
+++ b/c/src/core/transport.c
@@ -1556,7 +1556,7 @@ static void pni_amqp_decode_disposition (uint64_t type,
pn_bytes_t disp_data, pn
uint32_t number;
bool qoffset;
uint64_t offset;
- pn_amqp_decode_DqEQIQLe(disp_data, &qnumber, &number, &qoffset, &offset);
+ pn_amqp_decode_EQIQLe(disp_data, &qnumber, &number, &qoffset, &offset);
disp->type = PN_DISP_RECEIVED;
@@ -1576,7 +1576,7 @@ static void pni_amqp_decode_disposition (uint64_t type,
pn_bytes_t disp_data, pn
pn_bytes_t cond;
pn_bytes_t desc;
pn_bytes_t info;
- pn_amqp_decode_DqEDqEsSRee(disp_data, &cond, &desc, &info);
+ pn_amqp_decode_EDqEsSRee(disp_data, &cond, &desc, &info);
disp->type = PN_DISP_REJECTED;
pn_condition_set(&disp->u.s_rejected.condition, cond, desc, info);
@@ -1592,7 +1592,7 @@ static void pni_amqp_decode_disposition (uint64_t type,
pn_bytes_t disp_data, pn
bool qundeliverable;
bool undeliverable;
pn_bytes_t annotations_raw = (pn_bytes_t){0, NULL};
- pn_amqp_decode_DqEQoQoRe(disp_data, &qfailed, &failed, &qundeliverable,
&undeliverable, &annotations_raw);
+ pn_amqp_decode_EQoQoRe(disp_data, &qfailed, &failed, &qundeliverable,
&undeliverable, &annotations_raw);
disp->type = PN_DISP_MODIFIED;
pn_bytes_free(disp->u.s_modified.annotations_raw);
disp->u.s_modified.annotations_raw = pn_bytes_dup(annotations_raw);
@@ -1609,7 +1609,7 @@ static void pni_amqp_decode_disposition (uint64_t type,
pn_bytes_t disp_data, pn
pn_bytes_t id;
bool qoutcome;
pn_bytes_t outcome_raw;
- pn_amqp_decode_DqEzQRe(disp_data, &id, &qoutcome, &outcome_raw);
+ pn_amqp_decode_EzQRe(disp_data, &id, &qoutcome, &outcome_raw);
disp->type = PN_DISP_TRANSACTIONAL;
pn_bytes_free(disp->u.s_transactional.id);
disp->u.s_transactional.id = pn_bytes_dup(id);
@@ -1621,7 +1621,7 @@ static void pni_amqp_decode_disposition (uint64_t type,
pn_bytes_t disp_data, pn
}
default: {
pn_bytes_t data_raw = (pn_bytes_t){0, NULL};
- pn_amqp_decode_DqR(disp_data, &data_raw);
+ pn_amqp_decode_R(disp_data, &data_raw);
disp->type = PN_DISP_CUSTOM;
disp->u.s_custom.type = type;
pn_bytes_free(disp->u.s_custom.data_raw);
@@ -1631,10 +1631,10 @@ static void pni_amqp_decode_disposition (uint64_t type,
pn_bytes_t disp_data, pn
}
}
-static int pni_do_delivery_disposition(pn_transport_t * transport,
pn_delivery_t *delivery, bool settled, bool remote_data, bool type_init,
uint64_t type, pn_bytes_t disp_data) {
+static int pni_do_delivery_disposition(pn_transport_t * transport,
pn_delivery_t *delivery, bool settled, bool type_init, uint64_t type,
pn_bytes_t disp_data) {
pn_disposition_t *remote = &delivery->remote;
- if (remote_data && type_init) {
+ if (type_init) {
pni_amqp_decode_disposition(type, disp_data, remote);
}
@@ -1652,8 +1652,10 @@ int pn_do_disposition(pn_transport_t *transport, uint8_t
frame_type, uint16_t ch
pn_sequence_t first, last;
bool last_init, settled;
pn_bytes_t disp_data;
- pn_amqp_decode_DqEoIQIoRe(payload, &role, &first, &last_init,
- &last, &settled, &disp_data);
+ bool type_init;
+ uint64_t type;
+ pn_amqp_decode_DqEoIQIoDQLRe(payload, &role, &first, &last_init,
+ &last, &settled, &type_init, &type, &disp_data);
if (!last_init) last = first;
pn_session_t *ssn = pni_channel_state(transport, channel);
@@ -1672,12 +1674,6 @@ int pn_do_disposition(pn_transport_t *transport, uint8_t
frame_type, uint16_t ch
deliveries = &ssn->state.incoming;
}
- bool type_init;
- uint64_t type;
- bool remote_data;
- pn_amqp_decode_DQLQq(disp_data, &type_init, &type, &remote_data);
-
-
// Do some validation of received first and last values
// TODO: We should really also clamp the first value here, but we're not
keeping track of the earliest
// unsettled delivery sequence no
@@ -1691,14 +1687,14 @@ int pn_do_disposition(pn_transport_t *transport,
uint8_t frame_type, uint16_t ch
pn_sequence_t key = pn_hash_key(dh, entry);
if (sequence_lte(first, key) && sequence_lte(key, last)) {
pn_delivery_t *delivery = (pn_delivery_t*) pn_hash_value(dh, entry);
- pni_do_delivery_disposition(transport, delivery, settled, remote_data,
type_init, type, disp_data);
+ pni_do_delivery_disposition(transport, delivery, settled, type_init,
type, disp_data);
}
}
} else {
for (pn_sequence_t id = first; sequence_lte(id, last); ++id) {
pn_delivery_t *delivery = pni_delivery_map_get(deliveries, id);
if (delivery) {
- pni_do_delivery_disposition(transport, delivery, settled, remote_data,
type_init, type, disp_data);
+ pni_do_delivery_disposition(transport, delivery, settled, type_init,
type, disp_data);
}
}
}
diff --git a/c/tools/codec-generator/specs.json
b/c/tools/codec-generator/specs.json
index 82b4a013f..735d076ed 100644
--- a/c/tools/codec-generator/specs.json
+++ b/c/tools/codec-generator/specs.json
@@ -23,6 +23,10 @@
],
"scan_specs": [
"R",
+ "[?I?L]",
+ "[D.[sSR]]",
+ "[?o?oR]",
+ "[z?R]",
"D.R",
"D.[.....D..D.[.....RR]]",
"D.[.....D..D.[R]...]",
@@ -38,14 +42,11 @@
"D.[SIo?B?BD.[SIsIo.s]D.[SIsIo]..IL..?R]",
"D.[azSSSassttSIS]",
"D.[o?BIoI]",
- "D.[oI?IoR]",
- "D.[?o?oR]",
- "D.[?I?L]",
+ "D.[oI?IoD?LR]",
"D.[sz]",
"D.[s]",
"D.[z]",
"D.[Bz]",
- "D.[z?R]",
"D.[R]",
"D?L.",
"D?L?."
diff --git a/python/tests/proton_tests/engine.py
b/python/tests/proton_tests/engine.py
index 94010d61e..5289db059 100644
--- a/python/tests/proton_tests/engine.py
+++ b/python/tests/proton_tests/engine.py
@@ -2320,7 +2320,7 @@ class ReceivedTester(DispositionTester):
assert dlv.remote_state == self._type
assert dlv.remote.type == self._type
assert dlv.remote.section_number == self._section_number,
(dlv.remote.section_number, self._section_number)
- assert dlv.remote.section_offset == self._section_offset
+ assert dlv.remote.section_offset == self._section_offset,
(dlv.remote.section_offset, self._section_offset)
class NewReceivedTester(DispositionTester):
@@ -2356,8 +2356,8 @@ class ModifiedTester(DispositionTester):
def check(self, dlv: Delivery):
assert dlv.remote_state == self._type
assert dlv.remote.type == self._type
- assert dlv.remote.failed == self._failed
- assert dlv.remote.undeliverable == self._undeliverable
+ assert dlv.remote.failed == self._failed, (dlv.remote.failed,
self._failed)
+ assert dlv.remote.undeliverable == self._undeliverable,
(dlv.remote.undeliverable, self._undeliverable)
assert dlv.remote.annotations == self._annotations,
(dlv.remote.annotations, self._annotations)
@@ -2375,8 +2375,8 @@ class NewModifiedTester(DispositionTester):
def check(self, dlv: Delivery):
assert dlv.remote_state == self._type
assert dlv.remote.type == self._type
- assert dlv.remote.failed == self._failed
- assert dlv.remote.undeliverable == self._undeliverable
+ assert dlv.remote.failed == self._failed, (dlv.remote.failed,
self._failed)
+ assert dlv.remote.undeliverable == self._undeliverable,
(dlv.remote.undeliverable, self._undeliverable)
assert dlv.remote.annotations == self._annotations,
(dlv.remote.annotations, self._annotations)
@@ -2392,7 +2392,7 @@ class CustomTester(DispositionTester):
def check(self, dlv: Delivery):
assert dlv.remote_state == self._type
assert dlv.remote.type == self._type
- assert dlv.remote.data == self._data, (dlv.data, self._data)
+ assert dlv.remote.data == self._data, (dlv.remote.data, self._data)
class NewCustomTester(DispositionTester):
@@ -2407,7 +2407,7 @@ class NewCustomTester(DispositionTester):
def check(self, dlv: Delivery):
assert dlv.remote_state == self._type
assert dlv.remote.type == self._type, (dlv.remote.type, self._type)
- assert dlv.remote.data == self._data, (dlv.data, self._data)
+ assert dlv.remote.data == self._data, (dlv.remote.data, self._data)
class TransactionalTester(DispositionTester):
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]