mirror of git://git.sysmocom.de/ofono
cbs: Allow the last CBS fragment to be truncated
That does happen in real life.
This commit is contained in:
parent
6cc1851b18
commit
cf4a4a7bd0
|
@ -1756,7 +1756,7 @@ gboolean sms_udh_iter_init_from_cbs(const struct cbs *cbs,
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
hdr = cbs->ud;
|
hdr = cbs->ud;
|
||||||
max_ud_len = 82;
|
max_ud_len = cbs->udlen;
|
||||||
|
|
||||||
/* Must have at least one information-element if udhi is true */
|
/* Must have at least one information-element if udhi is true */
|
||||||
if (hdr[0] < 2)
|
if (hdr[0] < 2)
|
||||||
|
@ -3862,8 +3862,8 @@ gboolean cbs_dcs_decode(guint8 dcs, gboolean *udhi, enum sms_class *cls,
|
||||||
|
|
||||||
gboolean cbs_decode(const unsigned char *pdu, int len, struct cbs *out)
|
gboolean cbs_decode(const unsigned char *pdu, int len, struct cbs *out)
|
||||||
{
|
{
|
||||||
/* CBS is always a fixed length of 88 bytes */
|
/* CBS is (almost) always a fixed length of 88 bytes */
|
||||||
if (len != 88)
|
if (len < 6 || len > 88)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
out->gs = (enum cbs_geo_scope) ((pdu[0] >> 6) & 0x03);
|
out->gs = (enum cbs_geo_scope) ((pdu[0] >> 6) & 0x03);
|
||||||
|
@ -3874,6 +3874,10 @@ gboolean cbs_decode(const unsigned char *pdu, int len, struct cbs *out)
|
||||||
out->max_pages = pdu[5] & 0xf;
|
out->max_pages = pdu[5] & 0xf;
|
||||||
out->page = (pdu[5] >> 4) & 0xf;
|
out->page = (pdu[5] >> 4) & 0xf;
|
||||||
|
|
||||||
|
/* Allow the last fragment to be truncated */
|
||||||
|
if (len != 88 && out->max_pages != out->page)
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* If a mobile receives the code 0000 in either the first field or
|
* If a mobile receives the code 0000 in either the first field or
|
||||||
* the second field then it shall treat the CBS message exactly the
|
* the second field then it shall treat the CBS message exactly the
|
||||||
|
@ -3885,7 +3889,10 @@ gboolean cbs_decode(const unsigned char *pdu, int len, struct cbs *out)
|
||||||
out->page = 1;
|
out->page = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
memcpy(out->ud, pdu + 6, 82);
|
out->udlen = (guint8)(len - 6);
|
||||||
|
memcpy(out->ud, pdu + 6, out->udlen);
|
||||||
|
if (out->udlen < 82)
|
||||||
|
memset(out->ud + out->udlen, 0, 82 - out->udlen);
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
@ -4078,7 +4085,7 @@ char *cbs_decode_text(GSList *cbs_list, char *iso639_lang)
|
||||||
if (iso639)
|
if (iso639)
|
||||||
bufsize -= 3;
|
bufsize -= 3;
|
||||||
} else {
|
} else {
|
||||||
bufsize += 82;
|
bufsize += cbs->udlen;
|
||||||
|
|
||||||
if (iso639)
|
if (iso639)
|
||||||
bufsize -= 2;
|
bufsize -= 2;
|
||||||
|
@ -4095,7 +4102,7 @@ char *cbs_decode_text(GSList *cbs_list, char *iso639_lang)
|
||||||
if (sms_udh_iter_init_from_cbs(cbs, &iter))
|
if (sms_udh_iter_init_from_cbs(cbs, &iter))
|
||||||
taken = sms_udh_iter_get_udh_length(&iter) + 1;
|
taken = sms_udh_iter_get_udh_length(&iter) + 1;
|
||||||
|
|
||||||
unpack_7bit_own_buf(cbs->ud + taken, 82 - taken,
|
unpack_7bit_own_buf(cbs->ud + taken, cbs->udlen - taken,
|
||||||
taken, false, 2,
|
taken, false, 2,
|
||||||
NULL, 0,
|
NULL, 0,
|
||||||
(unsigned char *)iso639_lang);
|
(unsigned char *)iso639_lang);
|
||||||
|
@ -4128,7 +4135,7 @@ char *cbs_decode_text(GSList *cbs_list, char *iso639_lang)
|
||||||
max_chars =
|
max_chars =
|
||||||
sms_text_capacity_gsm(CBS_MAX_GSM_CHARS, taken);
|
sms_text_capacity_gsm(CBS_MAX_GSM_CHARS, taken);
|
||||||
|
|
||||||
unpack_7bit_own_buf(ud + taken, 82 - taken,
|
unpack_7bit_own_buf(ud + taken, cbs->udlen - taken,
|
||||||
taken, false, max_chars,
|
taken, false, max_chars,
|
||||||
&written, 0, unpacked);
|
&written, 0, unpacked);
|
||||||
|
|
||||||
|
@ -4162,7 +4169,7 @@ char *cbs_decode_text(GSList *cbs_list, char *iso639_lang)
|
||||||
* the check here since the specification isn't clear
|
* the check here since the specification isn't clear
|
||||||
*/
|
*/
|
||||||
} else {
|
} else {
|
||||||
int num_ucs2_chars = (82 - taken) >> 1;
|
int num_ucs2_chars = (cbs->udlen - taken) >> 1;
|
||||||
int i = taken;
|
int i = taken;
|
||||||
int max_offset = taken + num_ucs2_chars * 2;
|
int max_offset = taken + num_ucs2_chars * 2;
|
||||||
|
|
||||||
|
|
|
@ -408,6 +408,7 @@ struct cbs {
|
||||||
guint8 dcs; /* 8 bits */
|
guint8 dcs; /* 8 bits */
|
||||||
guint8 max_pages; /* 4 bits */
|
guint8 max_pages; /* 4 bits */
|
||||||
guint8 page; /* 4 bits */
|
guint8 page; /* 4 bits */
|
||||||
|
guint8 udlen;
|
||||||
guint8 ud[82];
|
guint8 ud[82];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue