diff --git a/src/sgpsdp/sgp_in.c b/src/sgpsdp/sgp_in.c index 973462eb..a794312a 100644 --- a/src/sgpsdp/sgp_in.c +++ b/src/sgpsdp/sgp_in.c @@ -76,6 +76,46 @@ int Checksum_Good(char *tle_set) return (checksum == check_digit); } +/* Checks that the epoch field in columns 19-32 of line 1 (YYDDD.FFFFFFFF) + holds a number that Convert_Satellite_Data() can read in full: digits, + with spaces allowed only where they are padding, i.e. in place of the + leading zeros of the day of year and after the last fraction digit. + Checksum_Good() counts a letter as 0, so a letter that replaced a 0 + would otherwise pass and the epoch would be read up to the letter. */ +static int Epoch_Good(char *tle_set) +{ + int i; + + /* year */ + if (!g_ascii_isdigit(tle_set[18]) || !g_ascii_isdigit(tle_set[19])) + return (0); + + /* day of year; the two leading digits may be padded with spaces */ + for (i = 20; i < 22; i++) + if (!g_ascii_isdigit(tle_set[i]) && (tle_set[i] != ' ')) + return (0); + if ((tle_set[20] != ' ') && (tle_set[21] == ' ')) + return (0); + if (!g_ascii_isdigit(tle_set[22])) + return (0); + + /* fraction of day; at least one digit, trailing spaces allowed */ + if (!g_ascii_isdigit(tle_set[24])) + return (0); + for (i = 25; i < 32; i++) + { + if (tle_set[i] == ' ') + break; + if (!g_ascii_isdigit(tle_set[i])) + return (0); + } + for (; i < 32; i++) + if (tle_set[i] != ' ') + return (0); + + return (1); +} + /* Carries out various checks on a TLE set to verify its validity */ /* tle_set is a character string holding the two lines read */ /* from a text file containing NASA format Keplerian elements. */ @@ -99,6 +139,9 @@ int Good_Elements(char *tle_set) (tle_set[115] != '.') || (tle_set[123] != '.') || (strncmp(&tle_set[61], " 0 ", 3) != 0)) return (0); + /* Check that the epoch is a well-formed number */ + if (!Epoch_Good(tle_set)) + return (0); return (1); } diff --git a/src/sgpsdp/test-001.c b/src/sgpsdp/test-001.c index 1a3287ff..30440859 100644 --- a/src/sgpsdp/test-001.c +++ b/src/sgpsdp/test-001.c @@ -67,6 +67,22 @@ const dataset_t expected[TEST_STEPS] = { }; +/* check digit of a 69 character TLE line, as computed by Checksum_Good() */ +static char line_checksum(const char *line) +{ + int i, sum = 0; + + for (i = 0; i < 68; i++) + { + if ((line[i] >= '0') && (line[i] <= '9')) + sum += line[i] - '0'; + else if (line[i] == '-') + sum += 1; + } + + return (char)('0' + sum % 10); +} + char tle_str[3][80]; sat_t sat; @@ -127,6 +143,39 @@ int main(void) return 1; } + /* a letter in the epoch field must be rejected, even when it + replaced a 0 and the checksum still holds */ + { + char tle_set[139]; + + memcpy(tle_set, tle_str[1], 69); + memcpy(&tle_set[69], tle_str[2], 69); + tle_set[138] = '\0'; + + if (!Good_Elements(tle_set)) + { + printf("Good_Elements() rejected the unmodified TLE\n"); + return 1; + } + + tle_set[27] = 'O'; /* epoch 80275.98708465 -> 80275.987O8465 */ + if (Good_Elements(tle_set)) + { + printf("Good_Elements() accepted a letter in the epoch\n"); + return 1; + } + + tle_set[27] = '0'; + tle_set[20] = ' '; /* day of year 5, padded with spaces */ + tle_set[21] = ' '; + tle_set[68] = line_checksum(tle_set); + if (!Good_Elements(tle_set)) + { + printf("Good_Elements() rejected a space-padded day of year\n"); + return 1; + } + } + select_ephemeris(&sat); printf("\nDEEP_SPACE_EPHEM: %d (expected 0)\n\n",