diff options
-rw-r--r-- | src/CraftingRecipes.cpp | 6 | ||||
-rw-r--r-- | src/StringUtils.h | 62 |
2 files changed, 64 insertions, 4 deletions
diff --git a/src/CraftingRecipes.cpp b/src/CraftingRecipes.cpp index 48178eecb..2d80ecaf8 100644 --- a/src/CraftingRecipes.cpp +++ b/src/CraftingRecipes.cpp @@ -392,8 +392,7 @@ void cCraftingRecipes::AddRecipeLine(int a_LineNum, const AString & a_RecipeLine } if (ResultSplit.size() > 1) { - Recipe->m_Result.m_ItemCount = atoi(ResultSplit[1].c_str()); - if (Recipe->m_Result.m_ItemCount == 0) + if (!StringToInteger<char>(ResultSplit[1].c_str(), Recipe->m_Result.m_ItemCount)) { LOGWARNING("crafting.txt: line %d: Cannot parse result count, ignoring the recipe.", a_LineNum); LOGINFO("Offending line: \"%s\"", a_RecipeLine.c_str()); @@ -445,8 +444,7 @@ bool cCraftingRecipes::ParseItem(const AString & a_String, cItem & a_Item) if (Split.size() > 1) { AString Damage = TrimString(Split[1]); - a_Item.m_ItemDamage = atoi(Damage.c_str()); - if ((a_Item.m_ItemDamage == 0) && (Damage.compare("0") != 0)) + if (!StringToInteger<short>(Damage.c_str(), a_Item.m_ItemDamage)) { // Parsing the number failed return false; diff --git a/src/StringUtils.h b/src/StringUtils.h index 142aaf59b..56ac83942 100644 --- a/src/StringUtils.h +++ b/src/StringUtils.h @@ -99,6 +99,68 @@ extern int GetBEInt(const char * a_Mem); /// Writes four bytes to the specified memory location so that they interpret as BigEndian int extern void SetBEInt(char * a_Mem, Int32 a_Value); +/// Parses any integer type. Checks bounds and +template<class T> +bool StringToInteger(AString a_str, T& a_Num) +{ + size_t i = 0; + T positive = true; + T result = 0; + if (a_str[0] == '+') + { + i++; + } + else if (a_str[0] == '-') + { + i++; + positive = false; + } + if (positive) + { + for(; i <= a_str.size(); i++) + { + if ((a_str[i] <= '0') || (a_str[i] >= '9')) + { + return false; + } + if (std::numeric_limits<T>::max() / 10 < result) + { + return false; + } + result *= 10; + T digit = a_str[i] - '0'; + if (std::numeric_limits<T>::max() - digit < result) + { + return false; + } + result += digit; + } + } + else + { + for(; i <= a_str.size(); i++) + { + if ((a_str[i] <= '0') || (a_str[i] >= '9')) + { + return false; + } + if (std::numeric_limits<T>::min() / 10 > result) + { + return false; + } + result *= 10; + T digit = a_str[i] - '0'; + if (std::numeric_limits<T>::min() + digit > result) + { + return false; + } + result -= digit; + } + } + a_Num = result; + return true; +} + // If you have any other string helper functions, declare them here |