examples: gps: bound NMEA line reads

The GPS example appends serial input to a fixed-size NMEA line buffer until CR or LF without checking the buffer limit. A malformed or overlong input line can write past the end of line[], and the code also uses ch even when read() does not return a byte.

Read bytes only after a successful read(), stop storing at MINMEA_MAX_LENGTH - 1, drain overlong lines until the line ending, and skip parsing truncated sentences.

Generated-by: OpenAI Codex
Signed-off-by: Old-Ding <35417409+Old-Ding@users.noreply.github.com>
This commit is contained in:
Old-Ding 2026-07-06 05:45:03 +08:00 committed by Xiang Xiao
parent f1d53c875d
commit e94e89113a

View file

@ -26,6 +26,7 @@
#include <nuttx/config.h> #include <nuttx/config.h>
#include <stdbool.h>
#include <stdio.h> #include <stdio.h>
#include <fcntl.h> #include <fcntl.h>
#include <wchar.h> #include <wchar.h>
@ -52,9 +53,11 @@ int main(int argc, FAR char *argv[])
{ {
int fd; int fd;
int cnt; int cnt;
ssize_t nread;
char ch; char ch;
char line[MINMEA_MAX_LENGTH]; char line[MINMEA_MAX_LENGTH];
char *port = "/dev/ttyS1"; char *port = "/dev/ttyS1";
bool truncated;
/* Get the GPS serial port argument. If none specified, default to ttyS1 */ /* Get the GPS serial port argument. If none specified, default to ttyS1 */
@ -79,18 +82,38 @@ int main(int argc, FAR char *argv[])
/* Read until we complete a line */ /* Read until we complete a line */
cnt = 0; cnt = 0;
do truncated = false;
for (; ; )
{ {
read(fd, &ch, 1); nread = read(fd, &ch, 1);
if (ch != '\r' && ch != '\n') if (nread <= 0)
{
continue;
}
if (ch == '\r' || ch == '\n')
{
break;
}
if (cnt < MINMEA_MAX_LENGTH - 1)
{ {
line[cnt++] = ch; line[cnt++] = ch;
} }
else
{
truncated = true;
}
} }
while (ch != '\r' && ch != '\n');
line[cnt] = '\0'; line[cnt] = '\0';
if (truncated)
{
continue;
}
switch (minmea_sentence_id(line, false)) switch (minmea_sentence_id(line, false))
{ {
case MINMEA_SENTENCE_RMC: case MINMEA_SENTENCE_RMC: