Switch to side-by-side view

--- a/src/unac/unac.c
+++ b/src/unac/unac.c
@@ -13067,7 +13067,7 @@
  * Debug level. See unac.h for a detailed discussion of the
  * values.
  */
-static int debug_level = UNAC_DEBUG_NONE;
+static int debug_level = UNAC_DEBUG_LOW;
 
 #ifdef UNAC_DEBUG_AVAILABLE
 
@@ -13142,7 +13142,7 @@
 
   if(name == 0) {
     if((cd = iconv_open("UTF-16BE", "UTF-16BE")) == (iconv_t)-1) {
-      if(debug_level == UNAC_DEBUG_LOW) DEBUG("could not find UTF-16BE (see iconv -l), using UTF-16. If UTF-16 happens to be encoded in little endian, be prepared for an horrible mess.");
+      if(debug_level >= UNAC_DEBUG_LOW) DEBUG("could not find UTF-16BE (see iconv -l), using UTF-16. If UTF-16 happens to be encoded in little endian, be prepared for an horrible mess.");
       name = "UTF-16";
     } else {
       iconv_close(cd);
@@ -13162,14 +13162,24 @@
   int i;
 
   out_size = in_length > 0 ? in_length : 1024;
-  if(*outp) {
+  if (*outp) {
     out = *outp;
     /* +1 for null */
     out = realloc(out, out_size + 1);
+    if(out == 0) {
+	if(debug_level >= UNAC_DEBUG_LOW)
+	  DEBUG("realloc %d bytes failed\n", out_size+1);
+	// *outp is still valid. Let the caller free it
+	return -1;
+    }
   } else {
     /* +1 for null */
     out = malloc(out_size + 1);
-    if(out == 0) return -1;
+    if (out == 0) {
+	if(debug_level >= UNAC_DEBUG_LOW)
+	  DEBUG("malloc %d bytes failed\n", out_size+1);
+	return -1;
+    }
   }
   out_length = 0;
 
@@ -13204,15 +13214,21 @@
 	DEBUG_APPEND("\n");
       }
     }
+
     /*
      * Make sure there is enough space to hold the decomposition
+     * Note: a previous realloc may have succeeded, which means that *outp 
+     * is not valid any more. We have to do the freeing and zero out *outp
      */
     if(out_length + ((l + 1) * 2) > out_size) {
       out_size += ((l + 1) * 2) + 1024;
+      char *saved = out;
       out = realloc(out, out_size);
       if(out == 0) {
-	if(debug_level == UNAC_DEBUG_LOW)
+	if(debug_level >= UNAC_DEBUG_LOW)
 	  DEBUG("realloc %d bytes failed\n", out_size);
+        free(saved);
+	*outp = 0;
 	return -1;
       }
     }
@@ -13283,10 +13299,20 @@
     out = *outp;
     /* +1 for null */
     out = realloc(out, out_size + 1);
+    if(out == 0) {
+	// *outp still valid, no freeing
+	if(debug_level >= UNAC_DEBUG_LOW)
+	  DEBUG("realloc %d bytes failed\n", out_size+1);
+	return -1;
+    }
   } else {
     /* +1 for null */
     out = malloc(out_size + 1);
-    if(out == 0) return -1;
+    if(out == 0) {
+	if(debug_level >= UNAC_DEBUG_LOW)
+	  DEBUG("malloc %d bytes failed\n", out_size+1);
+	return -1;
+    }
   }
   out_remain = out_size;
   out_base = out;
@@ -13338,13 +13364,24 @@
       case E2BIG:
 	{
 	  /*
-	 * The output does not fit in the current out buffer, enlarge it.
-	 */
+	   * The output does not fit in the current out buffer, enlarge it.
+	   */
 	  int length = out - out_base;
 	  out_size *= 2;
-	  /* +1 for null */
-	  out_base = realloc(out_base, out_size + 1);
-	  if(out_base == 0) return -1;
+	  {
+	      char *saved = out_base;
+	      /* +1 for null */
+	      out_base = realloc(out_base, out_size + 1);
+	      if (out_base == 0) {
+		  // *outp potentially not valid any more. Free here,
+		  // and zero out
+		  if(debug_level >= UNAC_DEBUG_LOW)
+		      DEBUG("realloc %d bytes failed\n", out_size+1);
+		  free(saved);
+		  *outp = 0;
+		  return -1;
+	      }
+	  }
 	  out = out_base + length;
 	  out_remain = out_size - length;
 	}
@@ -13372,11 +13409,13 @@
    * When converting an empty string, skip everything but alloc the
    * buffer if NULL pointer.
    */
-  if(in_length <= 0) {
-    if(!*outp)
-      *outp = malloc(32);
-    (*outp)[0] = '\0';
-    *out_lengthp = 0;
+  if (in_length <= 0) {
+      if(!*outp) {
+	  if ((*outp = malloc(32)) == 0)
+	      return -1;
+      }
+      (*outp)[0] = '\0';
+      *out_lengthp = 0;
   } else {
     char* utf16 = 0;
     size_t utf16_length = 0;