dgaudet 98/03/13 20:52:52
Modified: src/main util.c
Log:
escape_shell_cmd was O(n^2), fix that.
tweak os_escape_path and escape_path_segment
remove some old code that was #if 0
Revision Changes Path
1.101 +45 -90 apache-1.3/src/main/util.c
Index: util.c
===================================================================
RCS file: /export/home/cvs/apache-1.3/src/main/util.c,v
retrieving revision 1.100
retrieving revision 1.101
diff -u -r1.100 -r1.101
--- util.c 1998/03/14 02:43:46 1.100
+++ util.c 1998/03/14 04:52:51 1.101
@@ -84,7 +84,8 @@
static unsigned char test_char_table[256];
-#define TEST_CHAR(c, f) (test_char_table[((unsigned char)(c)) & 0xff] &
(f))
+/* we assume the folks using this ensure the char < 256 */
+#define TEST_CHAR(c, f) (test_char_table[(unsigned)(c)] & (f))
/* XXX: this should be compile-time initialized so that test_char_table can
* live in read-only memory and not require backing store across fork().
@@ -691,32 +692,6 @@
return res;
}
-#ifdef UNDEF
-/* this function is dangerous, and superceded by getword_white, so don't use
it
- */
-void cfg_getword(char *word, char *line)
-{
- int x = 0, y;
-
- for (x = 0; line[x] && isspace(line[x]); x++);
- y = 0;
- while (1) {
- if (!(word[y] = line[x]))
- break;
- if (isspace(line[x]))
- if ((!x) || (line[x - 1] != '\\'))
- break;
- if (line[x] != '\\')
- ++y;
- ++x;
- }
- word[y] = '\0';
- while (line[x] && isspace(line[x]))
- ++x;
- for (y = 0; (line[y] = line[x]); ++x, ++y);
-}
-#endif
-
/* Open a configfile_t as FILE, return open configfile_t struct pointer */
API_EXPORT(configfile_t *) pcfg_openfile(pool *p, const char *name)
@@ -980,8 +955,7 @@
}
tok_len = ptr - tok_start;
- token = palloc(p, tok_len + 1);
- ap_cpystrn(token, tok_start, tok_len + 1);
+ token = pstrndup(p, tok_start, tok_len);
/* Advance accept_line pointer to the next non-white byte */
@@ -1048,31 +1022,28 @@
API_EXPORT(char *) escape_shell_cmd(pool *p, const char *s)
{
- register int x, y, l;
char *cmd;
+ char *d;
- l = strlen(s);
- cmd = palloc(p, 2 * l + 1); /* Be safe */
- strcpy(cmd, s);
-
- for (x = 0; cmd[x]; x++) {
+ cmd = palloc(p, 2 * strlen(s) + 1); /* Be safe */
+ d = cmd;
+ for (; *s; ++s) {
#if defined(__EMX__) || defined(WIN32)
/* Don't allow '&' in parameters under OS/2. */
/* This can be used to send commands to the shell. */
- if (cmd[x] == '&') {
- cmd[x] = ' ';
+ if (*s == '&') {
+ *d++ = ' ';
+ continue;
}
#endif
- if (TEST_CHAR(cmd[x], T_ESCAPE_SHELL_CMD)) {
- for (y = l + 1; y > x; y--)
- cmd[y] = cmd[y - 1];
- l++; /* length has been increased */
- cmd[x] = '\\';
- x++; /* skip the character */
+ if (TEST_CHAR(*s, T_ESCAPE_SHELL_CMD)) {
+ *d++ = '\\';
}
+ *d++ = *s;
}
+ *d = '\0';
return cmd;
}
@@ -1170,7 +1141,15 @@
}
}
-#define c2x(what,where) sprintf(where,"%%%02x",(unsigned char)what)
+static const char c2x_table[] = "0123456789abcdef";
+
+static ap_inline char *c2x(unsigned char what, char *where)
+{
+ *where++ = '%';
+ *where++ = c2x_table[what >> 4];
+ *where++ = c2x_table[what & 0xf];
+ return where;
+}
/*
* escape_path_segment() escapes a path segment, as defined in RFC 1808. This
@@ -1189,46 +1168,50 @@
API_EXPORT(char *) escape_path_segment(pool *p, const char *segment)
{
- register int x, y;
char *copy = palloc(p, 3 * strlen(segment) + 1);
+ const unsigned char *s = (const unsigned char *)segment;
+ unsigned char *d = (unsigned char *)copy;
+ unsigned c;
- for (x = 0, y = 0; segment[x]; x++, y++) {
- char c = segment[x];
+ while ((c = *s)) {
if (TEST_CHAR(c, T_ESCAPE_PATH_SEGMENT)) {
- c2x(c, ©[y]);
- y += 2;
+ d = c2x(c, d);
}
- else
- copy[y] = c;
+ else {
+ *d++ = c;
+ }
+ ++s;
}
- copy[y] = '\0';
+ *d = '\0';
return copy;
}
API_EXPORT(char *) os_escape_path(pool *p, const char *path, int partial)
{
char *copy = palloc(p, 3 * strlen(path) + 3);
- char *s = copy;
+ const unsigned char *s = (const unsigned char *)path;
+ unsigned char *d = (unsigned char *)copy;
+ unsigned c;
if (!partial) {
char *colon = strchr(path, ':');
char *slash = strchr(path, '/');
if (colon && (!slash || colon < slash)) {
- *s++ = '.';
- *s++ = '/';
+ *d++ = '.';
+ *d++ = '/';
}
}
- for (; *path; ++path) {
- char c = *path;
+ while ((c = *s)) {
if (TEST_CHAR(c, T_OS_ESCAPE_PATH)) {
- c2x(c, s);
- s += 3;
+ d = c2x(c, d);
}
- else
- *s++ = c;
+ else {
+ *d++ = c;
+ }
+ ++s;
}
- *s = '\0';
+ *d = '\0';
return copy;
}
@@ -1507,34 +1490,6 @@
#endif
}
-#if 0
-int get_portnum(int sd)
-{
- struct sockaddr addr;
- int len;
-
- len = sizeof(struct sockaddr);
- if (getsockname(sd, &addr, &len) < 0)
- return -1;
- return ntohs(((struct sockaddr_in *) &addr)->sin_port);
-}
-
-struct in_addr get_local_addr(int sd)
-{
- struct sockaddr addr;
- int len;
-
- len = sizeof(struct sockaddr);
- if (getsockname(sd, &addr, &len) < 0) {
- perror("getsockname");
- fprintf(stderr, "Can't get local host address!\n");
- exit(1);
- }
-
- return ((struct sockaddr_in *) &addr)->sin_addr;
-}
-
-#endif
/*
* Parses a host of the form <address>[:port]