Commit c893450a authored by Christian Persch's avatar Christian Persch

icu: glue: Set error callback on the from-unicode conversion

The from-unicode side of the converter is only used on user input
(keyboard, IM, clipboard paste). When it receives input not representable
in the target encoding, it inserts the substitution character of the
target encoding, which in many cases is U+001A. However, when sent to a
PTY, that is interpreted as Ctrl-Z.

Instead, set the from-unicode converter to error out when encountering
such unrepresentable input.

Fixes: #233
(cherry picked from commit 344c2e77)
parent 2e178c52
......@@ -111,10 +111,35 @@ make_icu_converter(char const* charset,
{
auto err = icu::ErrorCode{};
auto converter = std::shared_ptr<UConverter>{ucnv_open(charset, err), &ucnv_close};
if (err.isFailure())
if (err.isFailure()) {
g_set_error(error, G_CONVERT_ERROR, G_CONVERT_ERROR_NO_CONVERSION,
"Failed to open converter for charset \"%s\": %s",
charset, err.errorName());
return {};
}
/* The unicode->target conversion is only used when converting
* user input (keyboard, clipboard) to be sent to the PTY, and
* we don't want the ucnv_fromUChars to substitute the SUB character
* for illegal input, since SUB is U+001A which is Ctrl-Z, which
* the default UCNV_FROM_U_CALLBACK_SUBSTITUTE callback does.
* Use UCNV_FROM_U_CALLBACK_STOP to stop conversion when encountering
* illegal input.
*/
err.reset();
ucnv_setFromUCallBack(converter.get(),
UCNV_FROM_U_CALLBACK_STOP,
nullptr,
nullptr,
nullptr,
err);
if (err.isFailure()) {
g_set_error(error, G_CONVERT_ERROR, G_CONVERT_ERROR_NO_CONVERSION,
"Failed ucnv_setFromUCallBack for charset \"%s\": %s",
charset, err.errorName());
return {};
}
return converter;
}
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment