aboutsummaryrefslogtreecommitdiffstats
path: root/src/gsm/gsm48_ie.c
diff options
context:
space:
mode:
authorOliver Smith <osmith@sysmocom.de>2019-06-06 16:11:32 +0200
committerOliver Smith <osmith@sysmocom.de>2019-06-07 11:01:51 +0200
commit186f87826608fe43060f446ae6d171cd7c56d27b (patch)
treebda352effc081a97888a3a899f90f1e75cce4628 /src/gsm/gsm48_ie.c
parent8c9befeaee7df8758a0584a7fdc988ab9afb14af (diff)
gsm48_decode_bcd_number2: fix ENOSPC edge case
Return ENOSPC if the decoding buffer is one byte too small, instead of returning 0 and silently truncating the string. Add a new "truncated" variable to detect if the loop breaks in the final iteration. The string is not truncated if there is exactly one 0xf ('\0') higher nibble remaining. This is covered by the existing test case "long 15-digit (maximum) MSISDN, limited buffer". Related: OS#4049 Change-Id: Ie05900aca50cc7fe8a45d17844dbfcd905fd82fe
Diffstat (limited to 'src/gsm/gsm48_ie.c')
-rw-r--r--src/gsm/gsm48_ie.c16
1 files changed, 13 insertions, 3 deletions
diff --git a/src/gsm/gsm48_ie.c b/src/gsm/gsm48_ie.c
index 59f931b2..31028ba4 100644
--- a/src/gsm/gsm48_ie.c
+++ b/src/gsm/gsm48_ie.c
@@ -82,6 +82,7 @@ int gsm48_decode_bcd_number2(char *output, size_t output_len,
{
uint8_t in_len;
int i;
+ bool truncated = false;
if (output_len < 1)
return -ENOSPC;
*output = '\0';
@@ -94,14 +95,23 @@ int gsm48_decode_bcd_number2(char *output, size_t output_len,
for (i = 1 + h_len; i <= in_len; i++) {
/* lower nibble */
- if (output_len <= 1)
+ if (output_len <= 1) {
+ truncated = true;
break;
+ }
*output++ = bcd_num_digits[bcd_lv[i] & 0xf];
output_len--;
/* higher nibble */
- if (output_len <= 1)
+ if (output_len <= 1) {
+ /* not truncated if there is exactly one 0xf ('\0') higher nibble remaining */
+ if (i == in_len && (bcd_lv[i] & 0xf0) == 0xf0) {
+ break;
+ }
+
+ truncated = true;
break;
+ }
*output++ = bcd_num_digits[bcd_lv[i] >> 4];
output_len--;
}
@@ -109,7 +119,7 @@ int gsm48_decode_bcd_number2(char *output, size_t output_len,
*output++ = '\0';
/* Indicate whether the output was truncated */
- if (i < in_len)
+ if (truncated)
return -ENOSPC;
return 0;