Author: brane
Date: Mon May 25 04:35:19 2026
New Revision: 1934576
Log:
Rename and reimplement UTF-8 string alignment functions to be aware of
grapheme boundaries, and to gracefully handle invalid UTF-8.
Also remove the expensive grapheme breaks calculator because it's not used.
* subversion/include/private/svn_utf_private.h
(svn_utf__cstring_align_right_trim_left): Update the docstring,
change the type of the width parameter and rename from
svn_utf__cstring_utf8_align_right. All references updated.
* subversion/include/private/svn_utf_private.h
(svn_utf__cstring_align_left): Update the docstring,
change the type of the width parameter and rename from
svn_utf__cstring_utf8_align_left. All references updated.
(svn_utf__utf8_grapheme_t,
svn_utf__cstring_utf8_grapheme_breaks): Remove.
* subversion/libsvn_subr/utf.c
(replacement_chars, align_substring): New helper functions.
(svn_utf__cstring_align_right_trim_left,
svn_utf__cstring_align_left): Reimplement here.
* subversion/libsvn_subr/utf8proc.c
(svn_utf__cstring_utf8_grapheme_breaks, utf8_skipn,
svn_utf__cstring_utf8_align_right,
svn_utf__cstring_utf8_align_left): Remove.
* subversion/svnbrowse/svnbrowse.c:
Update all references to renamed functions.
* subversion/tests/libsvn_subr/utf-test.c:
Update all references to renamed functions.
(test_utf8_grapheme_breaks): Remove.
(test_utf8_align): Add test cases for invalid UTF-8.
Update the expected result from the test that attempts to squeeze
a two-colums-wide emoji into one column.
(test_funcs): Remove test_utf8_grapheme_breaks.
Modified:
subversion/trunk/subversion/include/private/svn_utf_private.h
subversion/trunk/subversion/libsvn_subr/utf.c
subversion/trunk/subversion/libsvn_subr/utf8proc.c
subversion/trunk/subversion/svnbrowse/svnbrowse.c
subversion/trunk/subversion/tests/libsvn_subr/utf-test.c
Modified: subversion/trunk/subversion/include/private/svn_utf_private.h
==============================================================================
--- subversion/trunk/subversion/include/private/svn_utf_private.h Mon May
25 04:20:06 2026 (r1934575)
+++ subversion/trunk/subversion/include/private/svn_utf_private.h Mon May
25 04:35:19 2026 (r1934576)
@@ -291,35 +291,6 @@ svn_utf__utf32_to_utf8(const svn_string_
apr_pool_t *result_pool,
apr_pool_t *scratch_pool);
-/*
- * Describes one Unicode grapheme within a UTF-8 string.
- */
-typedef struct svn_utf__utf8_grapheme_t
-{
- /* The index of the beginning of the grapheme. */
- apr_size_t start;
- /* The index of the byte after the end of the grapheme. */
- apr_size_t end;
- /* The estimated visual width of the grapheme. */
- int width;
-} svn_utf__utf8_grapheme_t;
-
-/*
- * Find grapheme boundaries within a UTF-8 string CSTR. Return the total
- * estimated width of all the graphemes in the string. Set *GRAPHEMES to
- * an array of svn_utf__utf8_grapheme_t allocated from POOL. The final
- * grapheme in the returned array may not be complete; we don't check if
- * a grapheme break is allowed at the end bcause it's, well, the end.
- *
- * *GRAPHEMES will be set to NULL on return if CSTR is empty.
- *
- * If CSTR is not a valid UTF-8 string, the returned value will be -1.
- */
-apr_ssize_t
-svn_utf__cstring_utf8_grapheme_breaks(apr_array_header_t **graphemes,
- const char *cstr,
- apr_pool_t *pool);
-
/* Return the display width of the UTF-8 string CSTR, or -1 if the string is
* not valid. If LENGTH is not NULL, set *LENGTH to the byte-wise length
* of CSTR; this the same as the value returned by strlen(CSTR).
@@ -355,34 +326,39 @@ svn_utf__cstring_trim_left(const char **
const char *cstr,
apr_size_t max_width);
-/* Return a new string with a copy of @a cstr allocated in @a pool aligned to
- * the right side with spaces. This function takes UTF-8 multibyte encoding and
- * wcwidth into an account. The new string will be have exacly as much
- * printable characters as @a padding describes.
+/* Return a new string with a copy of CSTR allocated in POOL aligned to
+ * the right side with spaces. This function takes UTF-8 multibyte encoding
+ * and wcwidth into account. The new string will have exactly as many
+ * printable characters as fit into MAX_WIDTH. Glyphs from CSTR will be
+ * trimmed from the LEFT.
*
- * Please note, there might be a little artifact when there is a wider
- * character, then the string won't be perfectly aligned.
+ * If MAX_WIDTH is too narrow for even a single glyph, only spaces will be
+ * returned (for example, a two-column emoji doesn't fit into one column).
+ *
+ * If CSTR is not valid UTF-8, return up to four replacement characters
+ * (U+FFFD) aligned to the right
*/
char *
-svn_utf__cstring_utf8_align_right(const char *cstr,
- int padding,
- apr_pool_t *pool);
+svn_utf__cstring_align_right_trim_left(const char *cstr,
+ apr_size_t max_width,
+ apr_pool_t *pool);
-/* Return a new string with a copy of @a cstr allocated in @a pool aligned to
+/* Return a new string with a copy of CSTR allocated in POOL aligned to
* the left side with spaces. This function takes UTF-8 multibyte encoding and
- * wcwidth into an account. The new string will be have exacly as much
- * printable characters as @a padding describes.
- *
- * Please note, there might be a little artifact when there is a wider
- * character, then the string won't be perfectly aligned.
+ * wcwidth into an account. The new string will have exactly as many
+ * printable characters as fit into MAX_WIDTH. Glyphs from CSTR will be
+ * trimmed from the RIGHT.
+x *
+ * If MAX_WIDTH is too narrow for even a single glyph, only spaces will be
+ * returned (for example, a two-column emoji doesn't fit into one column).
*
- * Similar to svn_utf__cstring_utf8_align_right() but doing alignment to the
- * left side.
+ * If CSTR is not valid UTF-8, return up to four replacement characters
+ * (U+FFFD) aligned to the left
*/
char *
-svn_utf__cstring_utf8_align_left(const char *cstr,
- int padding,
- apr_pool_t *pool);
+svn_utf__cstring_align_left(const char *cstr,
+ apr_size_t max_width,
+ apr_pool_t *pool);
#ifdef __cplusplus
}
Modified: subversion/trunk/subversion/libsvn_subr/utf.c
==============================================================================
--- subversion/trunk/subversion/libsvn_subr/utf.c Mon May 25 04:20:06
2026 (r1934575)
+++ subversion/trunk/subversion/libsvn_subr/utf.c Mon May 25 04:35:19
2026 (r1934576)
@@ -1220,8 +1220,97 @@ svn_utf__locale_encoding(apr_pool_t *poo
#endif
}
-#ifdef WIN32
+/* Return a UTF-8 string allocated in POOL of exactly MAX_WIDTH printable
+ * characters, containing up to four U+FFFD replacement characters aligned
+ * left or right according to ALIGN_LEFT. The rest of the string is padded
+ * with spaces.
+ */
+static char *
+replacement_chars(apr_size_t max_width,
+ svn_boolean_t align_left,
+ apr_pool_t *pool)
+{
+ /* String of four Unicode replacement characters, U+FFFD. */
+ static const char fffds[13] =
+ "\xef\xbf\xbd" "\xef\xbf\xbd" "\xef\xbf\xbd" "\xef\xbf\xbd";
+
+ const apr_ssize_t length = max_width >= 4 ? 12 : 3 * max_width;
+ const apr_ssize_t spaces = max_width <= 4 ? 0 : max_width - 4;
+ char *const result = apr_palloc(pool, length + spaces + 1);
+
+ if (align_left)
+ {
+ memcpy(result, fffds, length);
+ memset(result + length, ' ', spaces);
+ }
+ else
+ {
+ memset(result, ' ', spaces);
+ memcpy(result + spaces, fffds, length);
+ }
+ result[length + spaces] = '\0';
+ return result;
+}
+
+/* Return a UTF-8 string allocated in POOL of exactly MAX_WIDTH printable
+ * characters, containing the substring from START to END with display width
+ * WIDTH aligned left or right according to ALIGN_LEFT. The rest of the
+ * string is padded with spaces.
+ */
+static char *
+align_substring(const char *start, const char *end,
+ apr_ssize_t width, apr_ssize_t max_width,
+ svn_boolean_t align_left, apr_pool_t *pool)
+{
+ const apr_ssize_t length = end - start;
+ const apr_ssize_t spaces = max_width - width;
+ char *const result = apr_palloc(pool, length + spaces + 1);
+
+ if (align_left)
+ {
+ memcpy(result, start, length);
+ memset(result + length, ' ', spaces);
+ }
+ else
+ {
+ memset(result, ' ', spaces);
+ memcpy(result + spaces, start, length);
+ }
+ result[length + spaces] = '\0';
+ return result;
+}
+
+char *
+svn_utf__cstring_align_right_trim_left(const char *cstr,
+ apr_size_t max_width,
+ apr_pool_t *pool)
+{
+ const char *start, *end;
+ const apr_ssize_t width =
+ svn_utf__cstring_trim_left(&start, &end, cstr, max_width);
+ if (width < 0)
+ return replacement_chars(max_width, FALSE, pool);
+
+ return align_substring(start, end, width, max_width, FALSE, pool);
+}
+
+char *
+svn_utf__cstring_align_left(const char *cstr,
+ apr_size_t max_width,
+ apr_pool_t *pool)
+{
+ const char *start, *end;
+ const apr_ssize_t width =
+ svn_utf__cstring_trim_right(&start, &end, cstr, max_width);
+
+ if (width < 0)
+ return replacement_chars(max_width, TRUE, pool);
+
+ return align_substring(start, end, width, max_width, TRUE, pool);
+}
+
+#ifdef WIN32
svn_error_t *
svn_utf__win32_utf8_to_utf16(const WCHAR **result,
Modified: subversion/trunk/subversion/libsvn_subr/utf8proc.c
==============================================================================
--- subversion/trunk/subversion/libsvn_subr/utf8proc.c Mon May 25 04:20:06
2026 (r1934575)
+++ subversion/trunk/subversion/libsvn_subr/utf8proc.c Mon May 25 04:35:19
2026 (r1934576)
@@ -609,80 +609,6 @@ svn_utf__fuzzy_escape(const char *src, a
}
apr_ssize_t
-svn_utf__cstring_utf8_grapheme_breaks(apr_array_header_t **graphemes,
- const char *cstr,
- apr_pool_t *pool)
-{
- apr_array_header_t *breaks;
- apr_ssize_t total_width = 0;
-
- utf8proc_int32_t state = 0;
- utf8proc_int32_t codepoint1;
- utf8proc_int32_t codepoint2;
-
- int grapheme_width = 0;
- apr_size_t grapheme_start = 0;
- apr_size_t grapheme_end = 0;
-
- utf8proc_ssize_t nbytes;
- const utf8proc_uint8_t *utf8 = (const utf8proc_uint8_t *)cstr;
- if (!*utf8)
- {
- *graphemes = NULL;
- return 0;
- }
-
- nbytes = utf8proc_iterate(utf8, -1, &codepoint1);
- if (nbytes < 0)
- return -1;
-
- breaks = apr_array_make(pool, 16, sizeof(svn_utf__utf8_grapheme_t));
- grapheme_width += utf8proc_charwidth(codepoint1);
- grapheme_end += nbytes;
- utf8 += nbytes;
-
- while(*utf8)
- {
- nbytes = utf8proc_iterate(utf8, -1, &codepoint2);
- if (nbytes < 0)
- return -1;
-
- if (utf8proc_grapheme_break_stateful(codepoint1, codepoint2, &state))
- {
- svn_utf__utf8_grapheme_t grapheme;
- grapheme.start = grapheme_start;
- grapheme.end = grapheme_end;
- grapheme.width = grapheme_width;
- APR_ARRAY_PUSH(breaks, svn_utf__utf8_grapheme_t) = grapheme;
-
- total_width += grapheme_width;
- grapheme_width = 0;
- grapheme_start = grapheme_end;
- }
-
- codepoint1 = codepoint2;
- grapheme_width += utf8proc_charwidth(codepoint1);
- grapheme_end += nbytes;
- utf8 += nbytes;
- }
-
- /* Record the final grapheme. */
- if (grapheme_end > grapheme_start)
- {
- svn_utf__utf8_grapheme_t grapheme;
- grapheme.start = grapheme_start;
- grapheme.end = grapheme_end;
- grapheme.width = grapheme_width;
- APR_ARRAY_PUSH(breaks, svn_utf__utf8_grapheme_t) = grapheme;
-
- total_width += grapheme_width;
- }
-
- *graphemes = breaks;
- return total_width;
-}
-
-apr_ssize_t
svn_utf__cstring_width(apr_size_t *length, const char *cstr)
{
const char *const start = cstr;
@@ -852,72 +778,3 @@ svn_utf__cstring_trim_left(const char **
return -1;
return width - skipped;
}
-
-/* Advances CSTR by N printable UTF-8 characters */
-static const char *
-utf8_skipn(const char *cstr, apr_size_t n)
-{
- apr_size_t i = 0;
-
- while (*cstr && i < n)
- {
- utf8proc_int32_t ucs;
-
- utf8proc_ssize_t nbytes = utf8proc_iterate(
- (const utf8proc_uint8_t *)cstr, -1, &ucs);
-
- if (nbytes < 0)
- return NULL;
-
- cstr += nbytes;
- i += utf8proc_charwidth(ucs);
- }
-
- return cstr;
-}
-
-char *
-svn_utf__cstring_utf8_align_right(const char *cstr, int padding,
- apr_pool_t *pool)
-{
- int width = svn_utf_cstring_utf8_width(cstr);
- apr_size_t size = strlen(cstr);
-
- if (width > padding)
- {
- apr_ssize_t len = utf8_skipn(cstr, padding) - cstr;
- return apr_pstrmemdup(pool, cstr + size - len, len);
- }
- else
- {
- int spaces = padding - width;
- char *result = apr_palloc(pool, size + spaces + 1);
- memset(result, ' ', spaces);
- memcpy(result + spaces, cstr, size);
- result[size + spaces] = '\0';
- return result;
- }
-}
-
-char *
-svn_utf__cstring_utf8_align_left(const char *cstr, int padding,
- apr_pool_t *pool)
-{
- int width = svn_utf_cstring_utf8_width(cstr);
-
- if (width > padding)
- {
- apr_ssize_t len = utf8_skipn(cstr, padding) - cstr;
- return apr_pstrmemdup(pool, cstr, len);
- }
- else
- {
- apr_size_t size = strlen(cstr);
- int spaces = padding - width;
- char *result = apr_palloc(pool, size + spaces + 1);
- memcpy(result, cstr, size);
- memset(result + size, ' ', spaces);
- result[size + spaces] = '\0';
- return result;
- }
-}
Modified: subversion/trunk/subversion/svnbrowse/svnbrowse.c
==============================================================================
--- subversion/trunk/subversion/svnbrowse/svnbrowse.c Mon May 25 04:20:06
2026 (r1934575)
+++ subversion/trunk/subversion/svnbrowse/svnbrowse.c Mon May 25 04:35:19
2026 (r1934576)
@@ -393,20 +393,20 @@ view_draw_item(const svn_browse__style_t
/* 12 + 12 + (20 + 1) + 2 = 47 */
waddch(win, ' ');
- waddstr(win, svn_utf__cstring_utf8_align_left(
+ waddstr(win, svn_utf__cstring_align_left(
format_node_name(item, scratch_pool), getmaxx(win) - 47,
scratch_pool));
wattrset(win, get_item_style(style, svn_node_file, selected));
- waddstr(win, svn_utf__cstring_utf8_align_right(
+ waddstr(win, svn_utf__cstring_align_right_trim_left(
format_node_size(item, scratch_pool),
12, scratch_pool));
- waddstr(win, svn_utf__cstring_utf8_align_right(
+ waddstr(win, svn_utf__cstring_align_right_trim_left(
apr_psprintf(scratch_pool, "r%ld",
item->dirent->created_rev),
12, scratch_pool));
waddch(win, ' ');
- waddstr(win, svn_utf__cstring_utf8_align_left(
+ waddstr(win, svn_utf__cstring_align_left(
item->dirent->last_author, 20, scratch_pool));
waddch(win, ' ');
}
@@ -438,7 +438,7 @@ view_draw_header(svn_browse__view_t *vie
wmove(win, 0, 0);
wattrset(win, view->style->header);
waddstr(win, prefix);
- waddstr(win, svn_utf__cstring_utf8_align_left(
+ waddstr(win, svn_utf__cstring_align_left(
apr_psprintf(scratch_pool, "URL: %s", abspath),
getmaxx(win) - strlen(prefix) - strlen(suffix),
scratch_pool));
@@ -484,18 +484,18 @@ view_draw_footer(svn_browse__view_t *vie
wmove(win, 0, 0);
wattrset(win, view->style->footer);
waddstr(win, " ");
- waddstr(win, svn_utf__cstring_utf8_align_left(
+ waddstr(win, svn_utf__cstring_align_left(
apr_psprintf(scratch_pool, "Ready"),
getmaxx(win) - 4 - strlen(brand) - 16,
scratch_pool));
waddstr(win, brand);
- waddstr(win, svn_utf__cstring_utf8_align_right(
+ waddstr(win, svn_utf__cstring_align_right_trim_left(
apr_psprintf(scratch_pool, "%d/%d",
state->selection + 1,
view_get_list_height(state)),
8, scratch_pool));
- waddstr(win, svn_utf__cstring_utf8_align_right(
+ waddstr(win, svn_utf__cstring_align_right_trim_left(
format_percentage_scroll(state->scroller_offset,
view_get_list_height(state),
getmaxy(view->list),
Modified: subversion/trunk/subversion/tests/libsvn_subr/utf-test.c
==============================================================================
--- subversion/trunk/subversion/tests/libsvn_subr/utf-test.c Mon May 25
04:20:06 2026 (r1934575)
+++ subversion/trunk/subversion/tests/libsvn_subr/utf-test.c Mon May 25
04:35:19 2026 (r1934576)
@@ -1258,88 +1258,62 @@ test_utf8_trim_left(apr_pool_t *pool)
}
static svn_error_t *
-test_utf8_grapheme_breaks(apr_pool_t *pool)
-{
- apr_array_header_t *graphemes = (void*)~0;
-
- SVN_TEST_INT_ASSERT(
- svn_utf__cstring_utf8_grapheme_breaks(&graphemes, "", pool), 0);
- SVN_TEST_ASSERT(graphemes == NULL);
-
- SVN_TEST_INT_ASSERT(
- svn_utf__cstring_utf8_grapheme_breaks(&graphemes, invalid, pool), -1);
-
-#define STRING_LENGTH_FROM_GRAPHEMES \
- APR_ARRAY_IDX(graphemes, graphemes->nelts - 1, svn_utf__utf8_grapheme_t).end
-
- svn_utf__cstring_utf8_grapheme_breaks(&graphemes, "abc123", pool);
- SVN_TEST_INT_ASSERT(graphemes->nelts, 6);
- SVN_TEST_INT_ASSERT(STRING_LENGTH_FROM_GRAPHEMES, strlen("abc123"));
-
- svn_utf__cstring_utf8_grapheme_breaks(&graphemes, fat_emojis, pool);
- SVN_TEST_INT_ASSERT(graphemes->nelts, 3);
- SVN_TEST_INT_ASSERT(STRING_LENGTH_FROM_GRAPHEMES, strlen(fat_emojis));
- SVN_TEST_INT_ASSERT(
- APR_ARRAY_IDX(graphemes, 0, svn_utf__utf8_grapheme_t).width, 2);
- SVN_TEST_INT_ASSERT(
- APR_ARRAY_IDX(graphemes, 1, svn_utf__utf8_grapheme_t).width, 2);
- SVN_TEST_INT_ASSERT(
- APR_ARRAY_IDX(graphemes, 2, svn_utf__utf8_grapheme_t).width, 2);
-
- svn_utf__cstring_utf8_grapheme_breaks(&graphemes, mixup, pool);
- SVN_TEST_INT_ASSERT(STRING_LENGTH_FROM_GRAPHEMES, strlen(mixup));
- SVN_TEST_INT_ASSERT(graphemes->nelts, 10);
-
- svn_utf__cstring_utf8_grapheme_breaks(&graphemes, bom, pool);
- SVN_TEST_INT_ASSERT(STRING_LENGTH_FROM_GRAPHEMES, strlen(bom));
- SVN_TEST_INT_ASSERT(graphemes->nelts, 4);
- SVN_TEST_INT_ASSERT(
- APR_ARRAY_IDX(graphemes, 0, svn_utf__utf8_grapheme_t).width, 0);
-
-#undef STRING_LENGTH_FROM_GRAPHEMES
-
- return SVN_NO_ERROR;
-}
-
-static svn_error_t *
test_utf8_align(apr_pool_t *pool)
{
+ /* Invalid */
+ SVN_TEST_STRING_ASSERT(svn_utf__cstring_align_left(invalid, 5, pool),
+ "\xef\xbf\xbd" "\xef\xbf\xbd"
+ "\xef\xbf\xbd" "\xef\xbf\xbd"
+ " ");
+ SVN_TEST_STRING_ASSERT(svn_utf__cstring_align_left(invalid, 3, pool),
+ "\xef\xbf\xbd" "\xef\xbf\xbd" "\xef\xbf\xbd");
+ SVN_TEST_STRING_ASSERT(
+ svn_utf__cstring_align_right_trim_left(invalid, 5, pool),
+ " "
+ "\xef\xbf\xbd" "\xef\xbf\xbd"
+ "\xef\xbf\xbd" "\xef\xbf\xbd");
+ SVN_TEST_STRING_ASSERT(
+ svn_utf__cstring_align_right_trim_left(invalid, 3, pool),
+ "\xef\xbf\xbd" "\xef\xbf\xbd" "\xef\xbf\xbd");
+
/* ASCII */
- SVN_TEST_STRING_ASSERT(svn_utf__cstring_utf8_align_left("abc", 5, pool),
+ SVN_TEST_STRING_ASSERT(svn_utf__cstring_align_left("abc", 5, pool),
"abc ");
- SVN_TEST_STRING_ASSERT(svn_utf__cstring_utf8_align_left("abc", 2, pool),
+ SVN_TEST_STRING_ASSERT(svn_utf__cstring_align_left("abc", 2, pool),
"ab");
- SVN_TEST_STRING_ASSERT(svn_utf__cstring_utf8_align_right("abc", 5, pool),
+ SVN_TEST_STRING_ASSERT(svn_utf__cstring_align_right_trim_left("abc", 5,
pool),
" abc");
- SVN_TEST_STRING_ASSERT(svn_utf__cstring_utf8_align_right("abc", 2, pool),
+ SVN_TEST_STRING_ASSERT(svn_utf__cstring_align_right_trim_left("abc", 2,
pool),
"bc");
/* two byte symbols */
SVN_TEST_STRING_ASSERT(
- svn_utf__cstring_utf8_align_left("\xc5\xaf\xc5\xa1", 4, pool),
+ svn_utf__cstring_align_left("\xc5\xaf\xc5\xa1", 4, pool),
"\xc5\xaf\xc5\xa1 ");
SVN_TEST_STRING_ASSERT(
- svn_utf__cstring_utf8_align_left("\xc5\xaf\xc5\xa1", 1, pool),
+ svn_utf__cstring_align_left("\xc5\xaf\xc5\xa1", 1, pool),
"\xc5\xaf");
SVN_TEST_STRING_ASSERT(
- svn_utf__cstring_utf8_align_right("\xc5\xaf\xc5\xa1", 4, pool),
+ svn_utf__cstring_align_right_trim_left("\xc5\xaf\xc5\xa1", 4, pool),
" \xc5\xaf\xc5\xa1");
SVN_TEST_STRING_ASSERT(
- svn_utf__cstring_utf8_align_right("\xc5\xaf\xc5\xa1", 1, pool),
+ svn_utf__cstring_align_right_trim_left("\xc5\xaf\xc5\xa1", 1, pool),
"\xc5\xa1");
/* an emoji */
SVN_TEST_STRING_ASSERT(
- svn_utf__cstring_utf8_align_right("\xf0\x9f\xa5\xba", 2, pool),
+ svn_utf__cstring_align_right_trim_left("\xf0\x9f\xa5\xba", 2, pool),
"\xf0\x9f\xa5\xba");
SVN_TEST_STRING_ASSERT(
- svn_utf__cstring_utf8_align_right("\xf0\x9f\xa5\xba", 3, pool),
+ svn_utf__cstring_align_right_trim_left("\xf0\x9f\xa5\xba", 3, pool),
" \xf0\x9f\xa5\xba");
- /* this is technically wrong (?) */
+ /* The emoji FACE WITH PLEADING EYES is two columns wide but we only
+ have space for one column. Since we can't split the emoji in half,
+ we can't display it, either. */
SVN_TEST_STRING_ASSERT(
- svn_utf__cstring_utf8_align_right("\xf0\x9f\xa5\xba", 1, pool),
- "\xf0\x9f\xa5\xba");
+ svn_utf__cstring_align_right_trim_left("\xf0\x9f\xa5\xba", 1, pool),
+ " ");
return SVN_NO_ERROR;
}
@@ -1380,8 +1354,6 @@ static struct svn_test_descriptor_t test
"test grapheme-aware right trim"),
SVN_TEST_PASS2(test_utf8_trim_left,
"test grapheme-aware left trim"),
- SVN_TEST_PASS2(test_utf8_grapheme_breaks,
- "test utf8 grapheme breaks"),
SVN_TEST_PASS2(test_utf8_align,
"test utf8 alignment"),
SVN_TEST_NULL