svn rev #21923: trunk/src/ include/ lib/krb5/error_tables/ lib/krb5/unicode/

ghudson@MIT.EDU ghudson at MIT.EDU
Mon Feb 9 13:35:22 EST 2009


http://src.mit.edu/fisheye/changelog/krb5/?cs=21923
Commit By: ghudson
Log Message:
ticket: 6378
subject: Change contract of krb5int_utf8_normalize and fix memory leaks
tags: pullup
target_version: 1.7

Make krb5int_utf8_normalize return a krb5_error_code and always allocate
a structure to be placed in the output parameter.  Adjust the function
structure to use a cleanup handler, fixing many memory leaks.



Changed Files:
U   trunk/src/include/k5-unicode.h
U   trunk/src/lib/krb5/error_tables/krb5_err.et
U   trunk/src/lib/krb5/unicode/ucstr.c
Modified: trunk/src/include/k5-unicode.h
===================================================================
--- trunk/src/include/k5-unicode.h	2009-02-09 18:13:08 UTC (rev 21922)
+++ trunk/src/include/k5-unicode.h	2009-02-09 18:35:19 UTC (rev 21923)
@@ -117,9 +117,9 @@
 #define KRB5_UTF8_ARG2NFC	0x4U
 #define KRB5_UTF8_APPROX	0x8U
 
-krb5_data * krb5int_utf8_normalize(
+krb5_error_code krb5int_utf8_normalize(
     krb5_data *,
-    krb5_data *,
+    krb5_data **,
     unsigned);
 
 int krb5int_utf8_normcmp(

Modified: trunk/src/lib/krb5/error_tables/krb5_err.et
===================================================================
--- trunk/src/lib/krb5/error_tables/krb5_err.et	2009-02-09 18:13:08 UTC (rev 21922)
+++ trunk/src/lib/krb5/error_tables/krb5_err.et	2009-02-09 18:35:19 UTC (rev 21923)
@@ -345,4 +345,6 @@
 
 error_code KRB5_PLUGIN_NO_HANDLE,	"Supplied data not handled by this plugin"
 error_code KRB5_PLUGIN_OP_NOTSUPP,  "Plugin does not support the operaton"
+
+error_code KRB5_ERR_INVALID_UTF8,	"Invalid UTF-8 string"
 end

Modified: trunk/src/lib/krb5/unicode/ucstr.c
===================================================================
--- trunk/src/lib/krb5/unicode/ucstr.c	2009-02-09 18:13:08 UTC (rev 21922)
+++ trunk/src/lib/krb5/unicode/ucstr.c	2009-02-09 18:35:19 UTC (rev 21923)
@@ -104,15 +104,17 @@
 #define TOUPPER(c)  (islower(c) ? toupper(c) : (c))
 #define TOLOWER(c)  (isupper(c) ? tolower(c) : (c))
 
-krb5_data *
+krb5_error_code
 krb5int_utf8_normalize(
 		       krb5_data * data,
-		       krb5_data * newdata,
+		       krb5_data ** newdataptr,
 		       unsigned flags)
 {
     int i, j, len, clen, outpos, ucsoutlen, outsize, last;
-    char *out, *outtmp, *s;
-    krb5_ucs4 *ucs, *p, *ucsout;
+    char *out = NULL, *outtmp, *s;
+    krb5_ucs4 *ucs = NULL, *p, *ucsout = NULL;
+    krb5_data *newdata;
+    krb5_error_code retval = 0;
 
     static unsigned char mask[] = {
     0, 0x7f, 0x1f, 0x0f, 0x07, 0x03, 0x01};
@@ -120,17 +122,15 @@
     unsigned casefold = flags & KRB5_UTF8_CASEFOLD;
     unsigned approx = flags & KRB5_UTF8_APPROX;
 
-    if (data == NULL) {
-	return NULL;
-    }
+    *newdataptr = NULL;
+
     s = data->data;
     len = data->length;
 
-    if (!newdata) {
-	newdata = (krb5_data *) malloc(sizeof(*newdata));
-	if (newdata == NULL)
-	    return NULL;
-    }
+    newdata = malloc(sizeof(*newdata));
+    if (newdata == NULL)
+	return ENOMEM;
+
     /*
      * Should first check to see if string is already in proper normalized
      * form. This is almost as time consuming as the normalization though.
@@ -140,9 +140,10 @@
     if (KRB5_UTF8_ISASCII(s)) {
 	if (casefold) {
 	    outsize = len + 7;
-	    out = (char *) malloc(outsize);
+	    out = malloc(outsize);
 	    if (out == NULL) {
-		return NULL;
+		retval = ENOMEM;
+		goto cleanup;
 	    }
 	    outpos = 0;
 
@@ -151,10 +152,7 @@
 	    }
 	    if (i == len) {
 		out[outpos++] = TOLOWER(s[len - 1]);
-		out[outpos] = '\0';
-		newdata->data = out;
-		newdata->length = outpos;
-		return newdata;
+		goto cleanup;
 	    }
 	} else {
 	    for (i = 1; (i < len) && KRB5_UTF8_ISASCII(s + i); i++) {
@@ -165,25 +163,29 @@
 		newdata->length = len;
 		newdata->data = malloc(newdata->length + 1);
 		if (newdata->data == NULL) {
-		    return NULL;
+		    retval = ENOMEM;
+		    goto cleanup;
 		}
 		memcpy(newdata->data, s, len);
 		newdata->data[len] = '\0';
-		return newdata;
+		*newdataptr = newdata;
+		return 0;
 	    }
 	    outsize = len + 7;
-	    out = (char *) malloc(outsize);
+	    out = malloc(outsize);
 	    if (out == NULL) {
-		return NULL;
+		retval = ENOMEM;
+		goto cleanup;
 	    }
 	    outpos = i - 1;
 	    memcpy(out, s, outpos);
 	}
     } else {
 	outsize = len + 7;
-	out = (char *) malloc(outsize);
+	out = malloc(outsize);
 	if (out == NULL) {
-	    return NULL;
+	    retval = ENOMEM;
+	    goto cleanup;
 	}
 	outpos = 0;
 	i = 0;
@@ -191,8 +193,8 @@
 
     p = ucs = malloc(len * sizeof(*ucs));
     if (ucs == NULL) {
-	free(out);
-	return NULL;
+	retval = ENOMEM;
+	goto cleanup;
     }
     /* convert character before first non-ascii to ucs-4 */
     if (i > 0) {
@@ -206,9 +208,8 @@
 	while (i < len) {
 	    clen = KRB5_UTF8_CHARLEN2(s + i, clen);
 	    if (clen == 0) {
-		free(ucs);
-		free(out);
-		return NULL;
+		retval = KRB5_ERR_INVALID_UTF8;
+		goto cleanup;
 	    }
 	    if (clen == 1) {
 		/* ascii */
@@ -218,9 +219,8 @@
 	    i++;
 	    for (j = 1; j < clen; j++) {
 		if ((s[i] & 0xc0) != 0x80) {
-		    free(ucs);
-		    free(out);
-		    return NULL;
+		    retval = KRB5_ERR_INVALID_UTF8;
+		    goto cleanup;
 		}
 		*p <<= 6;
 		*p |= s[i] & 0x3f;
@@ -249,12 +249,10 @@
 		 */
 		if (outsize - outpos < 7) {
 		    outsize = ucsoutlen - j + outpos + 6;
-		    outtmp = (char *) realloc(out, outsize);
+		    outtmp = realloc(out, outsize);
 		    if (outtmp == NULL) {
-			free(ucsout);
-			free(ucs);
-			free(out);
-			return NULL;
+			retval = ENOMEM;
+			goto cleanup;
 		    }
 		    out = outtmp;
 		}
@@ -273,11 +271,10 @@
 	/* Allocate more space in out if necessary */
 	if (len - i >= outsize - outpos) {
 	    outsize += 1 + ((len - i) - (outsize - outpos));
-	    outtmp = (char *) realloc(out, outsize);
+	    outtmp = realloc(out, outsize);
 	    if (outtmp == NULL) {
-		free(ucs);
-		free(out);
-		return NULL;
+		retval = ENOMEM;
+		goto cleanup;
 	    }
 	    out = outtmp;
 	}
@@ -295,11 +292,19 @@
 	p = ucs + 1;
     }
 
+cleanup:
     free(ucs);
+    free(ucsout);
+    if (retval) {
+	free(out);
+	free(newdata);
+	return retval;
+    }
     out[outpos] = '\0';
     newdata->data = out;
     newdata->length = outpos;
-    return newdata;
+    *newdataptr = newdata;
+    return 0;
 }
 
 /* compare UTF8-strings, optionally ignore casing */




More information about the cvs-krb5 mailing list