static void zend_accel_blacklist_update_regexp(zend_blacklist *blacklist)
{
	int i, end=0, j, rlen=6, clen, reg_err;
	char *regexp;
	zend_regexp_list **regexp_list_it, *it;

	if (blacklist->pos == 0) {
		/* we have no blacklist to talk about */
		return;
	}

	regexp_list_it = &(blacklist->regexp_list);
	for (i=0; i<blacklist->pos; i++) {
		rlen += blacklist->entries[i].path_length*2+2;

		/* don't create a regexp buffer bigger than 12K)*/
		if((i+1 == blacklist->pos) || ((rlen+blacklist->entries[i+1].path_length*2+2)>(12*1024) ) ) {
			regexp = (char *)malloc(rlen);
			if (!regexp) {
				zend_accel_error(ACCEL_LOG_ERROR, "malloc() failed\n");
				return;
			}
			regexp[0] = '^';
			regexp[1] = '(';

			clen=2;
			for (j=end; j<=i ;j++) {

				int c;
				if (j!=end) {
					regexp[clen++] = '|';
				}
				/* copy mangled filename */
				for(c=0; c<blacklist->entries[j].path_length; c++) {
					if(strchr("^.[]$()|*+?{}\\", blacklist->entries[j].path[c])) {
						regexp[clen++] = '\\';
					}
					regexp[clen++] = blacklist->entries[j].path[c];
				}
			}
			regexp[clen++] = ')';
			regexp[clen] = '\0';

			it = (zend_regexp_list*)malloc(sizeof(zend_regexp_list));
			if (!it) {
				zend_accel_error(ACCEL_LOG_ERROR, "malloc() failed\n");
				return;
			}
			it->next = NULL;

			if ((reg_err = regcomp(&it->comp_regex, regexp, REGEX_MODE)) != 0) {
				blacklist_report_regexp_error(&it->comp_regex, reg_err);
			}
			/* prepare for the next iteration */
			free(regexp);
			end = i+1;
			rlen = 6;
			*regexp_list_it = it;
			regexp_list_it = &it->next;
		}
	}
}
예제 #2
0
static void zend_accel_blacklist_update_regexp(zend_blacklist *blacklist)
{
	int i, reg_err;
	zend_regexp_list **regexp_list_it, *it;
	char regexp[12*1024], *p, *end, *c, *backtrack = NULL;

	if (blacklist->pos == 0) {
		/* we have no blacklist to talk about */
		return;
	}

	regexp_list_it = &(blacklist->regexp_list);

	regexp[0] = '^';
	regexp[1] = '(';
	p = regexp + 2;
	end = regexp + sizeof(regexp) - sizeof("[^\\\\]*)\0");

	for (i = 0; i < blacklist->pos; ) {
		c = blacklist->entries[i].path;
		if (p + blacklist->entries[i].path_length < end) {
			while (*c && p < end) {
				switch (*c) {
					case '?':
						c++;
#ifdef ZEND_WIN32
				 		p[0] = '[';			/* * => [^\\] on Win32 */
					 	p[1] = '^';
					 	p[2] = '\\';
					 	p[3] = '\\';
					 	p[4] = ']';
						p += 5;
#else
					 	p[0] = '[';			/* * => [^/] on *nix */
					 	p[1] = '^';
					 	p[2] = '/';
					 	p[3] = ']';
						p += 4;
#endif
						break;
					case '*':
						c++;
						if (*c == '*') {
							c++;
						 	p[0] = '.';			/* ** => .* */
							p[1] = '*';
							p += 2;
						} else {
#ifdef ZEND_WIN32
						 	p[0] = '[';			/* * => [^\\]* on Win32 */
						 	p[1] = '^';
						 	p[2] = '\\';
						 	p[3] = '\\';
						 	p[4] = ']';
						 	p[5] = '*';
							p += 6;
#else
						 	p[0] = '[';			/* * => [^/]* on *nix */
						 	p[1] = '^';
						 	p[2] = '/';
						 	p[3] = ']';
						 	p[4] = '*';
							p += 5;
#endif
						}
						break;
					case '^':
					case '.':
					case '[':
					case ']':
					case '$':
					case '(':
					case ')':
					case '|':
					case '+':
					case '{':
					case '}':
					case '\\':
						*p++ = '\\';
						/* break missing intentionally */
					default:
						*p++ = *c++;
				}
			}
		}

		if (*c || i == blacklist->pos - 1) {
			if (*c) {
				if (!backtrack) {
					zend_accel_error(ACCEL_LOG_ERROR, "Too long blacklist entry\n");
				}
				p = backtrack;
			} else {
				i++;
			}
			*p++ = ')';
			*p++ = '\0';

			it = (zend_regexp_list*)malloc(sizeof(zend_regexp_list));
			if (!it) {
				zend_accel_error(ACCEL_LOG_ERROR, "malloc() failed\n");
				return;
			}
			it->next = NULL;

			if ((reg_err = regcomp(&it->comp_regex, regexp, REGEX_MODE)) != 0) {
				blacklist_report_regexp_error(&it->comp_regex, reg_err);
			}
			/* prepare for the next iteration */
			p = regexp + 2;
			*regexp_list_it = it;
			regexp_list_it = &it->next;
		} else {
			backtrack = p;
			*p++ = '|';
			i++;
		}
	}
}