]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
MEDIUM: pattern: The pattern parser no more uses <opaque> and just takes one string.
authorThierry FOURNIER <tfournier@exceliance.fr>
Fri, 24 Jan 2014 09:58:12 +0000 (10:58 +0100)
committerWilly Tarreau <w@1wt.eu>
Mon, 17 Mar 2014 17:06:06 +0000 (18:06 +0100)
After the previous patches, the "pat_parse_strcat()" function disappear,
and the "pat_parse_int()" and "pat_parse_dotted_ver()" functions dont
use anymore the "opaque" argument, and take only one string on his
input.

So, after this patch, each pattern parser no longer use the opaque
variable and take only one string as input. This patch change the
prototype of the pattern parsing functions.

Now, the "char **args" is replaced by a "char *arg", the "int *opaque"
is removed and these functions return 1 in succes case, and 0 if fail.

include/proto/pattern.h
include/types/acl.h
include/types/pattern.h
src/pattern.c
src/proto_http.c

index e5c1b42df6a8801b14024c1c326ee813ace371c1..f48f5ae080832da6fb27897706cc36077496952a 100644 (file)
@@ -68,40 +68,40 @@ enum pat_match_res pattern_exec_match(struct pattern_expr *expr, struct sample *
 
 
 /* ignore the current line */
-int pat_parse_nothing(const char **text, struct pattern *pattern, enum pat_usage usage, int *opaque, char **err);
+int pat_parse_nothing(const char *text, struct pattern *pattern, enum pat_usage usage, char **err);
 
 /* Parse an integer. It is put both in min and max. */
-int pat_parse_int(const char **text, struct pattern *pattern, enum pat_usage usage, int *opaque, char **err);
+int pat_parse_int(const char *text, struct pattern *pattern, enum pat_usage usage, char **err);
 
 /* Parse len like an integer, but specify expected string type */
-int pat_parse_len(const char **text, struct pattern *pattern, enum pat_usage usage, int *opaque, char **err);
+int pat_parse_len(const char *text, struct pattern *pattern, enum pat_usage usage, char **err);
 
 /* Parse an version. It is put both in min and max. */
-int pat_parse_dotted_ver(const char **text, struct pattern *pattern, enum pat_usage usage, int *opaque, char **err);
+int pat_parse_dotted_ver(const char *text, struct pattern *pattern, enum pat_usage usage, char **err);
 
 /* Parse a range of integers delimited by either ':' or '-'. If only one
  * integer is read, it is set as both min and max.
  */
-int pat_parse_range(const char **text, struct pattern *pattern, enum pat_usage usage, int *opaque, char **err);
+int pat_parse_range(const char *text, struct pattern *pattern, enum pat_usage usage, char **err);
 
 /* Parse a string. It is allocated and duplicated. */
-int pat_parse_str(const char **text, struct pattern *pattern, enum pat_usage usage, int *opaque, char **err);
+int pat_parse_str(const char *text, struct pattern *pattern, enum pat_usage usage, char **err);
 
 /* Parse a hexa binary definition. It is allocated and duplicated. */
-int pat_parse_bin(const char **text, struct pattern *pattern, enum pat_usage usage, int *opaque, char **err);
+int pat_parse_bin(const char *text, struct pattern *pattern, enum pat_usage usage, char **err);
 
 /* Parse and concatenate strings into one. It is allocated and duplicated. */
-int pat_parse_strcat(const char **text, struct pattern *pattern, enum pat_usage usage, int *opaque, char **err);
+int pat_parse_strcat(const char *text, struct pattern *pattern, enum pat_usage usage, char **err);
 
 /* Parse a regex. It is allocated. */
-int pat_parse_reg(const char **text, struct pattern *pattern, enum pat_usage usage, int *opaque, char **err);
+int pat_parse_reg(const char *text, struct pattern *pattern, enum pat_usage usage, char **err);
 
 /* Parse an IP address and an optional mask in the form addr[/mask].
  * The addr may either be an IPv4 address or a hostname. The mask
  * may either be a dotted mask or a number of bits. Returns 1 if OK,
  * otherwise 0.
  */
-int pat_parse_ip(const char **text, struct pattern *pattern, enum pat_usage usage, int *opaque, char **err);
+int pat_parse_ip(const char *text, struct pattern *pattern, enum pat_usage usage, char **err);
 
 /* NB: For two strings to be identical, it is required that their lengths match */
 enum pat_match_res pat_match_str(struct sample *smp, struct pattern *pattern);
index afce9393c133ff8def223d0656b13f5648d225dd..74db67b556d3fbee744e770d26941b122c098433 100644 (file)
@@ -92,7 +92,7 @@ struct acl_expr;
 struct acl_keyword {
        const char *kw;
        char *fetch_kw;
-       int (*parse)(const char **text, struct pattern *pattern, enum pat_usage usage, int *opaque, char **err);
+       int (*parse)(const char *text, struct pattern *pattern, enum pat_usage usage, char **err);
        enum pat_match_res (*match)(struct sample *smp, struct pattern *pattern);
        /* must be after the config params */
        struct sample_fetch *smp; /* the sample fetch we depend on */
index 93ee29700fbf0b147aa11ed37e774a36e5d5a8ba..0cdd1ed9fa7f1faf8e28e1b98916ca7d274da8b6 100644 (file)
@@ -159,14 +159,14 @@ struct pattern {
  * are grouped together in order to optimize caching.
  */
 struct pattern_expr {
-       int (*parse)(const char **text, struct pattern *pattern, enum pat_usage usage, int *opaque, char **err);
+       int (*parse)(const char *text, struct pattern *pattern, enum pat_usage usage, char **err);
        enum pat_match_res (*match)(struct sample *smp, struct pattern *pattern);
        struct list patterns;         /* list of acl_patterns */
        struct eb_root pattern_tree;  /* may be used for lookup in large datasets */
 };
 
 extern char *pat_match_names[PAT_MATCH_NUM];
-extern int (*pat_parse_fcts[PAT_MATCH_NUM])(const char **, struct pattern *, enum pat_usage, int *, char **);
+extern int (*pat_parse_fcts[PAT_MATCH_NUM])(const char *, struct pattern *, enum pat_usage, char **);
 extern enum pat_match_res (*pat_match_fcts[PAT_MATCH_NUM])(struct sample *, struct pattern *);
 extern int pat_match_types[PAT_MATCH_NUM];
 
index b6816931607ff689e5a57249fbad1944b14ccbe6..701385185bc398b1f0a297dc4bfd2138d554b9d7 100644 (file)
@@ -40,7 +40,7 @@ char *pat_match_names[PAT_MATCH_NUM] = {
        [PAT_MATCH_REG]   = "reg",
 };
 
-int (*pat_parse_fcts[PAT_MATCH_NUM])(const char **, struct pattern *, enum pat_usage, int *, char **) = {
+int (*pat_parse_fcts[PAT_MATCH_NUM])(const char *, struct pattern *, enum pat_usage, char **) = {
        [PAT_MATCH_FOUND] = pat_parse_nothing,
        [PAT_MATCH_BOOL]  = pat_parse_nothing,
        [PAT_MATCH_INT]   = pat_parse_int,
@@ -163,64 +163,46 @@ static inline unsigned int make_4delim(unsigned char d1, unsigned char d2, unsig
  * These functions are exported and may be used by any other component.
  *
  * The following functions are used for parsing pattern matching
- * input value. The <text> contain a list of word. The last entry
- * must be one NULL character. the <text> contain the string to be
- * parsed. <pattern> must be a preallocated pattern. The pat_parse_*
- * functions fill this structure with the parsed value. <usage> can
- * be PAT_U_COMPILE or PAT_U_LOOKUP. If the value PAT_U_COMPILE is
- * used memory is allocated for filling the pattern. If the value
- * PAT_U_LOOKUP is set, the parser use "trash" or return pointers
- * to the input strings. In both cases, the caller must use the
- * value PAT_U_LOOKUP with caution. <opaque> is used to pass value
- * between two calls to the parser. the interger must ben initilized
- * to 0 (see note below). <err> is filled with an error message built
- * with memprintf() function.
+ * input value. The <text> contain the string to be parsed. <pattern>
+ * must be a preallocated pattern. The pat_parse_* functions fill this
+ * structure with the parsed value. <usage> can be PAT_U_COMPILE or
+ * PAT_U_LOOKUP. If the value PAT_U_COMPILE is used memory is allocated
+ * for filling the pattern. If the value PAT_U_LOOKUP is set, the parser
+ * use "trash" or return pointers to the input strings. In both cases,
+ * the caller must use the value PAT_U_LOOKUP with caution. <err> is
+ * filled with an error message built with memprintf() function.
  *
- * In succes case, the pat_parse_* function return the number of
- * <text> eated. If the function fail, it returns 0 and <err> is
- * filled.
- *
- * NOTE: <opaque>iIt is used with integer range parser. The following 
- * configuration line is processed with this method:
- *
- *    acl ... -m int eq 10 20
- *
- * The first call to the parser eat 2 elements: "eq" and "10". The
- * pattern is filled with "eq 10" content. The <opaque> contain
- * coded value value that represent "eq".
- *
- * The second call to the parser just eat 1 element: "20". The opaque
- * contain the value of the operator. The parser returns pattern filled
- * with "eq 20".
+ * In succes case, the pat_parse_* function return 1. If the function
+ * fail, it returns 0 and <err> is filled.
  *
  */
 
 /* ignore the current line */
-int pat_parse_nothing(const char **text, struct pattern *pattern, enum pat_usage usage, int *opaque, char **err)
+int pat_parse_nothing(const char *text, struct pattern *pattern, enum pat_usage usage, char **err)
 {
        return 1;
 }
 
 /* Parse a string. It is allocated and duplicated. */
-int pat_parse_str(const char **text, struct pattern *pattern, enum pat_usage usage, int *opaque, char **err)
+int pat_parse_str(const char *text, struct pattern *pattern, enum pat_usage usage, char **err)
 {
        pattern->type = SMP_T_CSTR;
        pattern->expect_type = SMP_T_CSTR;
        if (usage == PAT_U_COMPILE) {
-               pattern->ptr.str = strdup(*text);
+               pattern->ptr.str = strdup(text);
                if (!pattern->ptr.str) {
                        memprintf(err, "out of memory while loading string pattern");
                        return 0;
                }
        }
        else
-               pattern->ptr.str = (char *)*text;
-       pattern->len = strlen(*text);
+               pattern->ptr.str = (char *)text;
+       pattern->len = strlen(text);
        return 1;
 }
 
 /* Parse a binary written in hexa. It is allocated. */
-int pat_parse_bin(const char **text, struct pattern *pattern, enum pat_usage usage, int *opaque, char **err)
+int pat_parse_bin(const char *text, struct pattern *pattern, enum pat_usage usage, char **err)
 {
        struct chunk *trash;
 
@@ -234,16 +216,16 @@ int pat_parse_bin(const char **text, struct pattern *pattern, enum pat_usage usa
                 * if not fail. In succes case, this function eat always 1 elements.
                 * The double operator "!" converts the range "1-n" to "1".
                 */
-               return !!parse_binary(*text, &pattern->ptr.str, &pattern->len, err);
+               return !!parse_binary(text, &pattern->ptr.str, &pattern->len, err);
 
        trash = get_trash_chunk();
        pattern->len = trash->size;
        pattern->ptr.str = trash->str;
-       return !!parse_binary(*text, &pattern->ptr.str, &pattern->len, err);
+       return !!parse_binary(text, &pattern->ptr.str, &pattern->len, err);
 }
 
 /* Parse a regex. It is allocated. */
-int pat_parse_reg(const char **text, struct pattern *pattern, enum pat_usage usage, int *opaque, char **err)
+int pat_parse_reg(const char *text, struct pattern *pattern, enum pat_usage usage, char **err)
 {
        struct my_regex *preg;
        struct chunk *trash;
@@ -256,7 +238,7 @@ int pat_parse_reg(const char **text, struct pattern *pattern, enum pat_usage usa
                        return 0;
                }
 
-               if (!regex_comp(*text, preg, !(pattern->flags & PAT_F_IGNORE_CASE), 0, err)) {
+               if (!regex_comp(text, preg, !(pattern->flags & PAT_F_IGNORE_CASE), 0, err)) {
                        free(preg);
                        return 0;
                }
@@ -272,7 +254,7 @@ int pat_parse_reg(const char **text, struct pattern *pattern, enum pat_usage usa
                }
 
                preg = (struct my_regex *)trash->str;
-               preg->regstr = (char *)*text;
+               preg->regstr = (char *)text;
                pattern->freeptrbuf = NULL;
        }
 
@@ -296,15 +278,15 @@ int pat_parse_reg(const char **text, struct pattern *pattern, enum pat_usage usa
  * non-zero on success.
  *
  */
-int pat_parse_int(const char **text, struct pattern *pattern, enum pat_usage usage, int *opaque, char **err)
+int pat_parse_int(const char *text, struct pattern *pattern, enum pat_usage usage, char **err)
 {
-       const char *ptr = *text;
+       const char *ptr = text;
 
        pattern->type = SMP_T_UINT;
        pattern->expect_type = SMP_T_UINT;
 
        /* Empty string is not valid */
-       if (!**text)
+       if (!*text)
                goto not_valid_range;
 
        /* Search ':' or '-' separator. */
@@ -313,8 +295,8 @@ int pat_parse_int(const char **text, struct pattern *pattern, enum pat_usage usa
 
        /* If separator not found. */
        if (!*ptr) {
-               if (strl2llrc(*text, ptr - *text, &pattern->val.range.min) != 0) {
-                       memprintf(err, "'%s' is not a number", *text);
+               if (strl2llrc(text, ptr - text, &pattern->val.range.min) != 0) {
+                       memprintf(err, "'%s' is not a number", text);
                        return 0;
                }
                pattern->val.range.max = pattern->val.range.min;
@@ -324,7 +306,7 @@ int pat_parse_int(const char **text, struct pattern *pattern, enum pat_usage usa
        }
 
        /* If the separator is the first character. */
-       if (ptr == *text && *(ptr + 1) != '\0') {
+       if (ptr == text && *(ptr + 1) != '\0') {
                if (strl2llrc(ptr + 1, strlen(ptr + 1), &pattern->val.range.max) != 0)
                        goto not_valid_range;
 
@@ -335,7 +317,7 @@ int pat_parse_int(const char **text, struct pattern *pattern, enum pat_usage usa
 
        /* If separator is the last character. */
        if (*(ptr + 1) == '\0') {
-               if (strl2llrc(*text, ptr - *text, &pattern->val.range.min) != 0)
+               if (strl2llrc(text, ptr - text, &pattern->val.range.min) != 0)
                        goto not_valid_range;
 
                pattern->val.range.min_set = 1;
@@ -344,7 +326,7 @@ int pat_parse_int(const char **text, struct pattern *pattern, enum pat_usage usa
        }
 
        /* Else, parse two numbers. */
-       if (strl2llrc(*text, ptr - *text, &pattern->val.range.min) != 0)
+       if (strl2llrc(text, ptr - text, &pattern->val.range.min) != 0)
                goto not_valid_range;
 
        if (strl2llrc(ptr + 1, strlen(ptr + 1), &pattern->val.range.max) != 0)
@@ -358,15 +340,15 @@ int pat_parse_int(const char **text, struct pattern *pattern, enum pat_usage usa
        return 1;
 
  not_valid_range:
-       memprintf(err, "'%s' is not a valid number range", *text);
+       memprintf(err, "'%s' is not a valid number range", text);
        return 0;
 }
 
-int pat_parse_len(const char **text, struct pattern *pattern, enum pat_usage usage, int *opaque, char **err)
+int pat_parse_len(const char *text, struct pattern *pattern, enum pat_usage usage, char **err)
 {
        int ret;
 
-       ret = pat_parse_int(text, pattern, usage, opaque, err);
+       ret = pat_parse_int(text, pattern, usage, err);
        pattern->expect_type = SMP_T_CSTR;
        return ret;
 }
@@ -391,9 +373,9 @@ int pat_parse_len(const char **text, struct pattern *pattern, enum pat_usage usa
  *    acl valid_ssl       ssl_req_proto 3.0-3.1
  *
  */
-int pat_parse_dotted_ver(const char **text, struct pattern *pattern, enum pat_usage usage, int *opaque, char **err)
+int pat_parse_dotted_ver(const char *text, struct pattern *pattern, enum pat_usage usage, char **err)
 {
-       const char *ptr = *text;
+       const char *ptr = text;
 
        pattern->type = SMP_T_UINT;
        pattern->expect_type = SMP_T_UINT;
@@ -403,9 +385,9 @@ int pat_parse_dotted_ver(const char **text, struct pattern *pattern, enum pat_us
                ptr++;
 
        /* If separator not found. */
-       if (*ptr == '\0' && ptr > *text) {
-               if (strl2llrc_dotted(*text, ptr-*text, &pattern->val.range.min) != 0) {
-                       memprintf(err, "'%s' is not a dotted number", *text);
+       if (*ptr == '\0' && ptr > text) {
+               if (strl2llrc_dotted(text, ptr-text, &pattern->val.range.min) != 0) {
+                       memprintf(err, "'%s' is not a dotted number", text);
                        return 0;
                }
                pattern->val.range.max = pattern->val.range.min;
@@ -415,9 +397,9 @@ int pat_parse_dotted_ver(const char **text, struct pattern *pattern, enum pat_us
        }
 
        /* If the separator is the first character. */
-       if (ptr == *text && *(ptr+1) != '\0') {
+       if (ptr == text && *(ptr+1) != '\0') {
                if (strl2llrc_dotted(ptr+1, strlen(ptr+1), &pattern->val.range.max) != 0) {
-                       memprintf(err, "'%s' is not a valid dotted number range", *text);
+                       memprintf(err, "'%s' is not a valid dotted number range", text);
                        return 0;
                }
                pattern->val.range.min_set = 0;
@@ -426,9 +408,9 @@ int pat_parse_dotted_ver(const char **text, struct pattern *pattern, enum pat_us
        }
 
        /* If separator is the last character. */
-       if (ptr == &(*text)[strlen(*text)-1]) {
-               if (strl2llrc_dotted(*text, ptr-*text, &pattern->val.range.min) != 0) {
-                       memprintf(err, "'%s' is not a valid dotted number range", *text);
+       if (ptr == &text[strlen(text)-1]) {
+               if (strl2llrc_dotted(text, ptr-text, &pattern->val.range.min) != 0) {
+                       memprintf(err, "'%s' is not a valid dotted number range", text);
                        return 0;
                }
                pattern->val.range.min_set = 1;
@@ -437,16 +419,16 @@ int pat_parse_dotted_ver(const char **text, struct pattern *pattern, enum pat_us
        }
 
        /* Else, parse two numbers. */
-       if (strl2llrc_dotted(*text, ptr-*text, &pattern->val.range.min) != 0) {
-               memprintf(err, "'%s' is not a valid dotted number range", *text);
+       if (strl2llrc_dotted(text, ptr-text, &pattern->val.range.min) != 0) {
+               memprintf(err, "'%s' is not a valid dotted number range", text);
                return 0;
        }
        if (strl2llrc_dotted(ptr+1, strlen(ptr+1), &pattern->val.range.max) != 0) {
-               memprintf(err, "'%s' is not a valid dotted number range", *text);
+               memprintf(err, "'%s' is not a valid dotted number range", text);
                return 0;
        }
        if (pattern->val.range.min > pattern->val.range.max) {
-               memprintf(err, "'%s' is not a valid dotted number range", *text);
+               memprintf(err, "'%s' is not a valid dotted number range", text);
                return 0;
        }
        pattern->val.range.min_set = 1;
@@ -459,20 +441,20 @@ int pat_parse_dotted_ver(const char **text, struct pattern *pattern, enum pat_us
  * may either be a dotted mask or a number of bits. Returns 1 if OK,
  * otherwise 0. NOTE: IP address patterns are typed (IPV4/IPV6).
  */
-int pat_parse_ip(const char **text, struct pattern *pattern, enum pat_usage usage, int *opaque, char **err)
+int pat_parse_ip(const char *text, struct pattern *pattern, enum pat_usage usage, char **err)
 {
        pattern->expect_type = SMP_T_ADDR;
-       if (str2net(*text, &pattern->val.ipv4.addr, &pattern->val.ipv4.mask)) {
+       if (str2net(text, &pattern->val.ipv4.addr, &pattern->val.ipv4.mask)) {
                pattern->type = SMP_T_IPV4;
                return 1;
        }
-       else if (str62net(*text, &pattern->val.ipv6.addr, &pattern->val.ipv6.mask)) {
+       else if (str62net(text, &pattern->val.ipv6.addr, &pattern->val.ipv6.mask)) {
                /* no tree support right now */
                pattern->type = SMP_T_IPV6;
                return 1;
        }
        else {
-               memprintf(err, "'%s' is not a valid IPv4 or IPv6 address", *text);
+               memprintf(err, "'%s' is not a valid IPv4 or IPv6 address", text);
                return 0;
        }
 }
@@ -813,7 +795,6 @@ int pattern_register(struct pattern_expr *expr, const char **args,
                          struct pattern **pattern,
                          int patflags, char **err)
 {
-       int opaque = 0;
        unsigned int mask = 0;
        struct pat_idx_elt *node;
        int len;
@@ -833,7 +814,7 @@ int pattern_register(struct pattern_expr *expr, const char **args,
                memset(*pattern, 0, sizeof(**pattern));
                (*pattern)->flags = patflags;
 
-               ret = expr->parse(args, *pattern, PAT_U_COMPILE, &opaque, err);
+               ret = expr->parse(args[0], *pattern, PAT_U_COMPILE, err);
                if (!ret)
                        return 0;
 
@@ -1105,8 +1086,6 @@ int pattern_lookup(const char *key, struct pattern_expr *expr,
        struct pattern *pat;
        struct ebmb_node *node;
        struct pat_idx_elt *elt;
-       const char *args[2];
-       int opaque = 0;
        unsigned int mask = 0;
 
        /* no real pattern */
@@ -1114,9 +1093,7 @@ int pattern_lookup(const char *key, struct pattern_expr *expr,
                return 0;
 
        /* build lookup pattern */
-       args[0] = key;
-       args[1] = "";
-       if (!expr->parse(args, &pattern, PAT_U_LOOKUP, &opaque, NULL))
+       if (!expr->parse(key, &pattern, PAT_U_LOOKUP, NULL))
                return 0;
 
        pat = NULL;
index 702ef22fb3365f6579a6c570aa4bed9e02a8115d..fefcf641468618d2755a713b7d410a2a364b195d 100644 (file)
@@ -8973,18 +8973,18 @@ smp_prefetch_http(struct proxy *px, struct session *s, void *l7, unsigned int op
  * We use the pre-parsed method if it is known, and store its number as an
  * integer. If it is unknown, we use the pointer and the length.
  */
-static int pat_parse_meth(const char **text, struct pattern *pattern, enum pat_usage usage, int *opaque, char **err)
+static int pat_parse_meth(const char *text, struct pattern *pattern, enum pat_usage usage, char **err)
 {
        int len, meth;
        struct chunk *trash;
 
-       len  = strlen(*text);
-       meth = find_http_meth(*text, len);
+       len  = strlen(text);
+       meth = find_http_meth(text, len);
 
        pattern->val.i = meth;
        if (meth == HTTP_METH_OTHER) {
                if (usage == PAT_U_COMPILE) {
-                       pattern->ptr.str = strdup(*text);
+                       pattern->ptr.str = strdup(text);
                        if (!pattern->ptr.str) {
                                memprintf(err, "out of memory while loading pattern");
                                return 0;