fix(core): Changes invalid gump response to write to network errors. (#510)

This commit is contained in:
Kamron Batman 2021-02-15 08:31:53 -08:00 committed by GitHub
parent 8006fa20df
commit 6f5312cb89
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 98 additions and 8 deletions

View file

@ -0,0 +1,42 @@
/*************************************************************************
* ModernUO *
* Copyright (C) 2019-2021 - ModernUO Development Team *
* Email: hi@modernuo.com *
* File: ExceptionExtensions.cs *
* *
* This program is free software: you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation, either version 3 of the License, or *
* (at your option) any later version. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program. If not, see <http://www.gnu.org/licenses/>. *
*************************************************************************/
using System;
using System.Diagnostics;
using System.Linq.Expressions;
using System.Reflection;
namespace Server.Exceptions
{
public static class ExceptionExtensions
{
public static Exception SetStackTrace(this Exception target, StackTrace stack) => _setStackTrace(target, stack);
private static readonly Func<Exception, StackTrace, Exception> _setStackTrace = _createStackTraceMethod();
private static Func<Exception, StackTrace, Exception> _createStackTraceMethod()
{
ParameterExpression target = Expression.Parameter(typeof(Exception));
ParameterExpression stack = Expression.Parameter(typeof(StackTrace));
Type traceFormatType = typeof(StackTrace).GetNestedType("TraceFormat", BindingFlags.NonPublic);
MethodInfo toString = typeof(StackTrace).GetMethod("ToString", BindingFlags.NonPublic | BindingFlags.Instance, null, new[] { traceFormatType }, null);
object normalTraceFormat = Enum.GetValues(traceFormatType!).GetValue(0);
MethodCallExpression stackTraceString = Expression.Call(stack, toString!, Expression.Constant(normalTraceFormat, traceFormatType));
FieldInfo stackTraceStringField = typeof(Exception).GetField("_stackTraceString", BindingFlags.NonPublic | BindingFlags.Instance);
BinaryExpression assign = Expression.Assign(Expression.Field(target, stackTraceStringField!), stackTraceString);
return Expression.Lambda<Func<Exception, StackTrace, Exception>>(Expression.Block(assign, target), target, stack).Compile();
}
}
}

View file

@ -0,0 +1,26 @@
/*************************************************************************
* ModernUO *
* Copyright (C) 2019-2021 - ModernUO Development Team *
* Email: hi@modernuo.com *
* File: InvalidGumpResponseException.cs *
* *
* This program is free software: you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation, either version 3 of the License, or *
* (at your option) any later version. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program. If not, see <http://www.gnu.org/licenses/>. *
*************************************************************************/
using System;
namespace Server.Gumps
{
public class InvalidGumpResponseException : Exception
{
public InvalidGumpResponseException(string reason) : base(reason)
{
}
}
}

View file

@ -13,8 +13,10 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>. *
*************************************************************************/
using System.Diagnostics;
using Microsoft.Toolkit.HighPerformance.Extensions;
using Server.Diagnostics;
using Server.Exceptions;
using Server.Gumps;
namespace Server.Network
@ -372,7 +374,12 @@ namespace Server.Network
if (!buttonExists)
{
state.WriteConsole("Invalid gump response, disconnecting...");
state.Disconnect("Invalid gump response.");
var exception = new InvalidGumpResponseException($"Button {buttonID} doesn't exist");
exception.SetStackTrace(new StackTrace());
NetState.TraceException(exception);
state.Mobile?.SendMessage("Invalid gump response.");
// state.Disconnect("Invalid gump response.");
return;
}
@ -381,15 +388,20 @@ namespace Server.Network
if (switchCount < 0 || switchCount > gump.m_Switches)
{
state.WriteConsole("Invalid gump response, disconnecting...");
state.Disconnect("Invalid gump response.");
var exception = new InvalidGumpResponseException($"Bad switch count {switchCount}");
exception.SetStackTrace(new StackTrace());
NetState.TraceException(exception);
state.Mobile?.SendMessage("Invalid gump response.");
// state.Disconnect("Invalid gump response.");
return;
}
var switches = new int[switchCount];
for (var j = 0; j < switches.Length; ++j)
for (var i = 0; i < switches.Length; ++i)
{
switches[j] = reader.ReadInt32();
switches[i] = reader.ReadInt32();
}
var textCount = reader.ReadInt32();
@ -397,13 +409,18 @@ namespace Server.Network
if (textCount < 0 || textCount > gump.m_TextEntries)
{
state.WriteConsole("Invalid gump response, disconnecting...");
state.Disconnect("Invalid gump response.");
var exception = new InvalidGumpResponseException($"Bad text entry count {textCount}");
exception.SetStackTrace(new StackTrace());
NetState.TraceException(exception);
state.Mobile?.SendMessage("Invalid gump response.");
// state.Disconnect("Invalid gump response.");
return;
}
var textEntries = new TextRelay[textCount];
for (var j = 0; j < textEntries.Length; ++j)
for (var i = 0; i < textEntries.Length; ++i)
{
int entryID = reader.ReadUInt16();
int textLength = reader.ReadUInt16();
@ -411,12 +428,17 @@ namespace Server.Network
if (textLength > 239)
{
state.WriteConsole("Invalid gump response, disconnecting...");
state.Disconnect("Invalid gump response.");
var exception = new InvalidGumpResponseException($"Text entry {i} is too long ({textLength})");
exception.SetStackTrace(new StackTrace());
NetState.TraceException(exception);
state.Mobile?.SendMessage("Invalid gump response.");
// state.Disconnect("Invalid gump response.");
return;
}
var text = reader.ReadBigUniSafe(textLength);
textEntries[j] = new TextRelay(entryID, text);
textEntries[i] = new TextRelay(entryID, text);
}
state.RemoveGump(gump);