[glib] utf8: report allocation error



commit d6a19d2e76654570c056ef328c6fb4fdda939272
Author: Marc-André Lureau <marcandre lureau gmail com>
Date:   Wed Nov 6 12:21:58 2013 +0100

    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

 glib/gconvert.h |    4 +++-
 glib/gutf8.c    |   47 +++++++++++++++++++++++++++++++++++------------
 2 files changed, 38 insertions(+), 13 deletions(-)
---
diff --git a/glib/gconvert.h b/glib/gconvert.h
index 1945c07..3df66ce 100644
--- a/glib/gconvert.h
+++ b/glib/gconvert.h
@@ -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;
 
 /**
diff --git a/glib/gutf8.c b/glib/gutf8.c
index 9244fe8..149eeef 100644
--- a/glib/gutf8.c
+++ b/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];


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]