+/*
+ * Copyright (C) 1996-2014 The Squid Software Foundation and contributors
+ *
+ * Squid software is distributed under GPLv2+ license and includes
+ * contributions from numerous individuals and organizations.
+ * Please see the COPYING and CONTRIBUTORS files for details.
+ */
/*
* -----------------------------------------------------------------------------
#include "squid.h"
#include "util.h"
-#ifdef HAVE_LDAP
+#if HAVE_LDAP
#include "support.h"
struct gdstruct *init_gd(void);
+void free_gd(struct gdstruct *gdsp);
struct gdstruct *
init_gd(void) {
return gdsp;
}
+void
+free_gd(struct gdstruct *gdsp)
+{
+ while (gdsp) {
+ struct gdstruct *gdspn = gdsp->next;
+ xfree(gdsp->group);
+ xfree(gdsp->domain);
+ xfree(gdsp);
+ gdsp = gdspn;
+ }
+}
+
char *utf8dup(struct main_args *margs);
char *
utf8dup(struct main_args *margs)
{
- int c = 0, s;
+ size_t c = 0;
size_t n;
char *src;
- unsigned char *p, *dupp;
+ unsigned char *p;
src = margs->glist;
if (!src)
if ((unsigned char) src[n] > 127)
++c;
if (c != 0) {
+ unsigned char *dupp;
p = (unsigned char *) xmalloc(strlen(src) + c);
dupp = p;
for (n = 0; n < strlen(src); ++n) {
+ unsigned char s;
s = (unsigned char) src[n];
if (s > 127 && s < 192) {
*p = 194;
++p;
*p = s;
- } else if (s > 191 && s < 256) {
+ } else if (s > 191) {
*p = 195;
++p;
*p = s - 64;
char *
hex_utf_char(struct main_args *margs, int flag)
{
- char *up;
- char *upd;
- char *ul;
- int a, n, nl, ival, ichar;
+ int ival, ichar;
int iUTF2, iUTF3, iUTF4;
- if (flag) {
- up = margs->ulist;
- } else {
- up = margs->tlist;
- }
-
+ char *up = (flag ? margs->ulist : margs->tlist);
if (!up)
return NULL;
- upd = strrchr(up, '@');
- if (upd)
- a = upd - up;
- else
- a = strlen(up);
+ char *upd = strrchr(up, '@');
+ size_t a = (upd ? (size_t)(upd - up) : strlen(up) );
- ul = (char *) xmalloc(strlen(up));
- n = 0;
- nl = 0;
+ char *ul = (char *) xmalloc(strlen(up)+1);
+ size_t n = 0;
+ int nl = 0;
iUTF2 = 0;
iUTF3 = 0;
iUTF4 = 0;
- while (n < (int) strlen(up)) {
+ while (n < strlen(up)) {
if (flag && n == a)
break;
if (up[n] == '@') {
ichar = (ival - 48) * 16;
else {
debug((char *) "%s| %s: WARNING: Invalid Hex value %c\n", LogTime(), PROGRAM, ival);
- if (ul)
- xfree(ul);
+ xfree(ul);
return NULL;
}
if (n == a - 1) {
debug((char *) "%s| %s: WARNING: Invalid Hex UTF-8 string %s\n", LogTime(), PROGRAM, up);
- if (ul)
- xfree(ul);
+ xfree(ul);
return NULL;
}
++n;
ichar = ichar + ival - 48;
else {
debug((char *) "%s| %s: WARNING: Invalid Hex value %c\n", LogTime(), PROGRAM, ival);
- if (ul)
- xfree(ul);
+ xfree(ul);
return NULL;
}
if (iUTF2) {
if (iUTF2 == 0xC2 && ichar > 0x7F && ichar < 0xC0) {
iUTF2 = 0;
- ul[nl - 1] = ichar;
+ ul[nl - 1] = (char)ichar;
} else if (iUTF2 == 0xC3 && ichar > 0x7F && ichar < 0xC0) {
iUTF2 = 0;
- ul[nl - 1] = ichar + 64;
+ ul[nl - 1] = (char)(ichar + 64);
} else if (iUTF2 > 0xC3 && iUTF2 < 0xE0 && ichar > 0x7F && ichar < 0xC0) {
iUTF2 = 0;
- ul[nl] = ichar;
+ ul[nl] = (char)ichar;
++nl;
} else {
iUTF2 = 0;
- ul[nl] = ichar;
+ ul[nl] = (char)ichar;
ul[nl + 1] = '\0';
debug((char *) "%s| %s: WARNING: Invalid UTF-8 sequence for Unicode %s\n", LogTime(), PROGRAM, ul);
- if (ul)
- xfree(ul);
+ xfree(ul);
return NULL;
}
} else if (iUTF3) {
if (iUTF3 == 0xE0 && ichar > 0x9F && ichar < 0xC0) {
iUTF3 = 1;
- ul[nl] = ichar;
+ ul[nl] = (char)ichar;
++nl;
} else if (iUTF3 > 0xE0 && iUTF3 < 0xED && ichar > 0x7F && ichar < 0xC0) {
iUTF3 = 2;
- ul[nl] = ichar;
+ ul[nl] = (char)ichar;
++nl;
} else if (iUTF3 == 0xED && ichar > 0x7F && ichar < 0xA0) {
iUTF3 = 3;
- ul[nl] = ichar;
+ ul[nl] = (char)ichar;
++nl;
} else if (iUTF3 > 0xED && iUTF3 < 0xF0 && ichar > 0x7F && ichar < 0xC0) {
iUTF3 = 4;
- ul[nl] = ichar;
+ ul[nl] = (char)ichar;
++nl;
} else if (iUTF3 > 0 && iUTF3 < 5 && ichar > 0x7F && ichar < 0xC0) {
iUTF3 = 0;
- ul[nl] = ichar;
+ ul[nl] = (char)ichar;
++nl;
} else {
iUTF3 = 0;
- ul[nl] = ichar;
+ ul[nl] = (char)ichar;
ul[nl + 1] = '\0';
debug((char *) "%s| %s: WARNING: Invalid UTF-8 sequence for Unicode %s\n", LogTime(), PROGRAM, ul);
- if (ul)
- xfree(ul);
+ xfree(ul);
return NULL;
}
} else if (iUTF4) {
if (iUTF4 == 0xF0 && ichar > 0x8F && ichar < 0xC0) {
iUTF4 = 1;
- ul[nl] = ichar;
+ ul[nl] = (char)ichar;
++nl;
} else if (iUTF4 > 0xF0 && iUTF3 < 0xF4 && ichar > 0x7F && ichar < 0xC0) {
iUTF4 = 2;
- ul[nl] = ichar;
+ ul[nl] = (char)ichar;
++nl;
} else if (iUTF4 == 0xF4 && ichar > 0x7F && ichar < 0x90) {
iUTF4 = 3;
- ul[nl] = ichar;
+ ul[nl] = (char)ichar;
++nl;
} else if (iUTF4 > 0 && iUTF4 < 5 && ichar > 0x7F && ichar < 0xC0) {
if (iUTF4 == 4)
iUTF4 = 0;
else
iUTF4 = 4;
- ul[nl] = ichar;
+ ul[nl] = (char)ichar;
++nl;
} else {
iUTF4 = 0;
- ul[nl] = ichar;
+ ul[nl] = (char)ichar;
ul[nl + 1] = '\0';
debug((char *) "%s| %s: WARNING: Invalid UTF-8 sequence for Unicode %s\n", LogTime(), PROGRAM, ul);
- if (ul)
- xfree(ul);
+ xfree(ul);
return NULL;
}
} else if (ichar < 0x80) {
/* UTF1 */
- ul[nl] = ichar;
+ ul[nl] = (char)ichar;
++nl;
} else if (ichar > 0xC1 && ichar < 0xE0) {
/* UTF2 (Latin) */
iUTF2 = ichar;
- ul[nl] = ichar;
+ ul[nl] = (char)ichar;
++nl;
} else if (ichar > 0xDF && ichar < 0xF0) {
/* UTF3 */
iUTF3 = ichar;
- ul[nl] = ichar;
+ ul[nl] = (char)ichar;
++nl;
} else if (ichar > 0xEF && ichar < 0xF5) {
/* UTF4 */
iUTF4 = ichar;
- ul[nl] = ichar;
+ ul[nl] = (char)ichar;
++nl;
} else {
- ul[nl] = ichar;
+ ul[nl] = (char)ichar;
ul[nl + 1] = '\0';
debug((char *) "%s| %s: WARNING: Invalid UTF-8 sequence for Unicode %s\n", LogTime(), PROGRAM, ul);
- if (ul)
- xfree(ul);
+ xfree(ul);
return NULL;
}
++n;
if (iUTF2 || iUTF3 || iUTF4) {
debug((char *) "%s| %s: INFO: iUTF2: %d iUTF3: %d iUTF4: %d\n", LogTime(), PROGRAM, iUTF2, iUTF3, iUTF4);
debug((char *) "%s| %s: WARNING: Invalid UTF-8 sequence for Unicode %s\n", LogTime(), PROGRAM, ul);
- if (ul)
- xfree(ul);
+ xfree(ul);
return NULL;
}
if (flag && upd)
create_gd(struct main_args *margs)
{
char *gp, *dp;
- char *hp1, *hp2, *up;
char *p;
struct gdstruct *gdsp = NULL, *gdspn = NULL;
/*
*
*
*/
- hp1 = hex_utf_char(margs, 0);
- hp2 = hex_utf_char(margs, 1);
- up = utf8dup(margs);
+ char *hp1 = hex_utf_char(margs, 0);
+ char *hp2 = hex_utf_char(margs, 1);
+ char *up = utf8dup(margs);
+
+ // NP: will point to the start of a temporary assembly buffer used by 'p' and 'gp'
+ // for catenation of the hp1, hp2, and up buffer contents from above.
+ // necessary for xfree() because both p and gp move over the assembly area
+ char *gpbuf = NULL;
+
+ // release the allocated UTF decoding buffers
+#define cleanup() { \
+ xfree(gpbuf); \
+ xfree(hp1); \
+ xfree(hp2); \
+ xfree(up); \
+ free_gd(gdsp); \
+ }
+
p = up;
if (hp1) {
if (hp2) {
if (up) {
- p = (char *) xmalloc(strlen(up) + strlen(hp1) + strlen(hp2) + 2);
+ gpbuf = p = (char *) xmalloc(strlen(up) + strlen(hp1) + strlen(hp2) + 2);
strcpy(p, up);
strcat(p, ":");
strcat(p, hp1);
strcat(p, ":");
strcat(p, hp2);
} else {
- p = (char *) xmalloc(strlen(hp1) + strlen(hp2) + 1);
+ gpbuf = p = (char *) xmalloc(strlen(hp1) + strlen(hp2) + 1);
strcpy(p, hp1);
strcat(p, ":");
strcat(p, hp2);
}
} else {
if (up) {
- p = (char *) xmalloc(strlen(up) + strlen(hp1) + 1);
+ gpbuf = p = (char *) xmalloc(strlen(up) + strlen(hp1) + 1);
strcpy(p, up);
strcat(p, ":");
strcat(p, hp1);
} else {
if (hp2) {
if (up) {
- p = (char *) xmalloc(strlen(up) + strlen(hp2) + 1);
+ gpbuf = p = (char *) xmalloc(strlen(up) + strlen(hp2) + 1);
strcpy(p, up);
strcat(p, ":");
strcat(p, hp2);
if (!p) {
debug((char *) "%s| %s: ERROR: No groups defined.\n", LogTime(), PROGRAM);
+ cleanup();
return (1);
}
while (*p) { /* loop over group list */
if (*p == '@') { /* end of group name - start of domain name */
if (p == gp) { /* empty group name not allowed */
debug((char *) "%s| %s: ERROR: No group defined for domain %s\n", LogTime(), PROGRAM, p);
+ cleanup();
return (1);
}
+ if (dp) { /* end of domain name - twice */
+ debug((char *) "%s| %s: @ is not allowed in group name %s@%s\n",LogTime(), PROGRAM,gp,dp);
+ cleanup();
+ return(1);
+ }
*p = '\0';
++p;
gdsp = init_gd();
- gdsp->group = gp;
- if (gdspn) /* Have already an existing structure */
- gdsp->next = gdspn;
+ gdsp->group = xstrdup(gp);
+ gdsp->next = gdspn;
dp = p; /* after @ starts new domain name */
} else if (*p == ':') { /* end of group name or end of domain name */
if (p == gp) { /* empty group name not allowed */
debug((char *) "%s| %s: ERROR: No group defined for domain %s\n", LogTime(), PROGRAM, p);
+ cleanup();
return (1);
}
*p = '\0';
dp = NULL;
} else { /* end of group name and no domain name */
gdsp = init_gd();
- gdsp->group = gp;
- if (gdspn) /* Have already an existing structure */
- gdsp->next = gdspn;
+ gdsp->group = xstrdup(gp);
+ gdsp->next = gdspn;
}
gdspn = gdsp;
gp = p; /* after : starts new group name */
}
if (p == gp) { /* empty group name not allowed */
debug((char *) "%s| %s: ERROR: No group defined for domain %s\n", LogTime(), PROGRAM, p);
+ cleanup();
return (1);
}
if (dp) { /* end of domain name */
gdsp->domain = xstrdup(dp);
} else { /* end of group name and no domain name */
gdsp = init_gd();
- gdsp->group = gp;
+ gdsp->group = xstrdup(gp);
if (gdspn) /* Have already an existing structure */
gdsp->next = gdspn;
}
debug((char *) "%s| %s: INFO: Group %s Domain %s\n", LogTime(), PROGRAM, gdsp->group, gdsp->domain ? gdsp->domain : "NULL");
margs->groups = gdsp;
+ gdsp = NULL; // prevent the cleanup() deallocating it.
+ cleanup();
return (0);
}
#endif