summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTycho <work.tycho+git@gmail.com>2014-08-13 14:03:56 +0200
committerTycho <work.tycho+git@gmail.com>2014-08-13 14:03:56 +0200
commit781e1e6264794ec0fddccd37a76f7a78a3fa8b09 (patch)
tree694dabff0db889d7326e2cb3e7febae4271b788f
parentFixed type issues in CraftingRecipe.cpp (diff)
downloadcuberite-781e1e6264794ec0fddccd37a76f7a78a3fa8b09.tar
cuberite-781e1e6264794ec0fddccd37a76f7a78a3fa8b09.tar.gz
cuberite-781e1e6264794ec0fddccd37a76f7a78a3fa8b09.tar.bz2
cuberite-781e1e6264794ec0fddccd37a76f7a78a3fa8b09.tar.lz
cuberite-781e1e6264794ec0fddccd37a76f7a78a3fa8b09.tar.xz
cuberite-781e1e6264794ec0fddccd37a76f7a78a3fa8b09.tar.zst
cuberite-781e1e6264794ec0fddccd37a76f7a78a3fa8b09.zip
-rw-r--r--src/CraftingRecipes.cpp6
-rw-r--r--src/StringUtils.h62
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