diff --git a/coresdk/src/coresdk/basics.cpp b/coresdk/src/coresdk/basics.cpp index 7fe72bf5..104081ac 100644 --- a/coresdk/src/coresdk/basics.cpp +++ b/coresdk/src/coresdk/basics.cpp @@ -206,7 +206,24 @@ namespace splashkit_lib return 0; } - return stoi(bin_str, nullptr, 2); + try + { + const unsigned long result = std::stoul(bin_str, nullptr, 2); + + if (result > std::numeric_limits::max()) + { + return std::numeric_limits::max(); + } + else + { + return static_cast(result); + } + } + catch (const std::exception& error) + { + LOG(ERROR) << "Invalid binary string \"" << bin_str << "\" passed to bin_to_dec. Returning 0."; + return 0; + } } string hex_to_bin(const string &hex_str) @@ -300,18 +317,52 @@ namespace splashkit_lib return 0; } - return stoi(octal_string, nullptr, 8); + try + { + const unsigned long result = std::stoul(octal_string, nullptr, 8); + + if (result > std::numeric_limits::max()) + { + return std::numeric_limits::max(); + } + else + { + return static_cast(result); + } + } + catch (const std::exception& error) + { + LOG(ERROR) << "Invalid octal string \"" << octal_string << "\" passed to oct_to_dec. Returning 0."; + return 0; + } } unsigned int hex_to_dec(const string &hex_string) { if (!is_hex(hex_string)) { - LOG(ERROR) << "Invalid octal string \"" << hex_string << "\" passed to hex_to_dec. Returning 0."; + LOG(ERROR) << "Invalid hex string \"" << hex_string << "\" passed to hex_to_dec. Returning 0."; return 0; } - return stoi(hex_string, nullptr, 16); + try + { + const unsigned long result = std::stoul(hex_string, nullptr, 16); + + if (result > std::numeric_limits::max()) + { + return std::numeric_limits::max(); + } + else + { + return static_cast(result); + } + } + catch (const std::exception& error) + { + LOG(ERROR) << "Invalid hex string \"" << hex_string << "\" passed to hex_to_dec. Returning 0."; + return 0; + } } string oct_to_bin(const string &octal_str) @@ -496,4 +547,4 @@ namespace splashkit_lib return abs(number1 * number2) / greatest_common_divisor(number1, number2); } -} \ No newline at end of file +} diff --git a/coresdk/src/coresdk/basics.h b/coresdk/src/coresdk/basics.h index ddf1abe1..38778b8b 100644 --- a/coresdk/src/coresdk/basics.h +++ b/coresdk/src/coresdk/basics.h @@ -19,7 +19,7 @@ using std::vector; namespace splashkit_lib { - + /** * Return a new string that removes the spaces from the start and end of * the input string. @@ -101,7 +101,7 @@ namespace splashkit_lib /** * Returns true if the string contains the substring. - * + * * @param text The text to search * @param subtext The substring to search for * @returns True if the substring is found in the text. @@ -110,7 +110,7 @@ namespace splashkit_lib /** * Returns the index of the first occurrence of the substring in the text. - * + * * @param text The text to search * @param subtext The substring to search for * @returns The index of the first occurrence of the substring in the text, or -1 if the substring is not found. @@ -119,7 +119,7 @@ namespace splashkit_lib /** * Replace all occurrences of a substring in a string with another string. - * + * * @param text The text to search * @param substr The substring to find and replace * @param new_text The string to replace the substring with @@ -129,7 +129,7 @@ namespace splashkit_lib /** * Split a string into an array of strings based on a delimiter. - * + * * @param text The text to split * @param delimiter The character to split the text on * @returns An array of strings @@ -169,7 +169,7 @@ namespace splashkit_lib * @returns True if the string is a valid octal string, false otherwise */ bool is_octal(const string &octal_str); - + /** * @brief Converts a decimal (unsigned integer) to a binary string * @@ -187,6 +187,8 @@ namespace splashkit_lib * * Converts the provided binary string into an unsigned integer. * For example, "1010" will be converted to 10. + * Any input that exceedes the max value of unsigned integer will silently truncate and not be treated as an error. + * Any out of range error that occurs will result in the value being returned being 0. * * @param bin Binary string to convert * @@ -235,6 +237,8 @@ namespace splashkit_lib * * Converts the provided octal string into its decimal representation. * For example, "100" will be converted to 64. + * Any input that exceedes the max value of unsigned integer will silently truncate and not be treated as an error. + * Any out of range error that occurs will result in the value being returned being 0. * * @param octal_string Octal string to convert * @@ -280,9 +284,12 @@ namespace splashkit_lib /** * @brief Convert a hexadecimal string to its numeric value. - * + * For example, "A" will be converted to 10. + * Any input that exceedes the max value of unsigned integer will silently truncate and not be treated as an error. + * Any out of range error that occurs will result in the value being returned being 0. + * * @param hex_string the data to convert - * + * * @return unsigned int the numeric value of the hex string */ unsigned int hex_to_dec(const string &hex_string); diff --git a/coresdk/src/test/test_terminal.cpp b/coresdk/src/test/test_terminal.cpp index bb012c43..d3963785 100644 --- a/coresdk/src/test/test_terminal.cpp +++ b/coresdk/src/test/test_terminal.cpp @@ -6,6 +6,7 @@ * Copyright © 2016 Andrew Cain. All rights reserved. */ +#include #include "terminal.h" #include "utils.h" #include @@ -124,6 +125,9 @@ void bin_to_dec() // High values (32-bit boundaries) assert(bin_to_dec("10000000000000000000000000000000") == 2147483648); + // Test for over unsigned int max + assert(bin_to_dec("1111111111111111111111111111111111111111111111111111111111111111") == std::numeric_limits::max()); + // Mixed bits assert(bin_to_dec("1111011") == 123); assert(bin_to_dec("10000000001") == 1025); @@ -143,6 +147,7 @@ void bin_to_dec() assert(bin_to_dec("abcde") != 2147483647); assert(bin_to_dec("a1b2b3i4f02") != 1234); + string bin_input1 = "1111011"; int result1 = bin_to_dec(bin_input1); write_line("1111011 in decimal is " + to_string(result1)); @@ -203,6 +208,59 @@ void hex_to_bin() write_line("-------------------------------------"); } +void hex_to_dec_tests() +{ + write_line("Testing hexadecimal to decimal conversion"); + + // Basic cases + assert(hex_to_dec("0") == 0); + assert(hex_to_dec("1") == 1); + assert(hex_to_dec("A") == 10); + assert(hex_to_dec("F") == 15); + assert(hex_to_dec("10") == 16); + assert(hex_to_dec("FF") == 255); + assert(hex_to_dec("100") == 256); + assert(hex_to_dec("ABC") == 2748); + assert(hex_to_dec("1234") == 4660); + + // Larger hexadecimal values + assert(hex_to_dec("FFFF") == 65535); + assert(hex_to_dec("FFFFFFFF") == 4294967295); + assert(hex_to_dec("1FFFFFF") == 33554431); + assert(hex_to_dec("ABCDEF") == 11259375); + + // Tests for inequality + assert(hex_to_dec("0") != 1); + assert(hex_to_dec("1") != 0); + assert(hex_to_dec("A") != 11); + assert(hex_to_dec("F") != 16); + assert(hex_to_dec("10") != 10); + assert(hex_to_dec("FF") != 256); + assert(hex_to_dec("100") != 255); + assert(hex_to_dec("ABC") != 2749); + assert(hex_to_dec("1234") != 4670); + assert(hex_to_dec("FFFF") != 100); + assert(hex_to_dec("FFFFFFFF") != 200); + assert(hex_to_dec("1FFFFFF") != 300); + assert(hex_to_dec("GGGGGG") != 400); + + // Test over unsigned int + assert(hex_to_dec("100000000") == 4294967295); + // Test over unsigned long + assert(hex_to_dec("10000000000000000") == 0); + + const string hex_input1 = "ABCDEF"; + const unsigned int result1 = hex_to_dec(hex_input1); + write_line("ABCDEF in decimal is " + to_string(result1)); + + const string hex_input2 = "1234"; + const unsigned int result2 = hex_to_dec(hex_input2); + write_line("1234 in decimal is " + to_string(result2)); + + write_line("All hexadecimal to decimal tests passed!"); + write_line("-------------------------------------"); +} + void bin_to_hex() { write_line("Testing binary to hexadecimal conversion"); @@ -341,6 +399,9 @@ void test_oct_to_dec() assert(oct_to_dec("abcde") != 2147483647); assert(oct_to_dec("a1b2b3i4f02") != 1234); + // Test over unsigned int max + assert(oct_to_dec("1777777777777777777777") == std::numeric_limits::max()); + string oct_input1 = "173"; int result1 = oct_to_dec(oct_input1); write_line("173 in decimal is " + to_string(result1)); @@ -885,6 +946,7 @@ void run_terminal_test() dec_to_bin(); bin_to_dec(); hex_to_bin(); + hex_to_dec_tests(); bin_to_hex(); test_dec_to_oct(); test_oct_to_dec();