src: Yearly copyright bump This time on time!
common: Make regular expressions Unicode-aware Without the UseUnicodePropertiesOption flag, Qt's regular expressions do not include extra-ASCII codepoints when matching character classes. This results in \W (used by the highlight logic to prevent matching against substrings) matching against letters with diacritics, meaning the words 'Västra' and 'TÜV' would both count as a highlight for the nick V. Add unit tests to verify this functionality is correct in Quassel and any projects that implement ExpressionMatch. Co-authored-by: V <v@anomalous.eu>
ircv3: Add support for weird tag names, per the spec IRCv3 currently does not specify (or recommend specifying) any tag names which would contain multiple slashes, but IRCv3 does recommend clients should gracefully handle any possible tag, ideally treating it as opaque string. We’d like to avoid that, but also want to ensure even after a roundtrip through our core, tags we don’t support are still in identical condition.
common: Disable enum type stream operators for Qt >= 5.14 Starting from version 5.14, Qt provides stream operators for enum types, which collide with the ones we ship in types.h. Disable Quassel's stream operators when compiling against Qt 5.14 or later. Add a unit test that ensures that enum serialization honors the width of the underlying type.
Simplify the time formatting used in formatDateTimeToISO - Previously, a convoluted workaround using deprecated functionality was used to ensure we would format all types of QDateTime objects correctly - A new workaround has been found which ensures this works reliably without using deprecated functionality
tests: Verify ExpressionMatch test data won't OOB Verify that the ExpressionMatch test data for test trimMultiWildcardWhitespace won't try to access out of bounds data by changing EXPECT to ASSERT for patternPair.size() == 2. If the test data is wrong, the results will be undefined, so there's no point in continuing the test. Alternative: use std::vector's .at() function, which will raise a runtime error if out of bounds.
tests: Verify ExpressionMatch with invalid regex Verify that ExpressionMatch behaves reasonably with an invalid regular expression passed in, rejecting all matches and being labeled as not valid. This matches the test devised by justJanne in the process of resolving a crash in Quasseldroid-NG. We should make sure Quassel desktop never regresses into crashing, too. See https://git.kuschku.de/justJanne/QuasselDroid-ng/commit/f1f320782cb0bca3fb7974e7688ce33af19456cf
funchelpers: Support the invocation of non-void callables Let invokeWithArgsList() handle and return the return value of non-void callables wrapped in a QVariant. To avoid special-casing, the invocation of a void callable also returns a (default-constructed, thus invalid) QVariant. To indicate failure, wrap the QVariant in a boost::optional that is empty if the callable could not be invoked.
tests: Extend SignalProxyTest to cover request/receive method pairs When sending an RPC request (using REQUEST()), if the request method on the server side returns a value, a corresponding receive method is called on the client side. Extend the test case to cover this, so we can safely refactor relevant parts of SignalProxy in the future.
sigproxy: Modernize RPC calls (remote signals) The previous implementation relied on undocumented Qt internals to transform signals into RpcCall messages. It also relied on the old-style, slow signal/slot connections and required RPC call receivers to be actual slots, a feature deprecated in Qt. Reimplement this feature to make use of PMF connections. Utilize C++14 features such as variadic lambdas and templates to shift most of the work to compile time, which is not only more efficient, but also gives us compile-time checks for most things. Arguments are now marshalled to and from QVariant using the methods intended for the purpose, rather than reinterpreting void pointers into raw memory (which mimicked the way Qt works internally, but is of course fully unsupported, even though it miraculously worked basically unchanged since the early days of Qt 4...). The marshalling code is generated at compile time, which is more efficient than the previous approach of looking up types and constructing arguments at runtime. SignalProxy::attachSignal() now expects the signal to be given as a member function pointer. SignalProxy::attachSlot() supports member function pointers as well as functors, similar to QObject::connect(). Remove SignalRelay and related methods that are no longer needed. While we're at it, rename RpcCall's slotName attribute to signalName, which better reflects reality. The reimplementation does not affect the protocol; the serialization format remains unchanged.
sigproxy: Actually rename SyncableObjects when requested Until now, renaming a SyncableObject would properly update the maps in SignalProxy, but it would not actually update the objectName property on the client side. Fix this. Remove the renameObject() method in SyncableObject in favor of using setObjectName() and listening to the notifier signal emitted by Qt for triggering the update. This ensures that the actual object name and the expected one stay in sync. Also change places where we unnecessarily rename right after construction to use the appropriate constructor instead. Extend the test case to cover the renaming of SyncableObject.
funchelpers: Add a way to invoke a callable with a list of arguments In various places, we serialize function arguments as a QVariantList, and later use QMetaMethod and friends to call a slot with that list. In order to avoid this kind of runtime method lookup, we need a way to directly invoke a given callable (e.g. a function pointer) with a list of serialized arguments. We'll also want to use the type-based conversion functionality of QVariant instead of using undocumented methods and reinterpret_cast'ing raw memory, as is currently the case. Provide a method invokeWithArgsList() that takes any callable and a list of arguments serialized in a QVariantList, performs some runtime sanity checks (argument count and types), and invokes the callable with the arguments converted to the correct type, if possible. Also add a test case for this function.
tests: Add unit test for basic SignalProxy functionality Add unit test cases for attached signals as well as syncable objects. These test cases don't check for error behavior (yet); they mostly are intended for ensuring that the upcoming refactoring of the SignalProxy does not affect the format on the wire. As such, the test cases mostly focus on the protocol messages sent by invoking SignalProxy and SyncableObject functionality.