mirror of
				https://gitlab.freedesktop.org/pulseaudio/pulseaudio.git
				synced 2025-11-03 09:01:50 -05:00 
			
		
		
		
	rtp: Accept CRLF delimiters in SDP as required by RFC 4566
RFC 4566 states that SDP record is terminated with CRLF, and parsers should be able to accept records terminated with just LF. Pulseaudio only accepts LF here. Fix this by accepting both CRLF and LF terminators.
This commit is contained in:
		
							parent
							
								
									237c5a5c36
								
							
						
					
					
						commit
						b55bcc3df3
					
				
					 3 changed files with 30 additions and 7 deletions
				
			
		| 
						 | 
					@ -213,7 +213,9 @@ int pa_sap_recv(pa_sap_context *c, bool *goodbye) {
 | 
				
			||||||
    if ((unsigned) size >= sizeof(MIME_TYPE) && pa_streq(e, MIME_TYPE)) {
 | 
					    if ((unsigned) size >= sizeof(MIME_TYPE) && pa_streq(e, MIME_TYPE)) {
 | 
				
			||||||
        e += sizeof(MIME_TYPE);
 | 
					        e += sizeof(MIME_TYPE);
 | 
				
			||||||
        size -= (int) sizeof(MIME_TYPE);
 | 
					        size -= (int) sizeof(MIME_TYPE);
 | 
				
			||||||
    } else if ((unsigned) size < sizeof(PA_SDP_HEADER)-1 || strncmp(e, PA_SDP_HEADER, sizeof(PA_SDP_HEADER)-1)) {
 | 
					    } else if ((unsigned) size < sizeof(PA_SDP_HEADER)-1 || strncmp(e, PA_SDP_HEADER, sizeof(PA_SDP_HEADER)-1)
 | 
				
			||||||
 | 
					            || strcspn(e, "\r\n") != sizeof(PA_SDP_HEADER)-1) {
 | 
				
			||||||
 | 
					        /* SDP header does not start with v=0[\r]\n */
 | 
				
			||||||
        pa_log_warn("Invalid SDP header.");
 | 
					        pa_log_warn("Invalid SDP header.");
 | 
				
			||||||
        goto fail;
 | 
					        goto fail;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -73,7 +73,7 @@ char *pa_sdp_build(int af, const void *src, const void *dst, const char *name, u
 | 
				
			||||||
    pa_assert_se(inet_ntop(af, dst, buf_dst, sizeof(buf_dst)));
 | 
					    pa_assert_se(inet_ntop(af, dst, buf_dst, sizeof(buf_dst)));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    return pa_sprintf_malloc(
 | 
					    return pa_sprintf_malloc(
 | 
				
			||||||
            PA_SDP_HEADER
 | 
					            PA_SDP_HEADER "\n"
 | 
				
			||||||
            "o=%s %lu 0 IN %s %s\n"
 | 
					            "o=%s %lu 0 IN %s %s\n"
 | 
				
			||||||
            "s=%s\n"
 | 
					            "s=%s\n"
 | 
				
			||||||
            "c=IN %s %s\n"
 | 
					            "c=IN %s %s\n"
 | 
				
			||||||
| 
						 | 
					@ -130,17 +130,29 @@ pa_sdp_info *pa_sdp_parse(const char *t, pa_sdp_info *i, int is_goodbye) {
 | 
				
			||||||
    i->salen = 0;
 | 
					    i->salen = 0;
 | 
				
			||||||
    i->payload = 255;
 | 
					    i->payload = 255;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if (!pa_startswith(t, PA_SDP_HEADER)) {
 | 
					    if (pa_startswith(t, PA_SDP_HEADER)) {
 | 
				
			||||||
 | 
					        t += sizeof(PA_SDP_HEADER) - 1;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        /* CR delimiter is optional */
 | 
				
			||||||
 | 
					        if (*t == '\r')
 | 
				
			||||||
 | 
					            t++;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        /* LF delimiter is mandatory */
 | 
				
			||||||
 | 
					        if (*t == '\n')
 | 
				
			||||||
 | 
					            t++;
 | 
				
			||||||
 | 
					        else {
 | 
				
			||||||
 | 
					            pa_log("Failed to parse SDP data: missing header record terminator LF.");
 | 
				
			||||||
 | 
					            goto fail;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    } else {
 | 
				
			||||||
        pa_log("Failed to parse SDP data: invalid header.");
 | 
					        pa_log("Failed to parse SDP data: invalid header.");
 | 
				
			||||||
        goto fail;
 | 
					        goto fail;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    t += sizeof(PA_SDP_HEADER)-1;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    while (*t) {
 | 
					    while (*t) {
 | 
				
			||||||
        size_t l;
 | 
					        size_t l;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        l = strcspn(t, "\n");
 | 
					        l = strcspn(t, "\r\n");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if (l <= 2) {
 | 
					        if (l <= 2) {
 | 
				
			||||||
            pa_log("Failed to parse SDP data: line too short: >%s<.", t);
 | 
					            pa_log("Failed to parse SDP data: line too short: >%s<.", t);
 | 
				
			||||||
| 
						 | 
					@ -240,8 +252,17 @@ pa_sdp_info *pa_sdp_parse(const char *t, pa_sdp_info *i, int is_goodbye) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        t += l;
 | 
					        t += l;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        /* CR delimiter is optional */
 | 
				
			||||||
 | 
					        if (*t == '\r')
 | 
				
			||||||
 | 
					            t++;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        /* LF delimiter is mandatory */
 | 
				
			||||||
        if (*t == '\n')
 | 
					        if (*t == '\n')
 | 
				
			||||||
            t++;
 | 
					            t++;
 | 
				
			||||||
 | 
					        else {
 | 
				
			||||||
 | 
					            pa_log("Failed to parse SDP data: missing record terminator LF.");
 | 
				
			||||||
 | 
					            goto fail;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if (!i->origin || (!is_goodbye && (!i->salen || i->payload > 127 || !ss_valid || port == 0))) {
 | 
					    if (!i->origin || (!is_goodbye && (!i->salen || i->payload > 127 || !ss_valid || port == 0))) {
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -26,7 +26,7 @@
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include <pulse/sample.h>
 | 
					#include <pulse/sample.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define PA_SDP_HEADER "v=0\n"
 | 
					#define PA_SDP_HEADER "v=0"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
typedef struct pa_sdp_info {
 | 
					typedef struct pa_sdp_info {
 | 
				
			||||||
    char *origin;
 | 
					    char *origin;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue