Reduce number of reallocs in unparse_name.

git-svn-id: svn://svn.h5l.se/heimdal/trunk/heimdal@3768 ec53bebd-3082-4978-b11e-865c3cabbd6b
This commit is contained in:
Johan Danielsson
1997-11-03 19:33:50 +00:00
parent 21772f8038
commit 0311068542

View File

@@ -148,76 +148,79 @@ krb5_parse_name(krb5_context context,
return 0; return 0;
} }
static const char quotable_chars[] = "\n\t\b\\/@";
static const char replace_chars[] = "ntb\\/@";
#define add_char(BASE, INDEX, LEN, C) do { if((INDEX) < (LEN)) (BASE)[(INDEX)++] = (C); }while(0);
static size_t static size_t
quote_string(char *s, char **out) quote_string(const char *s, char *out, size_t index, size_t len)
{ {
size_t len; const char *p, *q;
char *p; for(p = s; *p && index < len; p++){
char *tmp; if((q = strchr(quotable_chars, *p))){
char c = 0; add_char(out, index, len, '\\');
tmp = *out; add_char(out, index, len, replace_chars[q - quotable_chars]);
if(tmp) }else
len = strlen(tmp); add_char(out, index, len, *p);
else
len = 0;
for(p = s; *p; p++){
if(*p == '\n')
c = 'n';
else if(*p == '\t')
c = 't';
else if(*p == '\b')
c = 'b';
else if(*p == '\0')
c = '0';
else if(*p == '/')
c='/';
else if(*p == '@')
c = '@';
if(c){
tmp = realloc(tmp, len + 2);
tmp[len] = '\\';
tmp[len + 1] = c;
len += 2;
c = 0;
}else{
tmp = realloc(tmp, len + 1);
tmp[len] = *p;
len++;
} }
} if(index < len)
tmp = realloc(tmp, len + 1); out[index] = '\0';
tmp[len] = 0; return index;
*out = tmp;
return len;
} }
krb5_error_code
krb5_unparse_name_fixed(krb5_context context,
krb5_principal principal,
char *name,
size_t len)
{
size_t index = 0;
int i;
for(i = 0; i < princ_num_comp(principal); i++){
if(i)
add_char(name, index, len, '/');
index = quote_string(princ_ncomp(principal, i), name, index, len);
}
add_char(name, index, len, '@');
index = quote_string(princ_realm(principal), name, index, len);
if(index == len)
return ENOMEM; /* XXX */
return 0;
}
krb5_error_code krb5_error_code
krb5_unparse_name(krb5_context context, krb5_unparse_name(krb5_context context,
krb5_principal principal, krb5_principal principal,
char **name) char **name)
{ {
size_t len; size_t len = 0, plen;
char *s;
int i; int i;
int ncomp = princ_num_comp(principal); krb5_error_code ret;
s = NULL; /* count length */
for (i = 0; i < ncomp; i++){ plen = strlen(princ_realm(principal));
if(i){ if(strcspn(princ_realm(principal), quotable_chars) == plen)
s = realloc(s, len + 2); len += plen;
s[len] = '/'; else
s[len + 1] = 0; len += 2*plen;
len++;
for(i = 0; i < princ_num_comp(principal); i++){
plen = strlen(princ_ncomp(principal, i));
if(strcspn(princ_ncomp(principal, i), quotable_chars) == plen)
len += plen;
else
len += 2*plen;
len++;
} }
len = quote_string(princ_ncomp(principal, i), &s); *name = malloc(len);
if(*name == NULL)
return ENOMEM;
ret = krb5_unparse_name_fixed(context, principal, *name, len);
if(ret)
free(*name);
return ret;
} }
s = realloc(s, len + 2);
s[len] = '@';
s[len + 1] = 0;
len = quote_string(princ_realm(principal), &s);
*name = s;
return 0;
}
#if 0 /* not implemented */ #if 0 /* not implemented */