Browse Source

[core] data_config_pcre_compile,exec()

collect PCRE usage related to config processing
personal/stbuehler/fix-fdevent
Glenn Strauss 4 years ago
parent
commit
e8c1efd5df
  1. 1
      src/CMakeLists.txt
  2. 2
      src/Makefile.am
  3. 20
      src/configfile-glue.c
  4. 4
      src/configfile.h
  5. 43
      src/configparser.y
  6. 60
      src/data_config.c
  7. 1
      src/meson.build

1
src/CMakeLists.txt

@ -662,6 +662,7 @@ add_executable(test_configfile
test_configfile.c
buffer.c
array.c
data_config.c
data_string.c
keyvalue.c
vector.c

2
src/Makefile.am

@ -520,7 +520,7 @@ test_buffer_LDADD = $(LIBUNWIND_LIBS)
test_base64_SOURCES = test_base64.c base64.c buffer.c
test_base64_LDADD = $(LIBUNWIND_LIBS)
test_configfile_SOURCES = test_configfile.c buffer.c array.c data_string.c keyvalue.c vector.c log.c sock_addr.c
test_configfile_SOURCES = test_configfile.c buffer.c array.c data_config.c data_string.c keyvalue.c vector.c log.c sock_addr.c
test_configfile_LDADD = $(PCRE_LIB) $(LIBUNWIND_LIBS)
noinst_HEADERS = $(hdr)

20
src/configfile-glue.c

@ -12,10 +12,6 @@
#include <string.h>
#include <stdlib.h>
#ifdef HAVE_PCRE_H
#include <pcre.h>
#endif
/**
* like all glue code this file contains functions which
* are the external interface of lighttpd. The functions
@ -480,29 +476,15 @@ static cond_result_t config_check_cond_nocache(server *srv, connection *con, dat
} else {
return (dc->cond == CONFIG_COND_EQ) ? COND_RESULT_FALSE : COND_RESULT_TRUE;
}
break;
#ifdef HAVE_PCRE_H
case CONFIG_COND_NOMATCH:
case CONFIG_COND_MATCH: {
int n;
#ifndef elementsof
#define elementsof(x) (sizeof(x) / sizeof(x[0]))
#endif
n = pcre_exec(dc->regex, dc->regex_study, CONST_BUF_LEN(l), 0, 0,
cache->matches, elementsof(cache->matches));
cache->patterncount = n;
if (n > 0) {
cache->comp_value = l;
if (data_config_pcre_exec(dc, cache, l) > 0) {
return (dc->cond == CONFIG_COND_MATCH) ? COND_RESULT_TRUE : COND_RESULT_FALSE;
} else {
/* cache is already cleared */
return (dc->cond == CONFIG_COND_MATCH) ? COND_RESULT_FALSE : COND_RESULT_TRUE;
}
break;
}
#endif
default:
/* no way */
break;

4
src/configfile.h

@ -79,7 +79,11 @@ struct data_config {
#endif
};
struct cond_cache_t; /* declaration */
data_config *data_config_init(void);
int data_config_pcre_compile(data_config *dc);
int data_config_pcre_exec(data_config *dc, struct cond_cache_t *cache, buffer *b);
typedef struct {
server *srv;

43
src/configparser.y

@ -12,13 +12,10 @@
#include <ctype.h>
#include <errno.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#ifdef HAVE_PCRE_H
#include <pcre.h>
#endif
static void configparser_push(config_t *ctx, data_config *dc, int isnew) {
if (isnew) {
dc->context_ndx = ctx->all_configs->used;
@ -694,49 +691,17 @@ context ::= DOLLAR SRVVARNAME(B) LBRACKET stringop(C) RBRACKET cond(E) expressio
}
}
dc->string = buffer_init_buffer(rvalue);
if (ctx->ok) switch(E) {
case CONFIG_COND_NE:
case CONFIG_COND_EQ:
dc->string = buffer_init_buffer(rvalue);
break;
case CONFIG_COND_NOMATCH:
case CONFIG_COND_MATCH: {
#ifdef HAVE_PCRE_H
const char *errptr;
int erroff, captures;
if (NULL == (dc->regex =
pcre_compile(rvalue->ptr, 0, &errptr, &erroff, NULL))) {
dc->string = buffer_init_string(errptr);
dc->cond = CONFIG_COND_UNSET;
fprintf(stderr, "parsing regex failed: %s -> %s at offset %d\n",
rvalue->ptr, errptr, erroff);
if (!data_config_pcre_compile(dc)) {
ctx->ok = 0;
} else if (NULL == (dc->regex_study =
pcre_study(dc->regex, 0, &errptr)) &&
errptr != NULL) {
fprintf(stderr, "studying regex failed: %s -> %s\n",
rvalue->ptr, errptr);
ctx->ok = 0;
} else if (0 != (pcre_fullinfo(dc->regex, dc->regex_study, PCRE_INFO_CAPTURECOUNT, &captures))) {
fprintf(stderr, "getting capture count for regex failed: %s\n",
rvalue->ptr);
ctx->ok = 0;
} else if (captures > 9) {
fprintf(stderr, "Too many captures in regex, use (?:...) instead of (...): %s\n",
rvalue->ptr);
ctx->ok = 0;
} else {
dc->string = buffer_init_buffer(rvalue);
}
#else
fprintf(stderr, "can't handle '$%s[%s] =~ ...' as you compiled without pcre support. \n"
"(perhaps just a missing pcre-devel package ?) \n",
B->ptr, C->ptr);
ctx->ok = 0;
#endif
break;
}

60
src/data_config.c

@ -1,5 +1,6 @@
#include "first.h"
#include "base.h" /* (cond_cache_t) */
#include "array.h"
#include "configfile.h"
@ -153,3 +154,62 @@ data_config *data_config_init(void) {
return ds;
}
int data_config_pcre_compile(data_config *dc) {
#ifdef HAVE_PCRE_H
/* (use fprintf() on error, as this is called from configparser.y) */
const char *errptr;
int erroff, captures;
if (dc->regex) pcre_free(dc->regex);
if (dc->regex_study) pcre_free(dc->regex_study);
dc->regex = pcre_compile(dc->string->ptr, 0, &errptr, &erroff, NULL);
if (NULL == dc->regex) {
fprintf(stderr, "parsing regex failed: %s -> %s at offset %d\n",
dc->string->ptr, errptr, erroff);
return 0;
}
dc->regex_study = pcre_study(dc->regex, 0, &errptr);
if (NULL == dc->regex_study && errptr != NULL) {
fprintf(stderr, "studying regex failed: %s -> %s\n",
dc->string->ptr, errptr);
return 0;
}
erroff = pcre_fullinfo(dc->regex, dc->regex_study, PCRE_INFO_CAPTURECOUNT,
&captures);
if (0 != erroff) {
fprintf(stderr, "getting capture count for regex failed: %s\n",
dc->string->ptr);
return 0;
} else if (captures > 9) {
fprintf(stderr, "Too many captures in regex, use (?:...) instead of (...): %s\n",
dc->string->ptr);
return 0;
}
return 1;
#else
fprintf(stderr, "can't handle '$%s[%s] =~ ...' as you compiled without pcre support. \n"
"(perhaps just a missing pcre-devel package ?) \n",
dc->comp_key->ptr, dc->comp_tag->ptr);
return 0;
#endif
}
int data_config_pcre_exec(data_config *dc, cond_cache_t *cache, buffer *b) {
#ifdef HAVE_PCRE_H
#ifndef elementsof
#define elementsof(x) (sizeof(x) / sizeof(x[0]))
#endif
cache->patterncount =
pcre_exec(dc->regex, dc->regex_study, CONST_BUF_LEN(b), 0, 0,
cache->matches, elementsof(cache->matches));
if (cache->patterncount > 0)
cache->comp_value = b; /* holds pointer to b (!) for pattern subst */
return cache->patterncount;
#else
return 0;
#endif
}

1
src/meson.build

@ -703,6 +703,7 @@ test('test_configfile', executable('test_configfile',
'test_configfile.c',
'buffer.c',
'array.c',
'data_config.c',
'data_string.c',
'keyvalue.c',
'vector.c',

Loading…
Cancel
Save