aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorTreeston <treeston.mmoc@gmail.com>2020-09-12 20:27:46 +0200
committerTreeston <treeston.mmoc@gmail.com>2020-09-12 20:27:46 +0200
commit090e3da96b101bb29aa0691e5856bd27ff06b0cd (patch)
treeff64aae0f1dd524adc77974ba23625b3635cca4f /src
parent75f9e7396e35360f3016cc0cb21e72e20f5d96d5 (diff)
Core/Chat: Fix hyperlink validation for inspected item links, for real this time.
Diffstat (limited to 'src')
-rw-r--r--src/server/game/Chat/HyperlinkTags.cpp23
-rw-r--r--src/server/game/Chat/Hyperlinks.cpp3
-rw-r--r--src/server/game/Chat/Hyperlinks.h3
3 files changed, 24 insertions, 5 deletions
diff --git a/src/server/game/Chat/HyperlinkTags.cpp b/src/server/game/Chat/HyperlinkTags.cpp
index b7ee7c3e905..acc9139f9f7 100644
--- a/src/server/game/Chat/HyperlinkTags.cpp
+++ b/src/server/game/Chat/HyperlinkTags.cpp
@@ -20,6 +20,7 @@
#include "ObjectMgr.h"
#include "SpellInfo.h"
#include "SpellMgr.h"
+#include <limits>
static constexpr char HYPERLINK_DATA_DELIMITER = ':';
@@ -113,17 +114,31 @@ bool Trinity::Hyperlinks::LinkTags::item::StoreTo(ItemLinkData& val, std::string
if (!t.TryConsumeTo(itemId))
return false;
val.Item = sObjectMgr->GetItemTemplate(itemId);
-
- int randomPropertyId;
+ val.IsBuggedInspectLink = false;
+
+ // randomPropertyId is actually a int16 in the client
+ // positive values index ItemRandomSuffix.dbc, while negative values index ItemRandomProperties.dbc
+ // however, there is also a client bug in inspect packet handling that causes a int16 to be cast to uint16, then int32 (dropping sign extension along the way)
+ // this results in the wrong value being sent in the link; DBC lookup clientside fails, so it sends the link without suffix
+ // to detect and allow these invalid links, we first read randomPropertyId as a full int32
+ int32 randomPropertyId;
if (!(val.Item && t.TryConsumeTo(val.EnchantId) && t.TryConsumeTo(val.GemEnchantId[0]) && t.TryConsumeTo(val.GemEnchantId[1]) &&
- t.TryConsumeTo(val.GemEnchantId[2]) && t.TryConsumeTo(dummy) && t.TryConsumeTo(randomPropertyId) && t.TryConsumeTo(val.PropertySeed) &&
+ t.TryConsumeTo(val.GemEnchantId[2]) && t.TryConsumeTo(dummy) && t.TryConsumeTo(randomPropertyId) && t.TryConsumeTo(val.RandomSuffixBaseAmount) &&
t.TryConsumeTo(val.RenderLevel) && t.IsEmpty() && !dummy))
return false;
+ if ((static_cast<int32>(std::numeric_limits<int16>::max()) < randomPropertyId) && (randomPropertyId <= std::numeric_limits<uint16>::max()))
+ { // this is the bug case, the id we received is actually static_cast<uint16>(i16RandomPropertyId)
+ randomPropertyId = static_cast<int16>(randomPropertyId);
+ val.IsBuggedInspectLink = true;
+ }
+
if (randomPropertyId < 0)
{
if (!val.Item->RandomSuffix)
return false;
+ if (randomPropertyId < -static_cast<int32>(sItemRandomSuffixStore.GetNumRows()))
+ return false;
if (ItemRandomSuffixEntry const* suffixEntry = sItemRandomSuffixStore.LookupEntry(-randomPropertyId))
{
val.RandomSuffix = suffixEntry;
@@ -150,7 +165,7 @@ bool Trinity::Hyperlinks::LinkTags::item::StoreTo(ItemLinkData& val, std::string
val.RandomProperty = nullptr;
}
- if ((val.RandomSuffix && !val.PropertySeed) || (val.PropertySeed && !val.RandomSuffix))
+ if ((val.RandomSuffix && !val.RandomSuffixBaseAmount) || (val.RandomSuffixBaseAmount && !val.RandomSuffix))
return false;
return true;
diff --git a/src/server/game/Chat/Hyperlinks.cpp b/src/server/game/Chat/Hyperlinks.cpp
index 3ed3c478077..9df1c21643c 100644
--- a/src/server/game/Chat/Hyperlinks.cpp
+++ b/src/server/game/Chat/Hyperlinks.cpp
@@ -138,6 +138,9 @@ struct LinkValidator<LinkTags::item>
else if (data.RandomSuffix)
randomSuffixes = &data.RandomSuffix->Name;
+ if (data.IsBuggedInspectLink) /* DBC lookup will have failed on the client, so the link should've arrived without suffix */
+ randomSuffixes = nullptr;
+
for (uint8 i = 0; i < TOTAL_LOCALES; ++i)
{
if (!locale && i != DEFAULT_LOCALE)
diff --git a/src/server/game/Chat/Hyperlinks.h b/src/server/game/Chat/Hyperlinks.h
index 773576ce4ec..008aec24fde 100644
--- a/src/server/game/Chat/Hyperlinks.h
+++ b/src/server/game/Chat/Hyperlinks.h
@@ -63,8 +63,9 @@ namespace Trinity::Hyperlinks
std::array<uint32, 3> GemEnchantId;
ItemRandomPropertiesEntry const* RandomProperty;
ItemRandomSuffixEntry const* RandomSuffix;
- uint32 PropertySeed;
+ uint32 RandomSuffixBaseAmount; /* ITEM_FIELD_PROPERTY_SEED - only nonzero for RandomSuffix items, AllocationPct from DBC are multiplied with this, then floored, to get stat value */
uint8 RenderLevel;
+ bool IsBuggedInspectLink;
};
struct QuestLinkData