Skip to content

Scrub invalid UTF-8 byte sequences from every string/text column - #1663

Open
MattBudz wants to merge 1 commit into
developfrom
content/scrub-invalid-utf8-via-attribute-type
Open

Scrub invalid UTF-8 byte sequences from every string/text column#1663
MattBudz wants to merge 1 commit into
developfrom
content/scrub-invalid-utf8-via-attribute-type

Conversation

@MattBudz

Copy link
Copy Markdown
Contributor

Summary

Notes, Cards, Nodes, and Evidence can pick up invalid UTF-8 byte sequences from pasted or imported content. Until now this only failed as an unhandled ArgumentError in whichever request happened to trip over it first, since validations end up calling String#length on invalid bytes.

This scrubs at the type-casting layer. ActiveRecord::Type::String and ActiveRecord::Type::Text both inherit from ActiveModel::Type::String, so prepending the scrub onto that shared base type covers every :string and :text column, on every model, without per-model registration.

This also has to work identically on CE (SQLite) and Pro (MySQL). MySQL can be configured to reject invalid UTF-8 at the DB layer, but SQLite has no charset enforcement at all, so DB-level rejection can't be the shared fix across editions. Scrubbing before the value ever reaches the DB is.

Check List

  • Added a CHANGELOG entry
  • Commit message has a detailed description of what changed and why.

Content can contain invalid UTF-8 byte sequences. MySQL can be
configured to reject these at the DB layer, but CE runs on SQLite,
which has no charset enforcement at all, so DB-level rejection can't
be the shared fix across editions. Scrub instead, so an unscrubbed
value never reaches the DB and never raises an unhandled ArgumentError
later, wherever it happens to be read first rather than where it was
written.

A per-model callback or opt-in list only protects the columns someone
remembered to register it on. ActiveRecord::Type::String and
ActiveRecord::Type::Text both inherit from ActiveModel::Type::String,
so prepending the scrub onto that shared base type covers every
:string and :text column, on every model and every adapter, with a
single registration.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant