--- libaitwww/src/tools.c 2012/08/06 11:26:23 1.3.2.2 +++ libaitwww/src/tools.c 2012/08/06 12:02:05 1.3.2.3 @@ -3,7 +3,7 @@ * by Michael Pounov * * $Author: misho $ -* $Id: tools.c,v 1.3.2.2 2012/08/06 11:26:23 misho Exp $ +* $Id: tools.c,v 1.3.2.3 2012/08/06 12:02:05 misho Exp $ * ************************************************************************** The ELWIX and AITNET software is distributed under the following @@ -182,19 +182,31 @@ www_unescape(char * __restrict str) /* * www_undot() - Undotted and clean WWW query filename * - * @fname = query filename - * @fnlen = filename length - * return: -1 error, 0 not valid filename or >0 validated filename length + * @pname = query filename + * return: =NULL error or !=NULL allocated valid filename, after use you must call io_freeVar() */ -int -www_undot(const char * __restrict fname, int fnlen) +ait_val_t * +www_undot(const char * __restrict pname) { - char *s, *s2; + char *s, *s2, *fname; int l; + ait_val_t *v; - if (!fname || !fnlen) - return -1; + if (!pname) + return NULL; + /* check for valid query filename */ + if (*pname != '/') + return NULL; + v = io_allocVar(); + if (!v) { + www_SetErr(io_GetErrno(), "%s", io_GetError()); + return NULL; + } else { + AIT_SET_STR(v, pname + 1); + fname = AIT_GET_STR(v); + } + /* collapse / sequences */ if ((s = strstr(fname, "//"))) { s2 = s + 1; @@ -204,14 +216,14 @@ www_undot(const char * __restrict fname, int fnlen) /* escaped ./ and /./ sequences */ while (!strncmp(fname, "./", 2)) - memmove((void*) fname, fname + 2, strlen(fname + 1)); + memmove(fname, fname + 2, strlen(fname + 1)); while ((s = strstr(fname, "/./"))) memmove(s, s + 2, strlen(s + 1)); /* alternate between removing leading ../ and removing xxx/../ */ while (42) { while (!strncmp(fname, "../", 3)) - memmove((void*) fname, fname + 3, strlen(fname + 2)); + memmove(fname, fname + 3, strlen(fname + 2)); if (!(s = strstr(fname, "/../"))) break; for (s2 = s - 1; s2 >= fname && *s2 != '/'; --s2); @@ -220,7 +232,7 @@ www_undot(const char * __restrict fname, int fnlen) /* elide any /.. at the end */ while ((l = strlen(fname)) > 3 && - !strcmp((s = (char*) fname + l - 3), "/..")) { + !strcmp((s = fname + l - 3), "/..")) { for (s2 = s - 1; s2 >= fname && *s2 != '/'; --s2); if (s2 < fname) break; @@ -228,13 +240,18 @@ www_undot(const char * __restrict fname, int fnlen) } /* if filename is empry add current dir */ - if (!*fname) - strlcpy((char*) fname, "./", fnlen); + if (!*fname) { + AIT_FREE_VAL(v); + AIT_SET_STR(v, "./"); + fname = AIT_GET_STR(v); + } /* check for valid filename */ if (*fname == '/' || (fname[0] == '.' && fname[1] == '.' && - (!fname[2] || fname[2] == '/'))) - return 0; + (!fname[2] || fname[2] == '/'))) { + io_freeVar(&v); + return NULL; + } - return strlen(fname); + return v; }