mirror of
https://gitlab.gnome.org/GNOME/glib.git
synced 2024-11-05 00:46:16 +01:00
utf8: report allocation error
Make some of the conversion functions a bit more friendly to allocation failure. Even though the glib policy is to abort() on allocation failure by default, it can be quite helpful to return an allocation error for functions already providing a GError. I needed a safer g_utf16_to_utf8() to solve crash on big clipboard operations with win32, related to rhbz#1017250 (and coming gdk handling bug). https://bugzilla.gnome.org/show_bug.cgi?id=711546
This commit is contained in:
parent
0dbe5c43df
commit
d6a19d2e76
@ -44,6 +44,7 @@ G_BEGIN_DECLS
|
||||
* @G_CONVERT_ERROR_PARTIAL_INPUT: Partial character sequence at end of input.
|
||||
* @G_CONVERT_ERROR_BAD_URI: URI is invalid.
|
||||
* @G_CONVERT_ERROR_NOT_ABSOLUTE_PATH: Pathname is not an absolute path.
|
||||
* @G_CONVERT_ERROR_NO_MEMORY: No memory available. Since: 2.40
|
||||
*
|
||||
* Error codes returned by character set conversion routines.
|
||||
*/
|
||||
@ -54,7 +55,8 @@ typedef enum
|
||||
G_CONVERT_ERROR_FAILED,
|
||||
G_CONVERT_ERROR_PARTIAL_INPUT,
|
||||
G_CONVERT_ERROR_BAD_URI,
|
||||
G_CONVERT_ERROR_NOT_ABSOLUTE_PATH
|
||||
G_CONVERT_ERROR_NOT_ABSOLUTE_PATH,
|
||||
G_CONVERT_ERROR_NO_MEMORY
|
||||
} GConvertError;
|
||||
|
||||
/**
|
||||
|
47
glib/gutf8.c
47
glib/gutf8.c
@ -776,6 +776,16 @@ g_utf8_to_ucs4_fast (const gchar *str,
|
||||
return result;
|
||||
}
|
||||
|
||||
static gpointer
|
||||
try_malloc (gsize n_bytes, GError **error)
|
||||
{
|
||||
gpointer ptr = g_try_malloc (n_bytes);
|
||||
if (ptr == NULL)
|
||||
g_set_error_literal (error, G_CONVERT_ERROR, G_CONVERT_ERROR_NO_MEMORY,
|
||||
_("Failed to allocate memory"));
|
||||
return ptr;
|
||||
}
|
||||
|
||||
/**
|
||||
* g_utf8_to_ucs4:
|
||||
* @str: a UTF-8 encoded string
|
||||
@ -840,8 +850,10 @@ g_utf8_to_ucs4 (const gchar *str,
|
||||
in = g_utf8_next_char (in);
|
||||
}
|
||||
|
||||
result = g_new (gunichar, n_chars + 1);
|
||||
|
||||
result = try_malloc (sizeof (gunichar) * (n_chars + 1), error);
|
||||
if (result == NULL)
|
||||
goto err_out;
|
||||
|
||||
in = str;
|
||||
for (i=0; i < n_chars; i++)
|
||||
{
|
||||
@ -911,7 +923,10 @@ g_ucs4_to_utf8 (const gunichar *str,
|
||||
result_length += UTF8_LENGTH (str[i]);
|
||||
}
|
||||
|
||||
result = g_malloc (result_length + 1);
|
||||
result = try_malloc (result_length + 1, error);
|
||||
if (result == NULL)
|
||||
goto err_out;
|
||||
|
||||
p = result;
|
||||
|
||||
i = 0;
|
||||
@ -1043,8 +1058,10 @@ g_utf16_to_utf8 (const gunichar2 *str,
|
||||
/* At this point, everything is valid, and we just need to convert
|
||||
*/
|
||||
/********** DIFFERENT for UTF8/UCS4 **********/
|
||||
result = g_malloc (n_bytes + 1);
|
||||
|
||||
result = try_malloc (n_bytes + 1, error);
|
||||
if (result == NULL)
|
||||
goto err_out;
|
||||
|
||||
high_surrogate = 0;
|
||||
out = result;
|
||||
in = str;
|
||||
@ -1180,8 +1197,10 @@ g_utf16_to_ucs4 (const gunichar2 *str,
|
||||
/* At this point, everything is valid, and we just need to convert
|
||||
*/
|
||||
/********** DIFFERENT for UTF8/UCS4 **********/
|
||||
result = g_malloc (n_bytes + 4);
|
||||
|
||||
result = try_malloc (n_bytes + 4, error);
|
||||
if (result == NULL)
|
||||
goto err_out;
|
||||
|
||||
high_surrogate = 0;
|
||||
out = result;
|
||||
in = str;
|
||||
@ -1310,8 +1329,10 @@ g_utf8_to_utf16 (const gchar *str,
|
||||
in = g_utf8_next_char (in);
|
||||
}
|
||||
|
||||
result = g_new (gunichar2, n16 + 1);
|
||||
|
||||
result = try_malloc (sizeof (gunichar2) * (n16 + 1), error);
|
||||
if (result == NULL)
|
||||
goto err_out;
|
||||
|
||||
in = str;
|
||||
for (i = 0; i < n16;)
|
||||
{
|
||||
@ -1405,9 +1426,11 @@ g_ucs4_to_utf16 (const gunichar *str,
|
||||
|
||||
i++;
|
||||
}
|
||||
|
||||
result = g_new (gunichar2, n16 + 1);
|
||||
|
||||
|
||||
result = try_malloc (sizeof (gunichar2) * (n16 + 1), error);
|
||||
if (result == NULL)
|
||||
goto err_out;
|
||||
|
||||
for (i = 0, j = 0; j < n16; i++)
|
||||
{
|
||||
gunichar wc = str[i];
|
||||
|
Loading…
Reference in New Issue
Block a user