On 02/26/2009 07:58 PM, Lars Eilebrecht wrote:
> Hi,
>
> the following SSI statements triggers a segfault when QUERY_STRING
> is empty (tested with 2.2.11):
>
> <!--#if expr="$QUERY_STRING = /foobar=([0-9]+)$/" -->
> <!--#set var="foobar" value="$1" -->
> <!--#else -->
> <!--#set var="foobar" value="$1" -->
> <!--#endif -->
>
> I tracked this down to get_include_var() in mod_include.c:
>
> --snip--
> static const char *get_include_var(const char *var, include_ctx_t *ctx)
> {
> const char *val;
> request_rec *r = ctx->intern->r;
>
> if (apr_isdigit(*var) && !var[1]) {
> apr_size_t idx = *var - '0';
> backref_t *re = ctx->intern->re;
>
> /* Handle $0 .. $9 from the last regex evaluated.
> * The choice of returning NULL strings on not-found,
> * v.s. empty strings on an empty match is deliberate.
> */
> if (!re) {
> ap_log_rerror(APLOG_MARK, APLOG_WARNING, 0, r,
> "regex capture $%" APR_SIZE_T_FMT " refers to no regex in %s",
> idx, r->filename);
> return NULL;
> }
> else {
> if (re->nsub < idx || idx >= AP_MAX_REG_MATCH) {
> ap_log_rerror(APLOG_MARK, APLOG_WARNING, 0, r,
> "regex capture $%" APR_SIZE_T_FMT
> " is out of range (last regex was: '%s') in
> %s",
> idx, re->rexp, r->filename);
> return NULL;
> }
>
> if (re->match[idx].rm_so < 0 || re->match[idx].rm_eo < 0) {
> return NULL;
> }
>
> val = apr_pstrmemdup(ctx->dpool, re->source +
> re->match[idx].rm_so,
> re->match[idx].rm_eo - re->match[idx].rm_so);
> }
> }
> else {
> val = apr_table_get(r->subprocess_env, var);
>
> if (val == LAZY_VALUE) {
> val = add_include_vars_lazy(r, var);
> }
> }
>
> return val;
> }
> --snip--
>
> The segfault happens with apr_pstrmemdup(), because
> "re->source + re->match[idx].rm_so" ends up being out of bounds.
>
> So despite the regex not matching, "ctx->intern->re" is actually
> not NULL, but I can't seem to figure out why this is the case.
What are the values of
idx
re->match[idx].rm_so
re->match[idx].rm_eo
re->source
and what is the string re->source is pointing to when the crash happens?
Regards
Rüdiger