📄 mod_include.c
字号:
r->connection->bucket_alloc); APR_BUCKET_INSERT_BEFORE(head_ptr, tmp_buck); if (*inserted_head == NULL) { *inserted_head = tmp_buck; } } else { CREATE_ERROR_BUCKET(ctx, tmp_buck, head_ptr, *inserted_head); return 1; } } } } return 0;}static int re_check(request_rec *r, include_ctx_t *ctx, char *string, char *rexp){ regex_t *compiled; const apr_size_t nres = sizeof(*ctx->re_result) / sizeof(regmatch_t); int regex_error; compiled = ap_pregcomp(r->pool, rexp, REG_EXTENDED | REG_NOSUB); if (compiled == NULL) { ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, "unable to compile pattern \"%s\"", rexp); return -1; } if (!ctx->re_result) { ctx->re_result = apr_pcalloc(r->pool, sizeof(*ctx->re_result)); } ctx->re_string = string; regex_error = ap_regexec(compiled, string, nres, *ctx->re_result, 0); ap_pregfree(r->pool, compiled); return (!regex_error);}enum token_type { token_string, token_re, token_and, token_or, token_not, token_eq, token_ne, token_rbrace, token_lbrace, token_group, token_ge, token_le, token_gt, token_lt};struct token { enum token_type type; char* value;};static const char *get_ptoken(request_rec *r, const char *string, struct token *token, int *unmatched){ char ch; int next = 0; char qs = 0; int tkn_fnd = 0; token->value = NULL; /* Skip leading white space */ if (string == (char *) NULL) { return (char *) NULL; } while ((ch = *string++)) { if (!apr_isspace(ch)) { break; } } if (ch == '\0') { return (char *) NULL; } token->type = token_string; /* the default type */ switch (ch) { case '(': token->type = token_lbrace; return (string); case ')': token->type = token_rbrace; return (string); case '=': token->type = token_eq; return (string); case '!': if (*string == '=') { token->type = token_ne; return (string + 1); } else { token->type = token_not; return (string); } case '\'': /* already token->type == token_string */ qs = '\''; break; case '/': token->type = token_re; qs = '/'; break; case '|': if (*string == '|') { token->type = token_or; return (string + 1); } break; case '&': if (*string == '&') { token->type = token_and; return (string + 1); } break; case '>': if (*string == '=') { token->type = token_ge; return (string + 1); } else { token->type = token_gt; return (string); } case '<': if (*string == '=') { token->type = token_le; return (string + 1); } else { token->type = token_lt; return (string); } default: /* already token->type == token_string */ break; } /* We should only be here if we are in a string */ token->value = apr_palloc(r->pool, strlen(string) + 2); /* 2 for ch plus trailing null */ if (!qs) { --string; } /* * I used the ++string throughout this section so that string * ends up pointing to the next token and I can just return it */ for (ch = *string; ((ch != '\0') && (!tkn_fnd)); ch = *++string) { if (ch == '\\') { if ((ch = *++string) == '\0') { tkn_fnd = 1; } else { token->value[next++] = ch; } } else { if (!qs) { if (apr_isspace(ch)) { tkn_fnd = 1; } else { switch (ch) { case '(': case ')': case '=': case '!': case '<': case '>': tkn_fnd = 1; break; case '|': if (*(string + 1) == '|') { tkn_fnd = 1; } break; case '&': if (*(string + 1) == '&') { tkn_fnd = 1; } break; } if (!tkn_fnd) { token->value[next++] = ch; } } } else { if (ch == qs) { qs = 0; tkn_fnd = 1; string++; } else { token->value[next++] = ch; } } } if (tkn_fnd) { break; } } /* If qs is still set, we have an unmatched quote */ if (qs) { *unmatched = 1; next = 0; } token->value[next] = '\0'; return (string);}/* there is an implicit assumption here that expr is at most MAX_STRING_LEN-1 * characters long... */static int parse_expr(request_rec *r, include_ctx_t *ctx, const char *expr, int *was_error, int *was_unmatched, char *debug){ struct parse_node { struct parse_node *left, *right, *parent; struct token token; int value, done; } *root, *current, *new; const char *parse; char* buffer; int retval = 0; apr_size_t debug_pos = 0; debug[debug_pos] = '\0'; *was_error = 0; *was_unmatched = 0; if ((parse = expr) == (char *) NULL) { return (0); } root = current = (struct parse_node *) NULL; /* Create Parse Tree */ while (1) { new = (struct parse_node *) apr_palloc(r->pool, sizeof(struct parse_node)); new->parent = new->left = new->right = (struct parse_node *) NULL; new->done = 0; if ((parse = get_ptoken(r, parse, &new->token, was_unmatched)) == (char *) NULL) { break; } switch (new->token.type) { case token_string:#ifdef DEBUG_INCLUDE debug_pos += sprintf (&debug[debug_pos], " Token: string (%s)\n", new->token.value);#endif if (current == (struct parse_node *) NULL) { root = current = new; break; } switch (current->token.type) { case token_string: current->token.value = apr_pstrcat(r->pool, current->token.value, current->token.value[0] ? " " : "", new->token.value, NULL); break; case token_eq: case token_ne: case token_and: case token_or: case token_lbrace: case token_not: case token_ge: case token_gt: case token_le: case token_lt: new->parent = current; current = current->right = new; break; default: ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, "Invalid expression \"%s\" in file %s", expr, r->filename); *was_error = 1; return retval; } break; case token_re:#ifdef DEBUG_INCLUDE debug_pos += sprintf (&debug[debug_pos], " Token: regex (%s)\n", new->token.value);#endif if (current == (struct parse_node *) NULL) { root = current = new; break; } switch (current->token.type) { case token_eq: case token_ne: case token_and: case token_or: case token_lbrace: case token_not: new->parent = current; current = current->right = new; break; default: ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, "Invalid expression \"%s\" in file %s", expr, r->filename); *was_error = 1; return retval; } break; case token_and: case token_or:#ifdef DEBUG_INCLUDE memcpy (&debug[debug_pos], " Token: and/or\n", sizeof (" Token: and/or\n")); debug_pos += sizeof (" Token: and/or\n");#endif if (current == (struct parse_node *) NULL) { ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, "Invalid expression \"%s\" in file %s", expr, r->filename); *was_error = 1; return retval; } /* Percolate upwards */ while (current != (struct parse_node *) NULL) { switch (current->token.type) { case token_string: case token_re: case token_group: case token_not: case token_eq: case token_ne: case token_and: case token_or: case token_ge: case token_gt: case token_le: case token_lt: current = current->parent; continue; case token_lbrace: break; default: ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, "Invalid expression \"%s\" in file %s", expr, r->filename); *was_error = 1; return retval; } break; } if (current == (struct parse_node *) NULL) { new->left = root; new->left->parent = new; new->parent = (struct parse_node *) NULL; root = new; } else { new->left = current->right; new->left->parent = new; current->right = new; new->parent = current; } current = new; break; case token_not:#ifdef DEBUG_INCLUDE memcpy(&debug[debug_pos], " Token: not\n", sizeof(" Token: not\n")); debug_pos += sizeof(" Token: not\n");#endif if (current == (struct parse_node *) NULL) { root = current = new; break;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -