Skip to content

Commit 25524b6

Browse files
Wer-Wolfij-intel
authored andcommitted
fs/nls: Fix utf16 to utf8 conversion
Currently the function responsible for converting between utf16 and utf8 strings will ignore any characters that cannot be converted. This however also includes multi-byte characters that do not fit into the provided string buffer. This can cause problems if such a multi-byte character is followed by a single-byte character. In such a case the multi-byte character might be ignored when the provided string buffer is too small, but the single-byte character might fit and is thus still copied into the resulting string. Fix this by stop filling the provided string buffer once a character does not fit. In order to be able to do this extend utf32_to_utf8() to return useful errno codes instead of -1. Fixes: 74675a5 ("NLS: update handling of Unicode") Signed-off-by: Armin Wolf <W_Armin@gmx.de> Link: https://patch.msgid.link/20251111131125.3379-2-W_Armin@gmx.de Reviewed-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com> Signed-off-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>
1 parent 39ae6c5 commit 25524b6

1 file changed

Lines changed: 12 additions & 4 deletions

File tree

fs/nls/nls_base.c

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -94,7 +94,7 @@ int utf32_to_utf8(unicode_t u, u8 *s, int maxout)
9494

9595
l = u;
9696
if (l > UNICODE_MAX || (l & SURROGATE_MASK) == SURROGATE_PAIR)
97-
return -1;
97+
return -EILSEQ;
9898

9999
nc = 0;
100100
for (t = utf8_table; t->cmask && maxout; t++, maxout--) {
@@ -110,7 +110,7 @@ int utf32_to_utf8(unicode_t u, u8 *s, int maxout)
110110
return nc;
111111
}
112112
}
113-
return -1;
113+
return -EOVERFLOW;
114114
}
115115
EXPORT_SYMBOL(utf32_to_utf8);
116116

@@ -217,8 +217,16 @@ int utf16s_to_utf8s(const wchar_t *pwcs, int inlen, enum utf16_endian endian,
217217
inlen--;
218218
}
219219
size = utf32_to_utf8(u, op, maxout);
220-
if (size == -1) {
221-
/* Ignore character and move on */
220+
if (size < 0) {
221+
if (size == -EILSEQ) {
222+
/* Ignore character and move on */
223+
continue;
224+
}
225+
/*
226+
* Stop filling the buffer with data once a character
227+
* does not fit anymore.
228+
*/
229+
break;
222230
} else {
223231
op += size;
224232
maxout -= size;

0 commit comments

Comments
 (0)