From 9820a658468aa692c7d1f1914a5539f778b34b09 Mon Sep 17 00:00:00 2001 From: chrysn Date: Fri, 5 Apr 2024 23:26:45 +0200 Subject: [PATCH] cord_lc: Process truncated reads Co-Authored-By: Marian Buschsieweke --- sys/net/application_layer/cord/lc/cord_lc.c | 29 ++++++++++++++------- 1 file changed, 20 insertions(+), 9 deletions(-) diff --git a/sys/net/application_layer/cord/lc/cord_lc.c b/sys/net/application_layer/cord/lc/cord_lc.c index 68fb2032b832..eddda2f7e7b1 100644 --- a/sys/net/application_layer/cord/lc/cord_lc.c +++ b/sys/net/application_layer/cord/lc/cord_lc.c @@ -204,6 +204,8 @@ static void _on_rd_init(const gcoap_request_memo_t *memo, coap_pkt_t *pdu, (void)remote; thread_flags_t flag = FLAG_NORSC; + size_t full_buf_len = _result_buf_len; + _result_buf_len = 0; if (memo->state == GCOAP_MEMO_RESP) { unsigned ct = coap_get_content_type(pdu); @@ -211,23 +213,30 @@ static void _on_rd_init(const gcoap_request_memo_t *memo, coap_pkt_t *pdu, DEBUG("cord_lc: error payload not in link format: %u\n", ct); goto end; } - if (pdu->payload_len == 0) { + size_t size = pdu->payload_len; + + if (size == 0) { DEBUG("cord_lc: error empty payload\n"); goto end; } - memcpy(_result_buf, pdu->payload, pdu->payload_len); - _result_buf_len = pdu->payload_len; - _result_buf[_result_buf_len] = '\0'; + if (size >= full_buf_len) { + DEBUG("cord_lc: truncating response from %" PRIuSIZE " to %" PRIuSIZE "\n", size, full_buf_len); + /* Not setting FLAG_OVERFLOW: There can still be valid + * .well-known/core lookup data in the usable area, which will be + * used as long as endpoint and resource lookup are both found */ + size = full_buf_len; + memcpy(_result_buf, pdu->payload, full_buf_len); + } + else { + memcpy(_result_buf, pdu->payload, size); + } + _result_buf_len = size; flag = FLAG_SUCCESS; } else if (memo->state == GCOAP_MEMO_TIMEOUT) { flag = FLAG_TIMEOUT; } end: - if (flag != FLAG_SUCCESS) { - _result_buf = NULL; - _result_buf_len = 0; - } thread_flags_set(_waiter, flag); } @@ -281,7 +290,9 @@ int cord_lc_rd_init(cord_lc_rd_t *rd, void *buf, size_t maxlen, clif_attr_t attrs[MAX_EXPECTED_ATTRS]; unsigned attrs_used = 0; size_t parsed_len = 0; - while ((!rd->res_lookif || !rd->ep_lookif) || + /* Quitting the loop once everything we are interested in was found allows + * us to succeed even if the data was truncated by a too small buffer */ + while ((!rd->res_lookif || !rd->ep_lookif) && (parsed_len != _result_buf_len)) { ssize_t ret = clif_decode_link(&lookif, attrs + attrs_used,