Skip to content

Commit 590d70e

Browse files
committed
Fix parse_csv() dropping the final CSV field
parse_csv() advances bptr and strdups into buf on every comma, but on the terminating '\0' it only sets fEnd and breaks out of the loop. The content accumulated in tmp since the last comma was never emitted, so for an N-field CSV the function returned N-1 strings followed by NULL even though count_fields() correctly reported N. In practice this meant buf[N-1] was NULL. Callers like _parseCSV() that read the last field (e.g. atof(fields[3]) for the elevation in a value,lat,lon,ele location CSV) dereferenced NULL and crashed with LoadProhibited on ESP32. The bug was masked on main by a second bug in _parseCSV() that incorrectly read fields[1] three times instead of fields[1..3], so the last slot was never actually accessed. Fix: emit the final field from inside the '\0' case before setting fEnd. Uses the same strdup + allocation-failure cleanup as the ',' case.
1 parent 7092002 commit 590d70e

File tree

1 file changed

+15
-0
lines changed

1 file changed

+15
-0
lines changed

src/AdafruitIO_Data.cpp

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -823,6 +823,21 @@ char **parse_csv(const char *line) {
823823
fQuote = 1;
824824
continue;
825825
case '\0':
826+
// Emit the final field. Previously this was dropped on the floor
827+
// because the null terminator only set fEnd and broke the loop,
828+
// so parse_csv() returned one fewer field than count_fields()
829+
// reported. Callers reading fields[n-1] would then dereference NULL.
830+
*tptr = '\0';
831+
*bptr = strdup(tmp);
832+
if (!*bptr) {
833+
for (bptr--; bptr >= buf; bptr--) {
834+
free(*bptr);
835+
}
836+
free(buf);
837+
free(tmp);
838+
return NULL;
839+
}
840+
bptr++;
826841
fEnd = 1;
827842
break;
828843
case ',':

0 commit comments

Comments
 (0)