You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

142 lines
4.3 KiB

commit 200c6215fe9c592d576f52d4a79627381ed6aa7f
Author: William Dauchy <w.dauchy@criteo.com>
Date: Tue Nov 26 12:56:26 2019 +0100
BUG/MINOR: contrib/prometheus-exporter: decode parameter and value only
we were decoding all substring and then parsing; this could lead to
consider & and = in decoding result as delimiters where it should not.
this patch reverses the order by first parsing and then decoding each key
and value separately.
we also stop parsing after number sign (#).
This patch should be backported to 2.1 and 2.0
Signed-off-by: William Dauchy <w.dauchy@criteo.com>
(cherry picked from commit c65f656d75091db3087a752dbc956159392fc8f2)
Signed-off-by: Christopher Faulet <cfaulet@haproxy.com>
(cherry picked from commit 8ec21c5fef89f13fea2ac9be55d55215d4b9104a)
Signed-off-by: Christopher Faulet <cfaulet@haproxy.com>
diff --git a/contrib/prometheus-exporter/service-prometheus.c b/contrib/prometheus-exporter/service-prometheus.c
index cfbfb8c3..c34ee0e1 100644
--- a/contrib/prometheus-exporter/service-prometheus.c
+++ b/contrib/prometheus-exporter/service-prometheus.c
@@ -2220,7 +2220,8 @@ static int promex_parse_uri(struct appctx *appctx, struct stream_interface *si)
struct channel *res = si_ic(si);
struct htx *req_htx, *res_htx;
struct htx_sl *sl;
- const char *p, *end;
+ char *p, *key, *value;
+ const char *end;
struct buffer *err;
int default_scopes = PROMEX_FL_SCOPE_ALL;
int len;
@@ -2234,57 +2235,72 @@ static int promex_parse_uri(struct appctx *appctx, struct stream_interface *si)
if (!p)
goto end;
end = HTX_SL_REQ_UPTR(sl) + HTX_SL_REQ_ULEN(sl);
- len = end-p;
- /* Decode the query-string */
+ /* copy the query-string */
+ len = end - p;
chunk_reset(&trash);
memcpy(trash.area, p, len);
trash.area[len] = 0;
- len = url_decode(trash.area);
- if (len == -1)
- goto error;
p = trash.area;
- end = p + len;
+ end = trash.area + len;
/* Parse the query-string */
- while (p < end) {
- if (*p == '&')
+ while (p < end && *p && *p != '#') {
+ value = NULL;
+
+ /* decode parameter name */
+ key = p;
+ while (p < end && *p != '=' && *p != '&' && *p != '#')
++p;
- else if (*p == 's' && (end-p) >= 6 && !memcmp(p, "scope=", 6)) {
- default_scopes = 0; /* at least a scope defined, unset default scopes */
- p += 6; /* now p point on the parameter value */
- len = 0; /* len is the value length */
- while ((p+len) < end && *(p+len) != '&')
- ++len;
+ /* found a value */
+ if (*p == '=') {
+ *(p++) = 0;
+ value = p;
+ }
+ else if (*p == '&')
+ *(p++) = 0;
+ else if (*p == '#')
+ *p = 0;
+ len = url_decode(key);
+ if (len == -1)
+ goto error;
+
+ /* decode value */
+ if (value) {
+ while (p < end && *p != '=' && *p != '&' && *p != '#')
+ ++p;
+ if (*p == '=')
+ goto error;
+ if (*p == '&')
+ *(p++) = 0;
+ else if (*p == '#')
+ *p = 0;
+ len = url_decode(value);
+ if (len == -1)
+ goto error;
+ }
- if (len == 0)
+ if (!strcmp(key, "scope")) {
+ default_scopes = 0; /* at least a scope defined, unset default scopes */
+ if (!value)
+ goto error;
+ else if (*value == 0)
appctx->ctx.stats.flags &= ~PROMEX_FL_SCOPE_ALL;
- else if (len == 1 && *p == '*')
+ else if (*value == '*')
appctx->ctx.stats.flags |= PROMEX_FL_SCOPE_ALL;
- else if (len == 6) {
- if (!memcmp(p, "global", len))
- appctx->ctx.stats.flags |= PROMEX_FL_SCOPE_GLOBAL;
- else if (!memcmp(p, "server", len))
- appctx->ctx.stats.flags |= PROMEX_FL_SCOPE_SERVER;
- }
- else if (len == 7 && !memcmp(p, "backend", len))
+ else if (!strcmp(value, "global"))
+ appctx->ctx.stats.flags |= PROMEX_FL_SCOPE_GLOBAL;
+ else if (!strcmp(value, "server"))
+ appctx->ctx.stats.flags |= PROMEX_FL_SCOPE_SERVER;
+ else if (!strcmp(value, "backend"))
appctx->ctx.stats.flags |= PROMEX_FL_SCOPE_BACK;
- else if (len == 8 && !memcmp(p, "frontend", len))
+ else if (!strcmp(value, "frontend"))
appctx->ctx.stats.flags |= PROMEX_FL_SCOPE_FRONT;
else
goto error;
-
- p += len;
}
- else if (*p == 'n' && (end-p) >= 8 && !memcmp(p, "no-maint", 8)) {
+ else if (!strcmp(key, "no-maint"))
appctx->ctx.stats.flags |= PROMEX_FL_NO_MAINT_SRV;
- p += 8;
- }
- else {
- /* ignore all other params for now */
- while (p < end && *p != '&')
- p++;
- }
}
end: