You've already forked FFmpeg
mirror of
https://github.com/FFmpeg/FFmpeg.git
synced 2025-08-10 06:10:52 +02:00
ffserver: HTML encode msgs instead of blindly stripping chars out
Fixes weirdness like our "??filename? not found" 404. None of the chars being used from the previously blacklisted list needs to be scaped on an UTF-8 document context Signed-off-by: Reynaldo H. Verdejo Pinochet <reynaldo@osg.samsung.com>
This commit is contained in:
89
ffserver.c
89
ffserver.c
@@ -243,6 +243,8 @@ static int rtp_new_av_stream(HTTPContext *c,
|
|||||||
int stream_index, struct sockaddr_in *dest_addr,
|
int stream_index, struct sockaddr_in *dest_addr,
|
||||||
HTTPContext *rtsp_c);
|
HTTPContext *rtsp_c);
|
||||||
/* utils */
|
/* utils */
|
||||||
|
static size_t htmlencode (const char *src, char **dest);
|
||||||
|
static inline void cp_html_entity (char *buffer, const char *entity);
|
||||||
static inline int check_codec_match(AVCodecContext *ccf, AVCodecContext *ccs,
|
static inline int check_codec_match(AVCodecContext *ccf, AVCodecContext *ccs,
|
||||||
int stream);
|
int stream);
|
||||||
|
|
||||||
@@ -263,12 +265,79 @@ static AVLFG random_state;
|
|||||||
|
|
||||||
static FILE *logfile = NULL;
|
static FILE *logfile = NULL;
|
||||||
|
|
||||||
static void htmlstrip(char *s) {
|
static inline void cp_html_entity (char *buffer, const char *entity) {
|
||||||
while (s && *s) {
|
if (!buffer || !entity)
|
||||||
s += strspn(s, "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ,. ");
|
return;
|
||||||
if (*s)
|
while (*entity)
|
||||||
*s++ = '?';
|
*buffer++ = *entity++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Substitutes known conflicting chars on a text string with
|
||||||
|
* their corresponding HTML entities.
|
||||||
|
*
|
||||||
|
* Returns the number of bytes in the 'encoded' representation
|
||||||
|
* not including the terminating NUL.
|
||||||
|
*/
|
||||||
|
static size_t htmlencode (const char *src, char **dest) {
|
||||||
|
const char *amp = "&";
|
||||||
|
const char *lt = "<";
|
||||||
|
const char *gt = ">";
|
||||||
|
const char *start;
|
||||||
|
char *tmp;
|
||||||
|
size_t final_size = 0;
|
||||||
|
|
||||||
|
if (!src)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
start = src;
|
||||||
|
|
||||||
|
/* Compute needed dest size */
|
||||||
|
while (*src != '\0') {
|
||||||
|
switch(*src) {
|
||||||
|
case 38: /* & */
|
||||||
|
final_size += 5;
|
||||||
|
break;
|
||||||
|
case 60: /* < */
|
||||||
|
case 62: /* > */
|
||||||
|
final_size += 4;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
final_size++;
|
||||||
|
}
|
||||||
|
src++;
|
||||||
|
}
|
||||||
|
|
||||||
|
src = start;
|
||||||
|
*dest = av_mallocz(final_size + 1);
|
||||||
|
if (!*dest)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
/* Build dest */
|
||||||
|
tmp = *dest;
|
||||||
|
while (*src != '\0') {
|
||||||
|
switch(*src) {
|
||||||
|
case 38: /* & */
|
||||||
|
cp_html_entity (tmp, amp);
|
||||||
|
tmp += 5;
|
||||||
|
break;
|
||||||
|
case 60: /* < */
|
||||||
|
cp_html_entity (tmp, lt);
|
||||||
|
tmp += 4;
|
||||||
|
break;
|
||||||
|
case 62: /* > */
|
||||||
|
cp_html_entity (tmp, gt);
|
||||||
|
tmp += 4;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
*tmp = *src;
|
||||||
|
tmp += 1;
|
||||||
|
}
|
||||||
|
src++;
|
||||||
|
}
|
||||||
|
*tmp = '\0';
|
||||||
|
|
||||||
|
return final_size;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int64_t ffm_read_write_index(int fd)
|
static int64_t ffm_read_write_index(int fd)
|
||||||
@@ -1356,6 +1425,7 @@ static int http_parse_request(HTTPContext *c)
|
|||||||
char url[1024], *q;
|
char url[1024], *q;
|
||||||
char protocol[32];
|
char protocol[32];
|
||||||
char msg[1024];
|
char msg[1024];
|
||||||
|
char *encoded_msg = NULL;
|
||||||
const char *mime_type;
|
const char *mime_type;
|
||||||
FFServerStream *stream;
|
FFServerStream *stream;
|
||||||
int i;
|
int i;
|
||||||
@@ -1753,7 +1823,9 @@ static int http_parse_request(HTTPContext *c)
|
|||||||
send_error:
|
send_error:
|
||||||
c->http_error = 404;
|
c->http_error = 404;
|
||||||
q = c->buffer;
|
q = c->buffer;
|
||||||
htmlstrip(msg);
|
if (!htmlencode(msg, &encoded_msg)) {
|
||||||
|
http_log("Could not encode filename '%s' as HTML\n", msg);
|
||||||
|
}
|
||||||
snprintf(q, c->buffer_size,
|
snprintf(q, c->buffer_size,
|
||||||
"HTTP/1.0 404 Not Found\r\n"
|
"HTTP/1.0 404 Not Found\r\n"
|
||||||
"Content-type: text/html\r\n"
|
"Content-type: text/html\r\n"
|
||||||
@@ -1761,16 +1833,17 @@ static int http_parse_request(HTTPContext *c)
|
|||||||
"<!DOCTYPE html>\n"
|
"<!DOCTYPE html>\n"
|
||||||
"<html>\n"
|
"<html>\n"
|
||||||
"<head>\n"
|
"<head>\n"
|
||||||
"<meta charset="UTF-8">\n"
|
"<meta charset=\"UTF-8\">\n"
|
||||||
"<title>404 Not Found</title>\n"
|
"<title>404 Not Found</title>\n"
|
||||||
"</head>\n"
|
"</head>\n"
|
||||||
"<body>%s</body>\n"
|
"<body>%s</body>\n"
|
||||||
"</html>\n", msg);
|
"</html>\n", encoded_msg? encoded_msg : "File not found");
|
||||||
q += strlen(q);
|
q += strlen(q);
|
||||||
/* prepare output buffer */
|
/* prepare output buffer */
|
||||||
c->buffer_ptr = c->buffer;
|
c->buffer_ptr = c->buffer;
|
||||||
c->buffer_end = q;
|
c->buffer_end = q;
|
||||||
c->state = HTTPSTATE_SEND_HEADER;
|
c->state = HTTPSTATE_SEND_HEADER;
|
||||||
|
av_freep(&encoded_msg);
|
||||||
return 0;
|
return 0;
|
||||||
send_status:
|
send_status:
|
||||||
compute_status(c);
|
compute_status(c);
|
||||||
|
Reference in New Issue
Block a user