Merge pull request #167 from ladyada-eagleclaw/fix-checksum-validation

Validate NMEA checksum digits and line ending
This commit is contained in:
Limor "Ladyada" Fried authored and GitHub committed 2026-09-14 20:20:42 -04:00
commit c7f66c99ae
2 files changed
+50 -2

No files matched your search

+38
View File
@@ -0,0 +1,38 @@
#include <Adafruit_GPS.h>
Adafruit_GPS GPS;
bool testsPassed = false;
void setup() {
Serial.begin(115200);
// Wait briefly for the Serial Monitor on native USB boards.
while (!Serial && millis() < 5000) {
delay(10);
}
delay(250);
Serial.println("Adafruit GPS checksum regression");
char good[] = "$GPGGA,120009,4807.038,N,01131.000,E,1,08,0.9,545.4,M,46.9,M,,*40";
if (!GPS.parse(good)) {
Serial.println("FAIL: valid checksum was rejected");
return;
}
Serial.println("PASS: valid checksum was accepted");
char bad[] = "$GPGGA,120009,4807.038,N,01131.000,E,1,08,0.9,545.4,M,46.9,M,,*4Z";
if (GPS.parse(bad)) {
Serial.println("FAIL: invalid checksum character was accepted");
return;
}
Serial.println("PASS: invalid checksum character was rejected");
testsPassed = true;
}
void loop() {
if (testsPassed) {
Serial.println("PASS: checksum regression");
} else {
Serial.println("FAIL: checksum regression");
}
delay(2000);
}
+12 -2
View File
@@ -21,6 +21,7 @@
/**************************************************************************/
#include <Adafruit_GPS.h>
#include <ctype.h>
/**************************************************************************/
/*!
@@ -575,8 +576,17 @@ bool Adafruit_GPS::check(char *nmea) {
if (*ast != '*')
return false; // there is no asterisk
else {
uint16_t sum = parseHex(*(ast + 1)) * 16; // extract checksum
sum += parseHex(*(ast + 2));
if (!isxdigit((unsigned char)ast[1]) || !isxdigit((unsigned char)ast[2]))
return false; // checksum must contain two hexadecimal digits
char *end = ast + 3;
if (*end == '\r')
end++;
if (*end == '\n')
end++;
if (*end != '\0')
return false; // only a line ending may follow the checksum
uint16_t sum = parseHex(toupper((unsigned char)ast[1])) * 16;
sum += parseHex(toupper((unsigned char)ast[2]));
char *p = nmea; // check checksum
for (char *p1 = p + 1; p1 < ast; p1++)
sum ^= *p1;