forked from mumble-voip/mumble
-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
FIX(server): Stale username cache-entries due to case differences
Mumble treats usernames case-insensitively. However, in the server, there is a cache that maps usernames to IDs of registered users. We do lazy loading so when a given name is not yet in the cache, we check the database for a match and if that returns something, we insert the result into the cache. However, the DB does case-insensitive lookups whereas the cache used to be case-sensitive. Therefore, different casings of the same username could end up in the cache (all pointing to the same user ID). If that user got unregistered, only one of the possible ways of writing their name gets removed from the cache, leaving the other entries (which are now stale) untouched. This can cause problems when another user now wants to register with a name that corresponds to one of those stale cache entries. The server will think that the given username is already taken, ensuring leading to a rejection of the registration request. A server restart purges the stale entries from the cache. This commit ensures that the cache is now also operating in a case-insensitive manner such that we shouldn't ever create any duplicate entries in there in the first place. Fixes mumble-voip#6383
- Loading branch information
Showing
6 changed files
with
227 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
# Copyright 2024 The Mumble Developers. All rights reserved. | ||
# Use of this source code is governed by a BSD-style license | ||
# that can be found in the LICENSE file at the root of the | ||
# Mumble source tree or at <https://www.mumble.info/LICENSE>. | ||
|
||
add_executable(TestCaseInsensitiveQString TestCaseInsensitiveQString.cpp) | ||
|
||
set_target_properties(TestCaseInsensitiveQString PROPERTIES AUTOMOC ON) | ||
|
||
target_link_libraries(TestCaseInsensitiveQString PRIVATE shared Qt5::Test) | ||
|
||
add_test(NAME TestCaseInsensitiveQString COMMAND $<TARGET_FILE:TestCaseInsensitiveQString>) |
91 changes: 91 additions & 0 deletions
91
src/tests/TestCaseInsensitiveQString/TestCaseInsensitiveQString.cpp
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,91 @@ | ||
// Copyright 2024 The Mumble Developers. All rights reserved. | ||
// Use of this source code is governed by a BSD-style license | ||
// that can be found in the LICENSE file at the root of the | ||
// Mumble source tree or at <https://www.mumble.info/LICENSE>. | ||
|
||
#include "QtUtils.h" | ||
|
||
#include <QHash> | ||
#include <QObject> | ||
#include <QTest> | ||
|
||
using namespace Mumble::QtUtils; | ||
|
||
class TestCaseInsensitiveQString : public QObject { | ||
Q_OBJECT | ||
private slots: | ||
|
||
void equality() const { | ||
CaseInsensitiveQString istr("test"); | ||
|
||
QVERIFY(QString("Test") == istr); | ||
QVERIFY(istr == QString("TEST")); | ||
QVERIFY(istr == istr); | ||
} | ||
|
||
void inequality() const { | ||
CaseInsensitiveQString istr("test"); | ||
|
||
QVERIFY(QString("Tezt") != istr); | ||
QVERIFY(istr != QString("TETS")); | ||
QVERIFY(istr != CaseInsensitiveQString("test2")); | ||
} | ||
|
||
void less_than() const { | ||
CaseInsensitiveQString istr("test"); | ||
|
||
QVERIFY(QString("abc") < istr); | ||
QVERIFY(istr < QString("xyz")); | ||
QVERIFY(CaseInsensitiveQString("another") < istr); | ||
} | ||
|
||
void less_equal() const { | ||
CaseInsensitiveQString istr("test"); | ||
|
||
QVERIFY(QString("Abc") <= istr); | ||
QVERIFY(istr <= QString("xyz")); | ||
QVERIFY(CaseInsensitiveQString("Taxi") <= istr); | ||
|
||
QVERIFY(QString("teSt") <= istr); | ||
QVERIFY(istr <= QString("Test")); | ||
QVERIFY(CaseInsensitiveQString("TEST") <= istr); | ||
} | ||
|
||
void greater_than() const { | ||
CaseInsensitiveQString istr("test"); | ||
|
||
QVERIFY(QString("xyz") > istr); | ||
QVERIFY(istr > QString("abc")); | ||
QVERIFY(CaseInsensitiveQString("Xenia") > istr); | ||
} | ||
|
||
void greater_equal() const { | ||
CaseInsensitiveQString istr("test"); | ||
|
||
QVERIFY(QString("xyz") >= istr); | ||
QVERIFY(istr >= QString("abc")); | ||
QVERIFY(CaseInsensitiveQString("Xenia") >= istr); | ||
|
||
QVERIFY(QString("Test") >= istr); | ||
QVERIFY(istr >= QString("teST")); | ||
QVERIFY(CaseInsensitiveQString("TeSt") >= istr); | ||
} | ||
|
||
void hash() const { | ||
QVERIFY(qHash(CaseInsensitiveQString("test")) == qHash(CaseInsensitiveQString("TEST"))); | ||
QVERIFY(qHash(CaseInsensitiveQString("test")) != qHash(CaseInsensitiveQString("TESTER"))); | ||
} | ||
|
||
void use_in_qhash() const { | ||
QHash< CaseInsensitiveQString, int > hash; | ||
hash.insert(QString("TeSt"), 42); | ||
|
||
QVERIFY(hash.contains(QString("test"))); | ||
QCOMPARE(hash[QString("test")], 42); | ||
QCOMPARE(static_cast< const QString & >(hash.begin().key()), QString("TeSt")); | ||
QVERIFY(static_cast< const QString & >(hash.begin().key()) != QString("test")); | ||
} | ||
}; | ||
|
||
QTEST_MAIN(TestCaseInsensitiveQString) | ||
#include "TestCaseInsensitiveQString.moc" |