From: Jaroslav Kysela Date: Mon, 10 Oct 2016 12:47:01 +0000 (+0200) Subject: http: fix http_arg_get(_remove) when query does not have key=val, fixes #4015, fixes... X-Git-Tag: v4.2.1~277 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=f608075b569da068632c3beb96ba6623074eb846;p=thirdparty%2Ftvheadend.git http: fix http_arg_get(_remove) when query does not have key=val, fixes #4015, fixes #4003 --- diff --git a/src/http.c b/src/http.c index 042c41d0a..b84957ead 100644 --- a/src/http.c +++ b/src/http.c @@ -429,7 +429,7 @@ http_send_header(http_connection_t *hc, int rc, const char *content, TAILQ_FOREACH(ra, args, link) { if (strcmp(ra->key, "Session") == 0) sess = 1; - htsbuf_qprintf(&hdrs, "%s: %s\r\n", ra->key, ra->val); + htsbuf_qprintf(&hdrs, "%s: %s\r\n", ra->key, ra->val ?: ""); } } if(hc->hc_session && !sess) @@ -637,8 +637,10 @@ http_redirect(http_connection_t *hc, const char *location, htsbuf_append(&hq, "?", 1); first = 0; htsbuf_append_and_escape_url(&hq, ra->key); - htsbuf_append(&hq, "=", 1); - htsbuf_append_and_escape_url(&hq, ra->val); + if (ra->val) { + htsbuf_append(&hq, "=", 1); + htsbuf_append_and_escape_url(&hq, ra->val); + } } loc = htsbuf_to_string(&hq); htsbuf_queue_flush(&hq); @@ -699,7 +701,7 @@ http_get_hostpath(http_connection_t *hc) proto = http_arg_get(&hc->hc_args, "X-Forwarded-Proto"); snprintf(buf, sizeof(buf), "%s://%s%s", - proto ?: "http", host, tvheadend_webroot ?: ""); + proto ?: "http", host ?: "localhost", tvheadend_webroot ?: ""); return strdup(buf); } @@ -1240,16 +1242,20 @@ char * http_arg_get_remove(struct http_arg_list *list, const char *name) { static char __thread buf[128]; + int empty; http_arg_t *ra; TAILQ_FOREACH(ra, list, link) if(!strcasecmp(ra->key, name)) { TAILQ_REMOVE(list, ra, link); - strncpy(buf, ra->val, sizeof(buf)-1); - buf[sizeof(buf)-1] = '\0'; + empty = ra->val == NULL; + if (!empty) { + strncpy(buf, ra->val, sizeof(buf)-1); + buf[sizeof(buf)-1] = '\0'; + } free(ra->key); free(ra->val); free(ra); - return buf; + return !empty ? buf : NULL; } buf[0] = '\0'; return buf; @@ -1267,7 +1273,7 @@ http_arg_set(struct http_arg_list *list, const char *key, const char *val) ra = malloc(sizeof(http_arg_t)); TAILQ_INSERT_TAIL(list, ra, link); ra->key = strdup(key); - ra->val = strdup(val); + ra->val = val ? strdup(val) : NULL; } /* @@ -1400,17 +1406,25 @@ http_parse_args(http_arg_list_t *list, char *args) args++; while(args) { k = args; - if((args = strchr(args, '=')) == NULL) - break; - *args++ = 0; + if((args = strchr(args, '=')) != NULL) { + *args++ = 0; + } else { + args = k; + } + v = args; args = strchr(args, '&'); - if(args != NULL) *args++ = 0; + else if(v == k) { + if (*k == '\0') + break; + v = NULL; + } http_deescape(k); - http_deescape(v); + if (v) + http_deescape(v); // printf("%s = %s\n", k, v); http_arg_set(list, k, v); } diff --git a/src/httpc.c b/src/httpc.c index c65baecf4..b9eb0aad1 100644 --- a/src/httpc.c +++ b/src/httpc.c @@ -613,10 +613,11 @@ error: TAILQ_FOREACH(h, header, link) { htsbuf_append_str(&q, h->key); htsbuf_append(&q, ": ", 2); - htsbuf_append_str(&q, h->val); + if (h->val) + htsbuf_append_str(&q, h->val); htsbuf_append(&q, "\r\n", 2); if (strcasecmp(h->key, "Connection") == 0 && - strcasecmp(h->val, "close") == 0) + strcasecmp(h->val ?: "", "close") == 0) hc->hc_keepalive = 0; } http_arg_flush(header); diff --git a/src/input/mpegts/iptv/iptv_auto.c b/src/input/mpegts/iptv/iptv_auto.c index 6a33cac9e..9e09ba09e 100644 --- a/src/input/mpegts/iptv/iptv_auto.c +++ b/src/input/mpegts/iptv/iptv_auto.c @@ -170,8 +170,10 @@ iptv_auto_network_process_m3u_item(iptv_network_t *in, if (!htsbuf_empty(&q)) htsbuf_append(&q, "&", 1); htsbuf_append_str(&q, ra1->key); - htsbuf_append(&q, "=", 1); - htsbuf_append_str(&q, ra1->val); + if (ra1->val) { + htsbuf_append(&q, "=", 1); + htsbuf_append_str(&q, ra1->val); + } } free(u.query); u.query = htsbuf_to_string(&q); diff --git a/src/satip/rtsp.c b/src/satip/rtsp.c index c0d65cb81..d3dabc77b 100644 --- a/src/satip/rtsp.c +++ b/src/satip/rtsp.c @@ -645,7 +645,7 @@ msys_to_tvh(http_connection_t *hc) { "dvbcb", DVB_SYS_DVBC_ANNEX_B } }; const char *s = http_arg_get_remove(&hc->hc_req_args, "msys"); - return s[0] ? str2val(s, tab) : DVB_SYS_NONE; + return s && s[0] ? str2val(s, tab) : DVB_SYS_NONE; } static inline int @@ -658,13 +658,13 @@ pol_to_tvh(http_connection_t *hc) { "r", DVB_POLARISATION_CIRCULAR_RIGHT }, }; const char *s = http_arg_get_remove(&hc->hc_req_args, "pol"); - return s[0] ? str2val(s, tab) : -1; + return s && s[0] ? str2val(s, tab) : -1; } static int fec_to_tvh(http_connection_t *hc) { - switch (atoi(http_arg_get_remove(&hc->hc_req_args, "fec"))) { + switch (atoi(http_arg_get_remove(&hc->hc_req_args, "fec") ?: "0")) { case 0: return DVB_FEC_AUTO; case 12: return DVB_FEC_1_2; case 13: return DVB_FEC_1_3; @@ -693,7 +693,7 @@ fec_to_tvh(http_connection_t *hc) static int bw_to_tvh(http_connection_t *hc) { - int bw = atof(http_arg_get_remove(&hc->hc_req_args, "bw")) * 1000; + int bw = atof(http_arg_get_remove(&hc->hc_req_args, "bw") ?: "0") * 1000; switch (bw) { case 0: return DVB_BANDWIDTH_AUTO; case DVB_BANDWIDTH_1_712_MHZ: @@ -711,7 +711,7 @@ bw_to_tvh(http_connection_t *hc) static int rolloff_to_tvh(http_connection_t *hc) { - int ro = atof(http_arg_get_remove(&hc->hc_req_args, "ro")) * 1000; + int ro = atof(http_arg_get_remove(&hc->hc_req_args, "ro") ?: "0") * 1000; switch (ro) { case 0: return DVB_ROLLOFF_35; @@ -728,11 +728,11 @@ static int pilot_to_tvh(http_connection_t *hc) { const char *s = http_arg_get_remove(&hc->hc_req_args, "plts"); - if (strcmp(s, "on") == 0) + if (s && strcmp(s, "on") == 0) return DVB_PILOT_ON; - if (strcmp(s, "off") == 0) + if (s && strcmp(s, "off") == 0) return DVB_PILOT_OFF; - if (s[0] == '\0' || strcmp(s, "auto") == 0) + if (s == NULL || s[0] == '\0' || strcmp(s, "auto") == 0) return DVB_PILOT_AUTO; return DVB_ROLLOFF_NONE; } @@ -750,7 +750,7 @@ tmode_to_tvh(http_connection_t *hc) { "32k", DVB_TRANSMISSION_MODE_32K }, }; const char *s = http_arg_get_remove(&hc->hc_req_args, "tmode"); - if (s[0]) { + if (s && s[0]) { int v = str2val(s, tab); return v >= 0 ? v : DVB_TRANSMISSION_MODE_NONE; } @@ -772,7 +772,7 @@ mtype_to_tvh(http_connection_t *hc) { "8vsb", DVB_MOD_VSB_8 }, }; const char *s = http_arg_get_remove(&hc->hc_req_args, "mtype"); - if (s[0]) { + if (s && s[0]) { int v = str2val(s, tab); return v >= 0 ? v : DVB_MOD_NONE; } @@ -782,7 +782,7 @@ mtype_to_tvh(http_connection_t *hc) static int gi_to_tvh(http_connection_t *hc) { - switch (atoi(http_arg_get_remove(&hc->hc_req_args, "gi"))) { + switch (atoi(http_arg_get_remove(&hc->hc_req_args, "gi") ?: "0")) { case 0: return DVB_GUARD_INTERVAL_AUTO; case 14: return DVB_GUARD_INTERVAL_1_4; case 18: return DVB_GUARD_INTERVAL_1_8; @@ -885,7 +885,7 @@ rtsp_parse_cmd has_args = !TAILQ_EMPTY(&hc->hc_req_args); - fe = atoi(http_arg_get_remove(&hc->hc_req_args, "fe")); + fe = atoi(http_arg_get_remove(&hc->hc_req_args, "fe") ?: 0); s = http_arg_get_remove(&hc->hc_req_args, "addpids"); if (parse_pids(s, &addpids)) goto end; s = http_arg_get_remove(&hc->hc_req_args, "delpids"); @@ -993,11 +993,11 @@ rtsp_parse_cmd if (msys == DVB_SYS_DVBS || msys == DVB_SYS_DVBS2) { - src = atoi(http_arg_get_remove(&hc->hc_req_args, "src")); + src = atoi(http_arg_get_remove(&hc->hc_req_args, "src") ?: "0"); if (src < 1) goto end; pol = pol_to_tvh(hc); if (pol < 0) goto end; - sr = atof(http_arg_get_remove(&hc->hc_req_args, "sr")) * 1000; + sr = atof(http_arg_get_remove(&hc->hc_req_args, "sr") ?: "0") * 1000; if (sr < 1000) goto end; fec = fec_to_tvh(hc); if (fec == DVB_FEC_NONE) goto end; @@ -1028,15 +1028,15 @@ rtsp_parse_cmd fec = fec_to_tvh(hc); if (fec == DVB_FEC_NONE) goto end; s = http_arg_get_remove(&hc->hc_req_args, "plp"); - if (s[0]) { + if (s && s[0]) { plp = atoi(s); if (plp < 0 || plp > 255) goto end; } else { plp = DVB_NO_STREAM_ID_FILTER; } - t2id = atoi(http_arg_get_remove(&hc->hc_req_args, "t2id")); + t2id = atoi(http_arg_get_remove(&hc->hc_req_args, "t2id") ?: "0"); if (t2id < 0 || t2id > 65535) goto end; - sm = atoi(http_arg_get_remove(&hc->hc_req_args, "sm")); + sm = atoi(http_arg_get_remove(&hc->hc_req_args, "sm") ?: "0"); if (sm < 0 || sm > 1) goto end; if (!TAILQ_EMPTY(&hc->hc_req_args)) goto eargs; @@ -1055,22 +1055,22 @@ rtsp_parse_cmd freq *= 1000; if (freq < 0) goto end; - c2tft = atoi(http_arg_get_remove(&hc->hc_req_args, "c2tft")); + c2tft = atoi(http_arg_get_remove(&hc->hc_req_args, "c2tft") ?: "0"); if (c2tft < 0 || c2tft > 2) goto end; bw = bw_to_tvh(hc); if (bw == DVB_BANDWIDTH_NONE) goto end; - sr = atof(http_arg_get_remove(&hc->hc_req_args, "sr")) * 1000; + sr = atof(http_arg_get_remove(&hc->hc_req_args, "sr") ?: "0") * 1000; if (sr < 1000) goto end; - ds = atoi(http_arg_get_remove(&hc->hc_req_args, "ds")); + ds = atoi(http_arg_get_remove(&hc->hc_req_args, "ds") ?: "0"); if (ds < 0 || ds > 255) goto end; s = http_arg_get_remove(&hc->hc_req_args, "plp"); - if (s[0]) { + if (s && s[0]) { plp = atoi(http_arg_get_remove(&hc->hc_req_args, "plp")); if (plp < 0 || plp > 255) goto end; } else { plp = DVB_NO_STREAM_ID_FILTER; } - specinv = atoi(http_arg_get_remove(&hc->hc_req_args, "specinv")); + specinv = atoi(http_arg_get_remove(&hc->hc_req_args, "specinv") ?: "0"); if (specinv < 0 || specinv > 1) goto end; fec = fec_to_tvh(hc); if (fec == DVB_FEC_NONE) goto end;