diff options
author | Gary E. Miller <gem@rellim.com> | 2019-04-29 18:16:49 -0700 |
---|---|---|
committer | Gary E. Miller <gem@rellim.com> | 2019-04-29 18:16:49 -0700 |
commit | beda62396c60839a3b48da6f4972fe92ff123302 (patch) | |
tree | 1b9f23d8ce183e6e6d2f583bd402a5049b1a227d /libgps_sock.c | |
parent | d51b8eb7a4efc48850eee4110503b2239f6a4770 (diff) | |
download | gpsd-beda62396c60839a3b48da6f4972fe92ff123302.tar.gz |
libgps_sock: Stop seg fault on overlong JSON.
Should never happen if GPS_JSON_RESPONSE_MAX is long enough. But
things always get longer. Or malicious...
Diffstat (limited to 'libgps_sock.c')
-rw-r--r-- | libgps_sock.c | 13 |
1 files changed, 9 insertions, 4 deletions
diff --git a/libgps_sock.c b/libgps_sock.c index 14811b68..7da4c5f1 100644 --- a/libgps_sock.c +++ b/libgps_sock.c @@ -253,16 +253,21 @@ int gps_sock_read(struct gps_data_t *gpsdata, char *message, int message_len) /* unpack the JSON message */ status = gps_unpack(PRIVATE(gpsdata)->buffer, gpsdata); + /* why the 1? */ response_length = eol - PRIVATE(gpsdata)->buffer + 1; - if (0 == (PRIVATE(gpsdata)->waiting - response_length)) { - /* no waiting data, clear the buffer, just in case */ + + /* calculate length of good data still in buffer */ + PRIVATE(gpsdata)->waiting -= response_length; + + if (1 > PRIVATE(gpsdata)->waiting) { + /* no waiting data, or overflow, clear the buffer, just in case */ *PRIVATE(gpsdata)->buffer = '\0'; + PRIVATE(gpsdata)->waiting = 0; } else { memmove(PRIVATE(gpsdata)->buffer, PRIVATE(gpsdata)->buffer + response_length, - PRIVATE(gpsdata)->waiting - response_length); + PRIVATE(gpsdata)->waiting); } - PRIVATE(gpsdata)->waiting -= response_length; gpsdata->set |= PACKET_SET; return (status == 0) ? (int)response_length : status; |