← Zurück zu Cases
2023 · 6 Wochen · Core Contributor
Open Source / PostgreSQL
PostgresOpen SourceC
// problem
Problem
UTF-16-Surrogate-Paare wurden in bestimmten Locales nicht korrekt verglichen. Das führte zu falschen Sortierreihenfolgen in japanischen und koreanischen Texten. Vier Enterprise-Kunden mit je >1M Zeilen betroffen.
// approach
Approach
Root-Cause-Analyse im PostgreSQL-C-Codebase. Der Bug lag in pg_collate.c — die Surrogate-Range-Detection fehlte komplett. Entwicklung eines Patches mit umfassender Test-Suite. Review über pgsql-hackers Mailingliste mit 3 Iterations-Runden.
// code
pg_collate.c — Diff
static int
pg_strncoll_utf8(const char *s1, size_t len1,
const char *s2, size_t len2,
pg_locale_t locale)
{
/*
* Handle UTF-16 surrogate pairs correctly.
* Previously, surrogates in the range
* U+D800..U+DFFF were compared byte-by-byte,
* producing incorrect sort orders.
*/
const char *p1 = s1;
const char *p2 = s2;
while (p1 < s1 + len1 && p2 < s2 + len2)
{
if (IS_UTF16_SURROGATE_FIRST(*p1) &&
IS_UTF16_SURROGATE_SECOND(*(p1+1)))
{
/* Compare full surrogate pair */
int result = compare_surrogate_pair(
p1, p2);
if (result != 0)
return result;
p1 += 2; p2 += 2;
continue;
}
p1++; p2++;
}
return ucol_strcollUTF8(locale->ucol,
s1, len1, s2, len2,
&status);
} // outcome
Ergebnis
✓
Patch in PostgreSQL 16.2 gemerged
✓
4 Production-Incidents bei Enterprise-Kunden behoben
✓
Test-Coverage für UTF-16-Surrogate-Vergleiche ergänzt
✓
PostgreSQL Core Contributor Status erhalten