Запрос с кириллицей падал с 500, хотя тесты на английском проходили
Сервис принимал имя пользователя через @RequestParam, валидировал длину и сохранял в базу. На стейдже с тестовыми данными на латинице всё работало. На проде первые же запросы с именами на кириллице стали падать с 500 без внятной причины в логе.
Проблема была в валидации — регулярка на длину строки считала не символы, а байты UTF-8 после неявного преобразования в byte[] где-то в цепочке фильтров. Кириллица в UTF-8 — два байта на символ, значит строка в 20 символов превращалась в 40 байт и упиралась в лимит, рассчитанный под латиницу.
Починили заменой байтового лимита на String.codePointCount() — считает символы, а не байты, и корректно работает с суррогатными парами, которых кириллица не использует, но эмодзи в будущем использовали бы.
int length = username.codePointCount( 0, username.length() );
if (length > MAX_LENGTH) { throw new ValidationException( "Name too long" ); }
На ревью спросили: а что будет, если в строке есть эмодзи с ZWJ-последовательностью — несколько code point визуально выглядят одним символом. codePointCount их всё равно посчитает отдельно, то есть смайлик из трёх code point даст длину 3, а не 1. Для лимита на UI это может быть неточно, но для защиты от переполнения буфера — достаточно.
Тесты на латинице не ловят баги кодировки — проверяйте граничные случаи на реальном алфавите продакшена.
Тренажёр: 907 вопросов, мок с таймером, план повторов
senior·base — что спрашивают на самом деле
В этом посте были ссылки, но мы их удалили по правилам Сетки