diff options
-rw-r--r-- | readeeprom.cpp | 47 |
1 files changed, 40 insertions, 7 deletions
diff --git a/readeeprom.cpp b/readeeprom.cpp index d518a83..f5fa148 100644 --- a/readeeprom.cpp +++ b/readeeprom.cpp @@ -17,13 +17,51 @@ static void exit_with_error(const char* err, char** argv) exit(-1); } +static uint8_t parse_fruid_or_exit(const char* fruid_str, char** argv) +{ + const uint8_t MAX_FRU_ID = 0xfe; + unsigned long fruid; + char* endptr = NULL; + + // The FRUID string must not be empty. + if (fruid_str == nullptr || *fruid_str == '\0') + { + exit_with_error("Empty fruid.", argv); + } + + errno = 0; + fruid = std::strtoul(fruid_str, &endptr, 16); + + // Handle error cases + if (errno == ERANGE) + { + exit_with_error("fruid is out of range.", argv); + } + if (errno != 0) + { + exit_with_error("Could not parse fruid.", argv); + } + if (*endptr != '\0') + { + // The string was not fully parsed, e.g. contains invalid characters + exit_with_error("Invalid fruid.", argv); + } + if (fruid > MAX_FRU_ID) + { + // The string was parsed, but the set FRUID is too large. + exit_with_error("fruid is out of range.", argv); + } + + return fruid; +} + //-------------------------------------------------------------------------- // This gets called by udev monitor soon after seeing hog plugs for EEPROMS. //-------------------------------------------------------------------------- int main(int argc, char** argv) { int rc = 0; - uint8_t fruid = 0; + uint8_t fruid; // Read the arguments. auto cli_options = std::make_unique<ArgumentParser>(argc, argv); @@ -44,12 +82,7 @@ int main(int argc, char** argv) } // Extract the fruid - fruid = std::strtol(fruid_str.c_str(), NULL, 16); - if (fruid == 0) - { - // User has not passed in the appropriate argument value - exit_with_error("Invalid fruid.", argv); - } + fruid = parse_fruid_or_exit(fruid_str.c_str(), argv); // Finished getting options out, so release the parser. cli_options.release(); |