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
This commit is contained in:
Pau Espin 2021-10-19 17:39:03 +02:00
parent ebdc0d8c17
commit 1859ec38cc
2 changed files with 37 additions and 7 deletions

View File

@ -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;
}

File diff suppressed because one or more lines are too long