aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorPau Espin Pedrol <pespin@sysmocom.de>2021-10-19 17:39:03 +0200
committerPau Espin Pedrol <pespin@sysmocom.de>2021-10-20 15:36:01 +0200
commit1859ec38cc4f4e3788e495a100fdec3787d25020 (patch)
tree6b694fe2bba1c9be2a005b0c76ce443de250e46e /src
parentebdc0d8c170ee2dbf23b19056d6c2d0ef316b3c2 (diff)
csn1: Avoid storing existence bit as true if content was actually NULL
If we decode Exist bit as "1" but we are at the end of the message, and all the Next items we'd read are expected to be possibly NULL, then swap the Exist bit in the decoded structure as "0" in order to tell the decoder user that the related information structure is actually unset, as if "0" was received. Related: SYS#5552 Related: OS#4955 Related: OS#5020 Change-Id: I38602e4b680ed87297c7e440691a494c07cad446
Diffstat (limited to 'src')
-rw-r--r--src/csn1_dec.c42
1 files changed, 36 insertions, 6 deletions
diff --git a/src/csn1_dec.c b/src/csn1_dec.c
index 4bc74f36..fa1f0c39 100644
--- a/src/csn1_dec.c
+++ b/src/csn1_dec.c
@@ -909,6 +909,7 @@ csnStreamDecoder(csnStream_t* ar, const CSN_DESCR* pDescr, struct bitvec *vector
case CSN_NEXT_EXIST:
{
guint8 fExist;
+ guint8 isnull;
pui8 = pui8DATA(data, pDescr->offset);
@@ -927,17 +928,30 @@ csnStreamDecoder(csnStream_t* ar, const CSN_DESCR* pDescr, struct bitvec *vector
/* the "regular" M_NEXT_EXIST description element */
fExist = 0x00;
+ isnull = 1;
if (bitvec_read_field(vector, readIndex, 1))
{
fExist = 0x01;
+ if (remaining_bits_len == 1) {
+ /* If { 1 < end > } and all next items may be null, store it as { 0 } */
+ const CSN_DESCR* pDescrNext = pDescr + 1;
+ guint8 i;
+ for (i = 0; i < pDescr->i; i++, pDescrNext++)
+ {
+ if (!pDescrNext->may_be_null)
+ isnull = 0;
+ }
+ } else {
+ isnull = 0;
+ }
}
- *pui8 = fExist;
+ *pui8 = !isnull;
remaining_bits_len -= 1;
- LOGPC(DCSN1, LOGL_DEBUG, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
+ LOGPC(DCSN1, LOGL_DEBUG, "%s = %u%s | ", pDescr->sz, (unsigned)fExist, fExist && isnull ? " (NULL)" : "");
++bit_offset;
- if (fExist == 0)
+ if (isnull)
{ /* Skip 'i' entries */
pDescr += pDescr->i;
}
@@ -949,6 +963,7 @@ csnStreamDecoder(csnStream_t* ar, const CSN_DESCR* pDescr, struct bitvec *vector
case CSN_NEXT_EXIST_LH:
{
guint8 fExist;
+ guint8 isnull;
pui8 = pui8DATA(data, pDescr->offset);
/* this if-statement represents the M_NEXT_EXIST_OR_NULL_LH description element */
@@ -964,14 +979,29 @@ csnStreamDecoder(csnStream_t* ar, const CSN_DESCR* pDescr, struct bitvec *vector
}
/* the "regular" M_NEXT_EXIST_LH description element */
- fExist = get_masked_bits8(vector, readIndex, bit_offset, 1);
- LOGPC(DCSN1, LOGL_DEBUG, "%s = %u | ", pDescr->sz , (unsigned)fExist);
+ isnull = 1;
+ if ((fExist = get_masked_bits8(vector, readIndex, bit_offset, 1)))
+ {
+ if (remaining_bits_len == 1) {
+ /* If { 1 < end > } and all next items may be null, store it as { 0 } */
+ const CSN_DESCR* pDescrNext = pDescr + 1;
+ guint8 i;
+ for (i = 0; i < pDescr->i; i++, pDescrNext++)
+ {
+ if (!pDescrNext->may_be_null)
+ isnull = 0;
+ }
+ } else {
+ isnull = 0;
+ }
+ }
+ LOGPC(DCSN1, LOGL_DEBUG, "%s = %u%s | ", pDescr->sz , (unsigned)fExist, fExist && isnull ? " (NULL)" : "");
*pui8++ = fExist;
remaining_bits_len -= 1;
bit_offset++;
- if (fExist == 0)
+ if (isnull)
{ /* Skip 'i' entries */
pDescr += pDescr->i;
}