mudlet/test/TEntityResolverTest.cpp

Ignoring revisions in .git-blame-ignore-revs. Click here to bypass and see the normal blame view.

151 lines
4.4 KiB
C++
Raw Permalink Normal View History

Refactoring/reimplementation of MXP support (#3625) Refactoring/reimplementation of MXP protocol Extracts MXP support from TBuffer Separates input parsing from protocol processing: input is parsed into MxpTag objects by the MxpNodeBuilder and are passed to be handled by the MxpTagProcessor Class hierarchy of MxpTagHandler for implementing support for each tag: allows for a clear separation of the implementation of each tag and makes it easier for adding support for new tags Defines a clear interface (MxpClient) separating the MXP implementation from other parts of the code Solves some limitations of previous implementation such as supporting element definitions not only for<SEND> tags, interpolating named and positional attributes and interpolating &text; placeholder by tag content Includes support for COLOR tag Handles FONT, U, I, B, VAR and !ENTITY tags, but so far no defined behavior (can be implemented in MxpMudlet) Attributes that hold MXP state are now in the Host class to avoid needless copies when TBuffer is copied around Introduces QtTests for some of the classes Other refactorings intended to simplify TBuffer class, extracting responbilities that aren't directly related to the buffer mgmt Extracted TEncodingTable from TBuffer, this class is responsible for mapping encoding names to tables. It also removes some bloat from TBuffer. TLinkStore to manage links and associated hints to be displayed. TEntityResolver to map character entities, such as &gt; &#32; &#x20; to their associated string values; supports interpolating strings replacing the entity placeholders by their values
2020-05-03 14:09:42 -03:00
#include <QMap>
#include <TEntityResolver.h>
#include <QtTest/QtTest>
#include "utils.h"
Refactoring/reimplementation of MXP support (#3625) Refactoring/reimplementation of MXP protocol Extracts MXP support from TBuffer Separates input parsing from protocol processing: input is parsed into MxpTag objects by the MxpNodeBuilder and are passed to be handled by the MxpTagProcessor Class hierarchy of MxpTagHandler for implementing support for each tag: allows for a clear separation of the implementation of each tag and makes it easier for adding support for new tags Defines a clear interface (MxpClient) separating the MXP implementation from other parts of the code Solves some limitations of previous implementation such as supporting element definitions not only for<SEND> tags, interpolating named and positional attributes and interpolating &text; placeholder by tag content Includes support for COLOR tag Handles FONT, U, I, B, VAR and !ENTITY tags, but so far no defined behavior (can be implemented in MxpMudlet) Attributes that hold MXP state are now in the Host class to avoid needless copies when TBuffer is copied around Introduces QtTests for some of the classes Other refactorings intended to simplify TBuffer class, extracting responbilities that aren't directly related to the buffer mgmt Extracted TEncodingTable from TBuffer, this class is responsible for mapping encoding names to tables. It also removes some bloat from TBuffer. TLinkStore to manage links and associated hints to be displayed. TEntityResolver to map character entities, such as &gt; &#32; &#x20; to their associated string values; supports interpolating strings replacing the entity placeholders by their values
2020-05-03 14:09:42 -03:00
class TEntityResolverTest : public QObject {
Q_OBJECT
private:
private slots:
void initTestCase()
{
}
void testStandardEntities()
{
TEntityResolver resolver;
QCOMPARE(resolver.getResolution("&nbsp;"), " ");
QCOMPARE(resolver.getResolution("&gt;"), ">");
QCOMPARE(resolver.getResolution("&lt;"), "<");
QCOMPARE(resolver.getResolution("&amp;"), "&");
QCOMPARE(resolver.getResolution("&quot;"), "\"");
QCOMPARE(resolver.getResolution("&Uacute;"), "Ú");
QCOMPARE(resolver.getResolution("&uacute;"), "ú");
Refactoring/reimplementation of MXP support (#3625) Refactoring/reimplementation of MXP protocol Extracts MXP support from TBuffer Separates input parsing from protocol processing: input is parsed into MxpTag objects by the MxpNodeBuilder and are passed to be handled by the MxpTagProcessor Class hierarchy of MxpTagHandler for implementing support for each tag: allows for a clear separation of the implementation of each tag and makes it easier for adding support for new tags Defines a clear interface (MxpClient) separating the MXP implementation from other parts of the code Solves some limitations of previous implementation such as supporting element definitions not only for<SEND> tags, interpolating named and positional attributes and interpolating &text; placeholder by tag content Includes support for COLOR tag Handles FONT, U, I, B, VAR and !ENTITY tags, but so far no defined behavior (can be implemented in MxpMudlet) Attributes that hold MXP state are now in the Host class to avoid needless copies when TBuffer is copied around Introduces QtTests for some of the classes Other refactorings intended to simplify TBuffer class, extracting responbilities that aren't directly related to the buffer mgmt Extracted TEncodingTable from TBuffer, this class is responsible for mapping encoding names to tables. It also removes some bloat from TBuffer. TLinkStore to manage links and associated hints to be displayed. TEntityResolver to map character entities, such as &gt; &#32; &#x20; to their associated string values; supports interpolating strings replacing the entity placeholders by their values
2020-05-03 14:09:42 -03:00
}
void testStandardEntitiesCaseInsensitive()
{
TEntityResolver resolver;
TEntityType type;
Refactoring/reimplementation of MXP support (#3625) Refactoring/reimplementation of MXP protocol Extracts MXP support from TBuffer Separates input parsing from protocol processing: input is parsed into MxpTag objects by the MxpNodeBuilder and are passed to be handled by the MxpTagProcessor Class hierarchy of MxpTagHandler for implementing support for each tag: allows for a clear separation of the implementation of each tag and makes it easier for adding support for new tags Defines a clear interface (MxpClient) separating the MXP implementation from other parts of the code Solves some limitations of previous implementation such as supporting element definitions not only for<SEND> tags, interpolating named and positional attributes and interpolating &text; placeholder by tag content Includes support for COLOR tag Handles FONT, U, I, B, VAR and !ENTITY tags, but so far no defined behavior (can be implemented in MxpMudlet) Attributes that hold MXP state are now in the Host class to avoid needless copies when TBuffer is copied around Introduces QtTests for some of the classes Other refactorings intended to simplify TBuffer class, extracting responbilities that aren't directly related to the buffer mgmt Extracted TEncodingTable from TBuffer, this class is responsible for mapping encoding names to tables. It also removes some bloat from TBuffer. TLinkStore to manage links and associated hints to be displayed. TEntityResolver to map character entities, such as &gt; &#32; &#x20; to their associated string values; supports interpolating strings replacing the entity placeholders by their values
2020-05-03 14:09:42 -03:00
QCOMPARE(resolver.getResolution("&GT;"), ">");
QCOMPARE(resolver.getResolution("&Lt;"), "<");
QCOMPARE(resolver.getResolution("&AmP;"), "&");
QCOMPARE(resolver.getResolution("&QUOT;"), "\"");
QCOMPARE(resolver.getResolution("&Copy;", true, &type), "©");
QCOMPARE(type, ENTITY_TYPE_SYSTEM);
Refactoring/reimplementation of MXP support (#3625) Refactoring/reimplementation of MXP protocol Extracts MXP support from TBuffer Separates input parsing from protocol processing: input is parsed into MxpTag objects by the MxpNodeBuilder and are passed to be handled by the MxpTagProcessor Class hierarchy of MxpTagHandler for implementing support for each tag: allows for a clear separation of the implementation of each tag and makes it easier for adding support for new tags Defines a clear interface (MxpClient) separating the MXP implementation from other parts of the code Solves some limitations of previous implementation such as supporting element definitions not only for<SEND> tags, interpolating named and positional attributes and interpolating &text; placeholder by tag content Includes support for COLOR tag Handles FONT, U, I, B, VAR and !ENTITY tags, but so far no defined behavior (can be implemented in MxpMudlet) Attributes that hold MXP state are now in the Host class to avoid needless copies when TBuffer is copied around Introduces QtTests for some of the classes Other refactorings intended to simplify TBuffer class, extracting responbilities that aren't directly related to the buffer mgmt Extracted TEncodingTable from TBuffer, this class is responsible for mapping encoding names to tables. It also removes some bloat from TBuffer. TLinkStore to manage links and associated hints to be displayed. TEntityResolver to map character entities, such as &gt; &#32; &#x20; to their associated string values; supports interpolating strings replacing the entity placeholders by their values
2020-05-03 14:09:42 -03:00
}
void testDecimalCode()
{
TEntityResolver resolver;
QCOMPARE(resolver.getResolution("&#10;"), "\n");
QCOMPARE(resolver.getResolution("&#37;"), "%");
QCOMPARE(resolver.getResolution("&#32;"), " ");
}
void testHexCode()
{
TEntityResolver resolver;
QCOMPARE(resolver.getResolution("&#x20;"), " ");
QCOMPARE(resolver.getResolution("&#x26;"), "&");
QCOMPARE(resolver.getResolution("&#x2B;"), "+");
}
fix: stop a malicious game from writing files outside the media folder (#9504) #### Brief overview of PR changes/additions - Reject MSP/GMCP media file names containing `..` that resolve outside the profile's media directory (relative sub-directories and wildcards still work). - Guard `TEntityResolver::resolveCode()` against the empty value from a malformed numeric entity like `&#;`, which previously called `QString::front()` on an empty string (undefined behaviour). - Add a `TEntityResolver` regression test for the malformed-entity case. #### Motivation for adding to Mudlet A connected game server could use a crafted MSP `!!SOUND`/`!!MUSIC` or GMCP `Client.Media` file name to download and write attacker-controlled content to an arbitrary path (e.g. an autostart entry), or read/play an arbitrary local file — with no user interaction, since both protocols are enabled by default. #### Other info (issues closed, discussion etc) Security hardening of the server-facing media path. `isFileRelative()` only rejected absolute paths, so a relative `..` traversal passed validation before being concatenated onto the media directory. **Test case:** Connect a profile to a server that sends `!!SOUND(../../evil.wav U=http://example/evil.wav)` — it is now rejected with a `WARNING - rejected a media file name that escapes the profile media directory` log line, while a normal `!!SOUND(hit.wav U=...)` still downloads and plays. --- _Generated by [Claude Code](https://claude.ai/code/session_011XUZefuDuy8F1M4bHq5jMZ)_ --------- Signed-off-by: Vadim Peretokin <vperetokin@hey.com> Co-authored-by: Claude <noreply@anthropic.com>
2026-07-25 17:23:31 +02:00
void testMalformedNumericEntity()
{
TEntityResolver resolver;
// A numeric entity with no digits ("&#;") leaves an empty value that was
// previously passed to QString::front() (undefined behaviour). It must
// now resolve safely rather than crash/assert.
QCOMPARE(resolver.getResolution("&#;"), "");
QCOMPARE(resolver.getResolution("&#x;"), "");
}
Refactoring/reimplementation of MXP support (#3625) Refactoring/reimplementation of MXP protocol Extracts MXP support from TBuffer Separates input parsing from protocol processing: input is parsed into MxpTag objects by the MxpNodeBuilder and are passed to be handled by the MxpTagProcessor Class hierarchy of MxpTagHandler for implementing support for each tag: allows for a clear separation of the implementation of each tag and makes it easier for adding support for new tags Defines a clear interface (MxpClient) separating the MXP implementation from other parts of the code Solves some limitations of previous implementation such as supporting element definitions not only for<SEND> tags, interpolating named and positional attributes and interpolating &text; placeholder by tag content Includes support for COLOR tag Handles FONT, U, I, B, VAR and !ENTITY tags, but so far no defined behavior (can be implemented in MxpMudlet) Attributes that hold MXP state are now in the Host class to avoid needless copies when TBuffer is copied around Introduces QtTests for some of the classes Other refactorings intended to simplify TBuffer class, extracting responbilities that aren't directly related to the buffer mgmt Extracted TEncodingTable from TBuffer, this class is responsible for mapping encoding names to tables. It also removes some bloat from TBuffer. TLinkStore to manage links and associated hints to be displayed. TEntityResolver to map character entities, such as &gt; &#32; &#x20; to their associated string values; supports interpolating strings replacing the entity placeholders by their values
2020-05-03 14:09:42 -03:00
void testRegisteredEntities()
{
TEntityResolver resolver;
TEntityType type;
Refactoring/reimplementation of MXP support (#3625) Refactoring/reimplementation of MXP protocol Extracts MXP support from TBuffer Separates input parsing from protocol processing: input is parsed into MxpTag objects by the MxpNodeBuilder and are passed to be handled by the MxpTagProcessor Class hierarchy of MxpTagHandler for implementing support for each tag: allows for a clear separation of the implementation of each tag and makes it easier for adding support for new tags Defines a clear interface (MxpClient) separating the MXP implementation from other parts of the code Solves some limitations of previous implementation such as supporting element definitions not only for<SEND> tags, interpolating named and positional attributes and interpolating &text; placeholder by tag content Includes support for COLOR tag Handles FONT, U, I, B, VAR and !ENTITY tags, but so far no defined behavior (can be implemented in MxpMudlet) Attributes that hold MXP state are now in the Host class to avoid needless copies when TBuffer is copied around Introduces QtTests for some of the classes Other refactorings intended to simplify TBuffer class, extracting responbilities that aren't directly related to the buffer mgmt Extracted TEncodingTable from TBuffer, this class is responsible for mapping encoding names to tables. It also removes some bloat from TBuffer. TLinkStore to manage links and associated hints to be displayed. TEntityResolver to map character entities, such as &gt; &#32; &#x20; to their associated string values; supports interpolating strings replacing the entity placeholders by their values
2020-05-03 14:09:42 -03:00
// Examples from MXP specification https://www.zuggsoft.com/zmud/mxp.htm#ENTITY
resolver.registerEntity("&Version;", "6.15");
resolver.registerEntity("&Start;", "<em>");
resolver.registerEntity("&End;", "</em>");
QCOMPARE(resolver.getResolution("&VERSION;"), "6.15");
QCOMPARE(resolver.getResolution("&Start;"), "<em>");
QCOMPARE(resolver.getResolution("&end;", true, &type), "</em>");
QCOMPARE(type, ENTITY_TYPE_CUSTOM);
// Check if disabling resolution of custom entities works and is properly signalled
QCOMPARE(resolver.getResolution("&end;", false, &type), "&end;");
QCOMPARE(type, ENTITY_TYPE_UNKNOWN);
Refactoring/reimplementation of MXP support (#3625) Refactoring/reimplementation of MXP protocol Extracts MXP support from TBuffer Separates input parsing from protocol processing: input is parsed into MxpTag objects by the MxpNodeBuilder and are passed to be handled by the MxpTagProcessor Class hierarchy of MxpTagHandler for implementing support for each tag: allows for a clear separation of the implementation of each tag and makes it easier for adding support for new tags Defines a clear interface (MxpClient) separating the MXP implementation from other parts of the code Solves some limitations of previous implementation such as supporting element definitions not only for<SEND> tags, interpolating named and positional attributes and interpolating &text; placeholder by tag content Includes support for COLOR tag Handles FONT, U, I, B, VAR and !ENTITY tags, but so far no defined behavior (can be implemented in MxpMudlet) Attributes that hold MXP state are now in the Host class to avoid needless copies when TBuffer is copied around Introduces QtTests for some of the classes Other refactorings intended to simplify TBuffer class, extracting responbilities that aren't directly related to the buffer mgmt Extracted TEncodingTable from TBuffer, this class is responsible for mapping encoding names to tables. It also removes some bloat from TBuffer. TLinkStore to manage links and associated hints to be displayed. TEntityResolver to map character entities, such as &gt; &#32; &#x20; to their associated string values; supports interpolating strings replacing the entity placeholders by their values
2020-05-03 14:09:42 -03:00
}
void testRegisterEntityAsChar()
{
TEntityResolver resolver;
resolver.registerEntity("&symbol;", '@');
QCOMPARE(resolver.getResolution("&symbol;"), "@");
}
void testInvalidRegister()
{
TEntityResolver resolver;
QVERIFY(!resolver.registerEntity("&symbol", '@'));
QVERIFY(!resolver.registerEntity("symbol", '@'));
QVERIFY(resolver.registerEntity("&symbol;", '@'));
}
void testResolveNonExistentEntity()
{
TEntityResolver resolver;
QCOMPARE(resolver.getResolution("&symbol;"), "&symbol;");
}
void testInterpolation()
{
TEntityResolver resolver;
QCOMPARE(resolver.interpolate("2 &lt; 4"), "2 < 4");
QCOMPARE(resolver.interpolate("2 &Lt; 4"), "2 < 4");
QCOMPARE(resolver.interpolate("You say &quot;Hello World&quot;"), "You say \"Hello World\"");
}
void testCustomInterpolation()
{
const QMap<QString, QString> attributes = {
{qsl("&name;"), qsl("drunk sailor")},
{qsl("&desc;"), qsl("A drunk sailor is lying here")}
Refactoring/reimplementation of MXP support (#3625) Refactoring/reimplementation of MXP protocol Extracts MXP support from TBuffer Separates input parsing from protocol processing: input is parsed into MxpTag objects by the MxpNodeBuilder and are passed to be handled by the MxpTagProcessor Class hierarchy of MxpTagHandler for implementing support for each tag: allows for a clear separation of the implementation of each tag and makes it easier for adding support for new tags Defines a clear interface (MxpClient) separating the MXP implementation from other parts of the code Solves some limitations of previous implementation such as supporting element definitions not only for<SEND> tags, interpolating named and positional attributes and interpolating &text; placeholder by tag content Includes support for COLOR tag Handles FONT, U, I, B, VAR and !ENTITY tags, but so far no defined behavior (can be implemented in MxpMudlet) Attributes that hold MXP state are now in the Host class to avoid needless copies when TBuffer is copied around Introduces QtTests for some of the classes Other refactorings intended to simplify TBuffer class, extracting responbilities that aren't directly related to the buffer mgmt Extracted TEncodingTable from TBuffer, this class is responsible for mapping encoding names to tables. It also removes some bloat from TBuffer. TLinkStore to manage links and associated hints to be displayed. TEntityResolver to map character entities, such as &gt; &#32; &#x20; to their associated string values; supports interpolating strings replacing the entity placeholders by their values
2020-05-03 14:09:42 -03:00
};
auto mapping = [attributes](auto& attr) {
auto ptr = attributes.find(attr);
return ptr != attributes.end() ? *ptr : attr;
};
QCOMPARE(TEntityResolver::interpolate("attack &#39;&name;&#39;|look &#39;&name;&#39;", mapping), "attack &#39;drunk sailor&#39;|look &#39;drunk sailor&#39;");
QCOMPARE(TEntityResolver::interpolate("desc: '&desc;'", mapping), "desc: 'A drunk sailor is lying here'");
}
void cleanupTestCase()
{
}
};
#include "TEntityResolverTest.moc"
QTEST_MAIN(TEntityResolverTest)