We already use our own extensive sanitization pipeline, and it turns out
tagfilter is extremely slow on large oneline input (such as big tables).
Rendering a large table inside a work package (2k rows, 20k cells) caused tagfilter to run for over 2 minutes.
Added a separate spec to test all tags the tagfilter filters for to avoid its runaway execution time.
Add fetch_request_cached method that layers RequestStore in front of Rails.cache.fetch
Used in the following places, as they are repeatedly accessed during schema initialization.
all_work_package_form_attributes, form_config_attribute_representation, Query.available_columns
In my tests, this improves cold cache access by reducing initial number of queries to access cache
Documents created with zero-width Unicode characters (e.g. U+200B)
in their titles become unclickable on the index page, making them
hard to manage or delete.
Introduce RemoveInvisibleCharacters normalizer, replacing the former
RemoveAsciiControlCharacters. It strips both ASCII control characters
and Unicode zero-width characters, with each category defined as a
named constant for clarity. Apply it to Document#title and update
existing callers (Project#identifier, CustomField#name).
Add a shared RSpec example "strips invisible characters" to verify
normalization consistently across all three models.
* Add rel=nofollow to user-generated links to deter SEO spam
Links in user-generated content (work package descriptions, comments,
wiki pages) previously carried rel="noopener noreferrer" but not
nofollow. Search engines therefore passed PageRank through them, making
OpenProject community instances attractive targets for spammers posting
links for SEO gain.
Adding nofollow removes this incentive without any visible impact on
legitimate users.
* Fix missing nofollow in AutolinkCustomProtocolsFilter
This error is intended for cases when a method is
intentionally not implemented, because the module/class defining
it expects a subclass (or class including the module) to implement
the method.
This is intended to distinguish it from other cases, such as:
* feature not implemented yet
* edge case of a method call not yet supported
Notably it avoids the misuse of the Ruby-defined NotImplementedError,
which is only intended for much more specific scenarios:
> Raised when a feature is not implemented on the current platform. For example, methods depending on the fsync or fork system calls may raise this exception [...]
Also see https://docs.ruby-lang.org/en/master/NotImplementedError.html