summaryrefslogtreecommitdiff
path: root/libgps_sock.c
diff options
context:
space:
mode:
authorGary E. Miller <gem@rellim.com>2019-04-29 18:16:49 -0700
committerGary E. Miller <gem@rellim.com>2019-04-29 18:16:49 -0700
commitbeda62396c60839a3b48da6f4972fe92ff123302 (patch)
tree1b9f23d8ce183e6e6d2f583bd402a5049b1a227d /libgps_sock.c
parentd51b8eb7a4efc48850eee4110503b2239f6a4770 (diff)
downloadgpsd-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.c13
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;