about summary refs log tree commit diff
path: root/libidn/idna.c
diff options
context:
space:
mode:
Diffstat (limited to 'libidn/idna.c')
-rw-r--r--libidn/idna.c69
1 files changed, 52 insertions, 17 deletions
diff --git a/libidn/idna.c b/libidn/idna.c
index bf692c029b..81e92f7d06 100644
--- a/libidn/idna.c
+++ b/libidn/idna.c
@@ -116,9 +116,13 @@ idna_to_ascii_4i (const uint32_t * in, size_t inlen, char *out, int flags)
     do
       {
 	len = 2 * len + 10;	/* XXX better guess? */
-	p = realloc (p, len);
+	char *newp = realloc (p, len);
 	if (p == NULL)
-	  return IDNA_MALLOC_ERROR;
+	  {
+	    free (p);
+	    return IDNA_MALLOC_ERROR;
+	  }
+	p = newp;
 
 	if (flags & IDNA_ALLOW_UNASSIGNED)
 	  rc = stringprep_nameprep (p, len);
@@ -288,9 +292,13 @@ idna_to_unicode_internal (char *utf8in,
    */
   do
     {
-      utf8in = realloc (utf8in, utf8len + addlen);
-      if (!utf8in)
-	return IDNA_MALLOC_ERROR;
+      char *newp = realloc (utf8in, utf8len + addlen);
+      if (newp == NULL)
+	{
+	  free (utf8in);
+	  return IDNA_MALLOC_ERROR;
+	}
+      utf8in = newp;
       if (flags & IDNA_ALLOW_UNASSIGNED)
 	rc = stringprep_nameprep (utf8in, utf8len + addlen);
       else
@@ -300,7 +308,10 @@ idna_to_unicode_internal (char *utf8in,
   while (rc == STRINGPREP_TOO_SMALL_BUFFER);
 
   if (rc != STRINGPREP_OK)
-    return IDNA_STRINGPREP_ERROR;
+    {
+      free (utf8in);
+      return IDNA_STRINGPREP_ERROR;
+    }
 
   /* 3. Verify that the sequence begins with the ACE prefix, and save a
    * copy of the sequence.
@@ -308,7 +319,10 @@ idna_to_unicode_internal (char *utf8in,
 
 step3:
   if (memcmp (IDNA_ACE_PREFIX, utf8in, strlen (IDNA_ACE_PREFIX)) != 0)
-    return IDNA_NO_ACE_PREFIX;
+    {
+      free (utf8in);
+      return IDNA_NO_ACE_PREFIX;
+    }
 
   /* 4. Remove the ACE prefix.
    */
@@ -325,7 +339,10 @@ step3:
 
   rc = punycode_decode (strlen (utf8in), utf8in, outlen, out, NULL);
   if (rc != PUNYCODE_SUCCESS)
-    return IDNA_PUNYCODE_ERROR;
+    {
+      free (utf8in);
+      return IDNA_PUNYCODE_ERROR;
+    }
 
   out[*outlen] = 0;		/* add zero */
 
@@ -334,18 +351,25 @@ step3:
 
   rc = idna_to_ascii_4i (out, *outlen, tmpout, flags);
   if (rc != IDNA_SUCCESS)
-    return rc;
+    {
+      free (utf8in);
+      return rc;
+    }
 
   /* 7. Verify that the result of step 6 matches the saved copy from
    * step 3, using a case-insensitive ASCII comparison.
    */
 
   if (strcasecmp (utf8in, tmpout + strlen (IDNA_ACE_PREFIX)) != 0)
-    return IDNA_ROUNDTRIP_VERIFY_ERROR;
+    {
+      free (utf8in);
+      return IDNA_ROUNDTRIP_VERIFY_ERROR;
+    }
 
   /* 8. Return the saved copy from step 5.
    */
 
+  free (utf8in);
   return IDNA_SUCCESS;
 }
 
@@ -404,7 +428,7 @@ idna_to_unicode_44i (const uint32_t * in, size_t inlen,
       *outlen = inlen;
     }
 
-  free (p);
+  /* p is freed in idna_to_unicode_internal.  */
 
   return rc;
 }
@@ -479,9 +503,13 @@ idna_to_ascii_4z (const uint32_t * input, char **output, int flags)
 
       if (out)
 	{
-	  out = realloc (out, strlen (out) + 1 + strlen (buf) + 1);
-	  if (!out)
-	    return IDNA_MALLOC_ERROR;
+	  char *newp = realloc (out, strlen (out) + 1 + strlen (buf) + 1);
+	  if (!newp)
+	    {
+	      free (out);
+	      return IDNA_MALLOC_ERROR;
+	    }
+	  out = newp;
 	  strcat (out, ".");
 	  strcat (out, buf);
 	}
@@ -605,9 +633,16 @@ idna_to_unicode_4z4z (const uint32_t * input, uint32_t ** output, int flags)
 
       if (out)
 	{
-	  out = realloc (out, sizeof (out[0]) * (outlen + 1 + buflen + 1));
-	  if (!out)
-	    return IDNA_MALLOC_ERROR;
+	  uint32_t *newp = realloc (out,
+				    sizeof (out[0])
+				    * (outlen + 1 + buflen + 1));
+	  if (!newp)
+	    {
+	      free (buf);
+	      free (out);
+	      return IDNA_MALLOC_ERROR;
+	    }
+	  out = newp;
 	  out[outlen++] = 0x002E;	/* '.' (full stop) */
 	  memcpy (out + outlen, buf, sizeof (buf[0]) * buflen);
 	  outlen += buflen;