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