Abort parsing in case of format error

Usecase:
1. Enable hf client and connect to AG.
2. Send +COPS with length more than allowed 16 characters.

Failure:
Crash might be seen while parsing +COPS response from AG.

Root cause:
sscanf used for parsing the AT commands does not update
the characters scanned when there is format error.

Fix:
Abort the processing in case of format error.

Change-Id: Id3ca80712df3d0251cf9ffb04d9c766be809ae84
diff --git a/bta/hf_client/bta_hf_client_at.c b/bta/hf_client/bta_hf_client_at.c
index 3eafa23..610bc88 100644
--- a/bta/hf_client/bta_hf_client_at.c
+++ b/bta/hf_client/bta_hf_client_at.c
@@ -692,7 +692,7 @@
 
 static char *bta_hf_client_parse_cind_list(char *buffer)
 {
-    int offset;
+    int offset = 0;
     char name[129];
     UINT32 min, max;
     UINT32 index = 0;
@@ -701,6 +701,12 @@
     while ((res = sscanf(buffer, "(\"%128[^\"]\",(%u%*[-,]%u))%n", name, &min, &max, &offset)) > 2)
     {
         bta_hf_client_handle_cind_list_item(name, min, max, index);
+        if (offset == 0)
+        {
+            APPL_TRACE_ERROR("%s: Format Error %s", __func__, buffer);
+            return NULL;
+        }
+
         buffer += offset;
         index++;
 
@@ -808,7 +814,7 @@
 {
     UINT32 index, value;
     int res;
-    int offset;
+    int offset = 0;
 
     AT_CHECK_EVENT(buffer, "+CIEV:");
 
@@ -818,6 +824,12 @@
         return NULL;
     }
 
+    if (offset == 0)
+    {
+        APPL_TRACE_ERROR("%s: Format Error %s", __func__, buffer);
+        return NULL;
+    }
+
     buffer += offset;
 
     AT_CHECK_RN(buffer);
@@ -888,7 +900,7 @@
     char number[33];
     UINT32 type = 0;
     int res;
-    int offset;
+    int offset = 0;
 
     AT_CHECK_EVENT(buffer, "+CLIP:");
 
@@ -899,6 +911,12 @@
         return NULL;
     }
 
+    if (offset == 0)
+    {
+        APPL_TRACE_ERROR("%s: Format Error %s", __func__, buffer);
+        return NULL;
+    }
+
     buffer += offset;
 
     AT_SKIP_REST(buffer);
@@ -916,7 +934,7 @@
     char number[33];
     UINT32 type = 0;
     int res ;
-    int offset;
+    int offset = 0;
 
     AT_CHECK_EVENT(buffer, "+CCWA:");
 
@@ -927,6 +945,12 @@
         return NULL;
     }
 
+    if (offset == 0)
+    {
+        APPL_TRACE_ERROR("%s: Format Error %s", __func__, buffer);
+        return NULL;
+    }
+
     buffer += offset;
 
     AT_SKIP_REST(buffer);
@@ -953,6 +977,12 @@
     {
         return NULL;
     }
+    /* Abort in case offset not set because of format error */
+    if (offset == 0)
+    {
+        APPL_TRACE_ERROR("%s: Format Error %s", __func__, buffer);
+        return NULL;
+    }
 
     buffer += offset;
 
@@ -970,7 +1000,7 @@
     /* phone number is 32 chars plus one for \0*/
     char numstr[33];
     int res;
-    int offset;
+    int offset = 0;
 
     AT_CHECK_EVENT(buffer, "+BINP:");
 
@@ -980,6 +1010,13 @@
         return NULL;
     }
 
+    /* Abort in case offset not set because of format error */
+    if (offset == 0)
+    {
+        APPL_TRACE_ERROR("%s: Format Error %s", __func__, buffer);
+        return NULL;
+    }
+
     buffer += offset;
 
     /* some phones might sent type as well, just skip it */
@@ -997,7 +1034,7 @@
     char numstr[33];     /* spec forces 32 chars, plus one for \0*/
     UINT16 type;
     int res;
-    int offset;
+    int offset = 0;
 
     AT_CHECK_EVENT(buffer, "+CLCC:");
 
@@ -1008,7 +1045,15 @@
         return NULL;
     }
 
+    /* Abort in case offset not set because of format error */
+    if (offset == 0)
+    {
+        APPL_TRACE_ERROR("%s: Format Error %s", __func__, buffer);
+        return NULL;
+    }
+
     buffer += offset;
+    offset = 0;
 
     /* check optional part */
     if (*buffer == ',')
@@ -1031,6 +1076,13 @@
         if (res2 >= 2)
         {
             res += res2;
+            /* Abort in case offset not set because of format error */
+            if (offset == 0)
+            {
+                APPL_TRACE_ERROR("%s: Format Error %s", __func__, buffer);
+                return NULL;
+            }
+
             buffer += offset;
         }
     }
@@ -1059,7 +1111,7 @@
     UINT16 type;
     UINT16 service = 0; /* 0 in case this optional parameter is not being sent */
     int res;
-    int offset;
+    int offset = 0;
 
     AT_CHECK_EVENT(buffer, "+CNUM:");
 
@@ -1087,6 +1139,13 @@
         return NULL;
     }
 
+    /* Abort in case offset not set because of format error */
+    if (offset == 0)
+    {
+        APPL_TRACE_ERROR("%s: Format Error %s", __func__, buffer);
+        return NULL;
+    }
+
     buffer += offset;
 
     AT_CHECK_RN(buffer);
@@ -1431,6 +1490,11 @@
     APPL_TRACE_DEBUG("%s", __FUNCTION__);
 
     at_len = snprintf(buf, sizeof(buf), "AT+BRSF=%u\r", bta_hf_client_cb.scb.features);
+    if (at_len < 0)
+    {
+        APPL_TRACE_ERROR("%s: AT command Framing error", __func__);
+        return;
+    }
 
     bta_hf_client_send_at(BTA_HF_CLIENT_AT_BRSF , buf, at_len);
 }
@@ -1461,6 +1525,11 @@
     APPL_TRACE_DEBUG("%s", __FUNCTION__);
 
     at_len = snprintf(buf, sizeof(buf), "AT+BCS=%u\r", codec);
+    if (at_len < 0)
+    {
+        APPL_TRACE_ERROR("%s: AT command Framing error", __func__);
+        return;
+    }
 
     bta_hf_client_send_at(BTA_HF_CLIENT_AT_BCS, buf, at_len);
 }
@@ -1512,6 +1581,12 @@
     else
         at_len = snprintf(buf, sizeof(buf), "AT+CHLD=%c\r", cmd);
 
+    if (at_len < 0)
+    {
+        APPL_TRACE_ERROR("%s: AT command Framing error", __func__);
+        return;
+    }
+
     bta_hf_client_send_at(BTA_HF_CLIENT_AT_CHLD, buf, at_len);
 }
 
@@ -1605,6 +1680,11 @@
     APPL_TRACE_DEBUG("%s", __FUNCTION__);
 
     at_len = snprintf(buf, sizeof(buf), "AT+VGS=%u\r", volume);
+    if (at_len < 0)
+    {
+        APPL_TRACE_ERROR("%s: AT command Framing error", __func__);
+        return;
+    }
 
     bta_hf_client_send_at(BTA_HF_CLIENT_AT_VGS, buf, at_len);
 }
@@ -1617,6 +1697,11 @@
     APPL_TRACE_DEBUG("%s", __FUNCTION__);
 
     at_len = snprintf(buf, sizeof(buf), "AT+VGM=%u\r", volume);
+    if (at_len < 0)
+    {
+        APPL_TRACE_ERROR("%s: AT command Framing error", __func__);
+        return;
+    }
 
     bta_hf_client_send_at(BTA_HF_CLIENT_AT_VGM, buf, at_len);
 }
@@ -1633,13 +1718,19 @@
     } else {
         at_len = snprintf(buf, sizeof(buf), "ATD>%u;\r", memory);
     }
+
     if (at_len < 0) {
-        APPL_TRACE_ERROR("%s: error preparing ATD command");
+        APPL_TRACE_ERROR("%s: error preparing ATD command", __func__);
         return;
     }
 
     at_len = MIN((size_t)at_len, sizeof(buf));
 
+    if (at_len < 0)
+    {
+        APPL_TRACE_ERROR("%s: AT command Framing error", __func__);
+        return;
+    }
     bta_hf_client_send_at(BTA_HF_CLIENT_AT_ATD, buf, at_len);
 }
 
@@ -1692,6 +1783,12 @@
         at_len = snprintf(buf, sizeof(buf), "AT+BTRH=%u\r", val);
     }
 
+    if (at_len < 0)
+    {
+        APPL_TRACE_ERROR("%s: AT command Framing error", __func__);
+        return;
+    }
+
     bta_hf_client_send_at(BTA_HF_CLIENT_AT_BTRH, buf, at_len);
 }
 
@@ -1704,6 +1801,12 @@
 
     at_len = snprintf(buf, sizeof(buf), "AT+VTS=%c\r", code);
 
+    if (at_len < 0)
+    {
+        APPL_TRACE_ERROR("%s: AT command Framing error", __func__);
+        return;
+    }
+
     bta_hf_client_send_at(BTA_HF_CLIENT_AT_VTS, buf, at_len);
 }
 
@@ -1755,6 +1858,12 @@
 
     at_len = snprintf(buf, sizeof(buf), "AT+BINP=%u\r", action);
 
+    if (at_len < 0)
+    {
+        APPL_TRACE_ERROR("%s: AT command Framing error", __func__);
+        return;
+    }
+
     bta_hf_client_send_at(BTA_HF_CLIENT_AT_BINP, buf, at_len);
 }
 
@@ -1782,6 +1891,12 @@
 
     buf[at_len - 1] = '\r';
 
+    if (at_len < 0)
+    {
+        APPL_TRACE_ERROR("%s: AT command Framing error", __func__);
+        return;
+    }
+
     bta_hf_client_send_at(BTA_HF_CLIENT_AT_BIA, buf, at_len);
 }