From e94e89113a39649bdd7d617c99c2302f5df6ecac Mon Sep 17 00:00:00 2001 From: Old-Ding <35417409+Old-Ding@users.noreply.github.com> Date: Mon, 6 Jul 2026 05:45:03 +0800 Subject: [PATCH] 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> --- examples/gps/gps_main.c | 31 +++++++++++++++++++++++++++---- 1 file changed, 27 insertions(+), 4 deletions(-) diff --git a/examples/gps/gps_main.c b/examples/gps/gps_main.c index 68f6da66e..a308f5213 100644 --- a/examples/gps/gps_main.c +++ b/examples/gps/gps_main.c @@ -26,6 +26,7 @@ #include +#include #include #include #include @@ -52,9 +53,11 @@ int main(int argc, FAR char *argv[]) { int fd; int cnt; + ssize_t nread; char ch; char line[MINMEA_MAX_LENGTH]; char *port = "/dev/ttyS1"; + bool truncated; /* 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 */ cnt = 0; - do + truncated = false; + + for (; ; ) { - read(fd, &ch, 1); - if (ch != '\r' && ch != '\n') + nread = read(fd, &ch, 1); + if (nread <= 0) + { + continue; + } + + if (ch == '\r' || ch == '\n') + { + break; + } + + if (cnt < MINMEA_MAX_LENGTH - 1) { line[cnt++] = ch; } + else + { + truncated = true; + } } - while (ch != '\r' && ch != '\n'); line[cnt] = '\0'; + if (truncated) + { + continue; + } + switch (minmea_sentence_id(line, false)) { case MINMEA_SENTENCE_RMC: