Allow modification of which types of links are shown

There's a callback to add data at the end of the Links portlet, but
nothing to allow you to change what's display.  This provides a callback
that would let you remove (for example) the Parents from the listing, so
that you can list them in a separate portlet later, with a custom
display.
add an overdue class to Due dates in ticket lists

This treats Due the same as DueRelative in ticket lists.
add overdue class only if ticket status is active

This makes Due on ticket display consistent with ticket lists (collections).
Don't create empty LinkValueTo/IncludeContentForValue attributes

dec257a fixed RT::CustomField->Create() to accept LinkValueTo and
IncludeContentForValue, which are stored in attributes.  However, it
also ensured that those attributes are created even if they're empty.
This means every CF in the system, regardless of if it uses them, adds
two attributes.

Adjust _URLTemplate to remove attributes that are now empty, and more
explicitly return undef when the attribute does not exist.

Fixes: #22191
Merge branch '4.2/limit-link-display' into 4.2-trunk
Merge branch '4.2/overdue-class' into 4.2-trunk
add %AdminSearchResultRows config option

This adds a row limit to the Classes and Templates list for the first time.

It also changes the row limit for Groups and Users lists from 100 to 50.

The rows limit for the Membership page for Groups and Users is changed from
20 to 50. This e.g. helps adding groups to users as it avoids jumping through
pages if you have many groups.
Modernize and condense t/mail/sendmail.t and t/mail/sendmail-plaintext.t

t/data/emails/text-html-in-russian was removed because the original
purpose of the test was removed in 46fd04d9, after 90f9c190 stopped
attaching text/html incoming mail to autoreplies.
Always log bytes, not characters

Ensure that we always send UTF-8 encoded bytes to loggers, and not wide
characters.  This is correctly done via an explicit call to
Encode::encode, and not via checks of utf8::is_utf8 (which may be false
for character strings with codepoints > 127 but < 256), and not via
_utf8_off (which would fail similarly for such characters).
The alluded-to deficiency is not a concern in perl ≥ 5.8.3

The comment and code were added in RT 2.1.38, which only required perl
5.6.1; the perl version was increased to 5.8.3 to cover a large number
of encoding bugs, such as the one this comment was likely alluding to.
Ensure all MIME::Entity bodies are UTF-8 encoded bytes

Placing wide characters into MIME::Entity objects can lead to
double-encoding.  Always treat them as byte stores, encoding as UTF-8
and noting their character set.

In the case of Approvals/index.html, there was no need for an explicit
MIME::Entity object; ->Correspond creates one as needed from a "Content"
argument.
Ensure all MIME::Entity headers are UTF-8 encoded bytes

Placing wide characters into MIME::Entity objects can lead to
double-encoding, as discovered most recently in d469cacc.  Explicitly
decode all headers as UTF-8 when retrieving them with ->get(), and
encode them as UTF-8 before updating them with ->set() or ->replace().
This also applies to headers passed to ->build().  The only exceptions
to this are fixed strings in the source (which, in the absence of "use
utf8", are always bytes).

While the majority of these headers will never have wide characters in
them, always decoding and encoding ensures the proper disipline to
guarantee that strings with the "UTF8" flag do not get placed in a
header, which can cause double-encoding.
Make RT::Action::SendEmail->SetHeader take characters, not bytes

This helper method is used in a number of places in
RT::Action::SendEmail, often without remembering that it should be
passed bytes, not characters.  Change it to always take characters, and
modify the two callsite which (correctly) passed it bytes to no longer
do so.
Add a utility method to check that an input is bytes

Note that it is impossible to verify that an input is characters; here,
we can only validate if it _could_ be bytes.

First, any string with the "UTF8" flag off cannot contain codepoints
above 255, and as such is safe.  Additionally, if the "UTF8" flag is on,
having no codepoints above 127 means the bytes are unambigious.  Having
codepoints above 255 is guaranteedly a sign that the input is not a byte
string.

This leaves only the case of a string with the "UTF8" flag on, and
codepoints above 127 but below 255.  The "UTF8" flag is a sign that they
were _likely_ touched by character data at some point.  In such cases we
warn, suggesting that the bytes have the "UTF8" flag disabled by means
of utf8::downgrade, if they are indeed bytes.
Verify that MIME::Entity bodies are bytes, and remove _utf8_off call

Use the newly-added RT::Util::assert_bytes function to verify that the
body is indeed bytes, and not characters.

We also remove the _utf8_off call -- because, contrary to what the
comment implies, the presence or absence of the "UTF8" flag does _not_
determine if a string is "encoded as octets and not as characters"; it
merely states that the string is capable of holding codepoints > 255.
If it happens to not contain any, the _utf8_off does nothing.  If it
does, it effectively encodes all codepoints > 127 in UTF-8.

Given the premise that the string contains bytes in some (probably
non-UTF-8) encoding, re-encoding some bytes of it as UTF-8 cannot
possibly produce valid output.  The flaw in this situation cannot be
fixed by a simple _utf8_off, but instead must be fixed by ensuring that
the body always contains bytes, not wide characters -- as it now does,
thanks to the prior commits.  The call to RT::Util::assert_bytes serves
as an additional safeguard against backsliding on that assumption.
Verify that MIME::Entity headers are bytes, and remove _utf8_off call

See the prior commit for reasoning, which applies just as much to the
header as the body.
Standardize on the stricter Encode::encode("UTF-8", ...) everywhere

This is not only for code consistency, but also for consistency of
output.  Encode::encode_utf8(...) is equivalent to
Encode::encode("utf8",...) which is the non-"strict" form of UTF-8.
Strict UTF-8 encoding differs in that (from `perldoc Encode`):

    ...its range is much narrower (0 ..  0x10_FFFF to cover only 21 bits
    instead of 32 or 64 bits) and some sequences are not allowed, like
    those used in surrogate pairs, the 31 non-character code points
    0xFDD0 .. 0xFDEF, the last two code points in any plane (0xXX_FFFE
    and 0xXX_FFFF), all non-shortest encodings, etc.

RT deals with interchange with databases, email, and other systems.  In
dealing with encodings, it should ensure that it does not produce byte
sequences that are invalid according to official Unicode standards.
Remove "use utf8" from RT::I18N::fr, making NBSP explicit

"use utf8" causes the sourcecode (including all strings) to be
interpreted by perl as characters encoded in UTF-8, not bytes.  In
lib/RT/I18N/fr.pm, this was being used to substitude codepoint 160
(NO-BREAK SPACE, U+00A0) for commas.  The fact that the space character
was not 0x20, but rather 0xA0, was mostly hidden by use of "use utf8".

Remove the "use utf8" and make the replacement character clear.
Remove remaining cases of "use utf8"

All remaining cases of "use utf8" lie in the testsuite.  As "use utf8"
changes the semantics of dealing with Unicode strings, remove it to
allow programmers to always assume that literals are interpreted as
bytestrings, not characters.  To do otherwise means that one must always
ask if "use utf8" is in scope before performing operations on any
literals; instead, simply make the encodings and decodings explicit.

Note that wide characters may appear in editors, and that the encoding
of the characters on _disk_ will always be UTF-8.  The removal of "use
utf8" merely means that perl will generate a two-byte string from "é",
and not a one-character string.
Dashboard: decode bytes in query parameters into characters

The dashboard mailer code replicates many of the original steps of Mason
parameter parsing -- but omitted the important step of decoding the
bytes once they had been un-URI-encoded.