diff options
Diffstat (limited to 'libavformat/rtmpproto.c')
-rw-r--r-- | libavformat/rtmpproto.c | 97 |
1 files changed, 59 insertions, 38 deletions
diff --git a/libavformat/rtmpproto.c b/libavformat/rtmpproto.c index 77a801d11c..f0c1422ccf 100644 --- a/libavformat/rtmpproto.c +++ b/libavformat/rtmpproto.c @@ -2,20 +2,20 @@ * RTMP network protocol * Copyright (c) 2009 Konstantin Shishkov * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * FFmpeg is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * - * Libav is distributed in the hope that it will be useful, + * FFmpeg is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public - * License along with Libav; if not, write to the Free Software + * License along with FFmpeg; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ @@ -48,9 +48,9 @@ #include <zlib.h> #endif -#define APP_MAX_LENGTH 128 -#define PLAYPATH_MAX_LENGTH 256 -#define TCURL_MAX_LENGTH 512 +#define APP_MAX_LENGTH 1024 +#define PLAYPATH_MAX_LENGTH 512 +#define TCURL_MAX_LENGTH 1024 #define FLASHVER_MAX_LENGTH 64 #define RTMP_PKTDATA_DEFAULT_SIZE 4096 #define RTMP_HEADER 11 @@ -217,9 +217,8 @@ static void free_tracked_methods(RTMPContext *rt) int i; for (i = 0; i < rt->nb_tracked_methods; i ++) - av_free(rt->tracked_methods[i].name); - av_free(rt->tracked_methods); - rt->tracked_methods = NULL; + av_freep(&rt->tracked_methods[i].name); + av_freep(&rt->tracked_methods); rt->tracked_methods_size = 0; rt->nb_tracked_methods = 0; } @@ -322,7 +321,7 @@ static int gen_connect(URLContext *s, RTMPContext *rt) int ret; if ((ret = ff_rtmp_packet_create(&pkt, RTMP_SYSTEM_CHANNEL, RTMP_PT_INVOKE, - 0, 4096)) < 0) + 0, 4096 + APP_MAX_LENGTH)) < 0) return ret; p = pkt.data; @@ -419,6 +418,7 @@ static int read_connect(URLContext *s, RTMPContext *rt) if (pkt.type == RTMP_PT_CHUNK_SIZE) { if ((ret = handle_chunk_size(s, &pkt)) < 0) return ret; + ff_rtmp_packet_destroy(&pkt); if ((ret = ff_rtmp_packet_read(rt->stream, &pkt, rt->in_chunk_size, &rt->prev_pkt[0], &rt->nb_prev_pkt[0])) < 0) @@ -1748,18 +1748,23 @@ static int handle_connect_error(URLContext *s, const char *desc) char *value = strchr(ptr, '='); if (next) *next++ = '\0'; - if (value) + if (value) { *value++ = '\0'; - if (!strcmp(ptr, "user")) { - user = value; - } else if (!strcmp(ptr, "salt")) { - salt = value; - } else if (!strcmp(ptr, "opaque")) { - opaque = value; - } else if (!strcmp(ptr, "challenge")) { - challenge = value; - } else if (!strcmp(ptr, "nonce")) { - nonce = value; + if (!strcmp(ptr, "user")) { + user = value; + } else if (!strcmp(ptr, "salt")) { + salt = value; + } else if (!strcmp(ptr, "opaque")) { + opaque = value; + } else if (!strcmp(ptr, "challenge")) { + challenge = value; + } else if (!strcmp(ptr, "nonce")) { + nonce = value; + } else { + av_log(s, AV_LOG_INFO, "Ignoring unsupported var %s\n", ptr); + } + } else { + av_log(s, AV_LOG_WARNING, "Variable %s has NULL value\n", ptr); } ptr = next; } @@ -2411,7 +2416,7 @@ static int get_packet(URLContext *s, int for_header) rt->last_timestamp = rpkt.timestamp; rt->bytes_read += ret; - if (rt->bytes_read > rt->last_bytes_read + rt->client_report_size) { + if (rt->bytes_read - rt->last_bytes_read > rt->client_report_size) { av_log(s, AV_LOG_DEBUG, "Sending bytes read report\n"); if ((ret = gen_bytes_read(s, rt, rpkt.timestamp + 1)) < 0) return ret; @@ -2528,7 +2533,7 @@ static int inject_fake_duration_metadata(RTMPContext *rt) // Increase the size by the injected packet rt->flv_size += 55; // Delete the old FLV data - av_free(old_flv_data); + av_freep(&old_flv_data); p = rt->flv_data + 13; bytestream_put_byte(&p, FLV_TAG_TYPE_META); @@ -2573,7 +2578,7 @@ static int rtmp_open(URLContext *s, const char *uri, int flags) { RTMPContext *rt = s->priv_data; char proto[8], hostname[256], path[1024], auth[100], *fname; - char *old_app, *qmark, fname_buffer[1024]; + char *old_app, *qmark, *n, fname_buffer[1024]; uint8_t buf[2048]; int port; AVDictionary *opts = NULL; @@ -2588,11 +2593,13 @@ static int rtmp_open(URLContext *s, const char *uri, int flags) hostname, sizeof(hostname), &port, path, sizeof(path), s->filename); - if (strchr(path, ' ')) { + n = strchr(path, ' '); + if (n) { av_log(s, AV_LOG_WARNING, "Detected librtmp style URL parameters, these aren't supported " "by the libavformat internal RTMP handler currently enabled. " "See the documentation for the correct way to pass parameters.\n"); + *n = '\0'; // Trim not supported part } if (auth[0]) { @@ -2691,8 +2698,14 @@ reconnect: char *next = *path ? path + 1 : path; char *p = strchr(next, '/'); if (!p) { - fname = next; - rt->app[0] = '\0'; + if (old_app) { + // If name of application has been defined by the user, assume that + // playpath is provided in the URL + fname = next; + } else { + fname = NULL; + av_strlcpy(rt->app, next, APP_MAX_LENGTH); + } } else { // make sure we do not mismatch a playpath for an application instance char *c = strchr(p + 1, ':'); @@ -2709,29 +2722,36 @@ reconnect: if (old_app) { // The name of application has been defined by the user, override it. + if (strlen(old_app) >= APP_MAX_LENGTH) { + ret = AVERROR(EINVAL); + goto fail; + } av_free(rt->app); rt->app = old_app; } if (!rt->playpath) { - int len = strlen(fname); - rt->playpath = av_malloc(PLAYPATH_MAX_LENGTH); if (!rt->playpath) { ret = AVERROR(ENOMEM); goto fail; } - if (!strchr(fname, ':') && len >= 4 && - (!strcmp(fname + len - 4, ".f4v") || - !strcmp(fname + len - 4, ".mp4"))) { - memcpy(rt->playpath, "mp4:", 5); + if (fname) { + int len = strlen(fname); + if (!strchr(fname, ':') && len >= 4 && + (!strcmp(fname + len - 4, ".f4v") || + !strcmp(fname + len - 4, ".mp4"))) { + memcpy(rt->playpath, "mp4:", 5); + } else { + if (len >= 4 && !strcmp(fname + len - 4, ".flv")) + fname[len - 4] = '\0'; + rt->playpath[0] = 0; + } + av_strlcat(rt->playpath, fname, PLAYPATH_MAX_LENGTH); } else { - if (len >= 4 && !strcmp(fname + len - 4, ".flv")) - fname[len - 4] = '\0'; - rt->playpath[0] = 0; + rt->playpath[0] = '\0'; } - av_strlcat(rt->playpath, fname, PLAYPATH_MAX_LENGTH); } if (!rt->tcurl) { @@ -2933,6 +2953,7 @@ static int rtmp_write(URLContext *s, const uint8_t *buf, int size) if (rt->flv_header_bytes < RTMP_HEADER) { const uint8_t *header = rt->flv_header; int channel = RTMP_AUDIO_CHANNEL; + copy = FFMIN(RTMP_HEADER - rt->flv_header_bytes, size_temp); bytestream_get_buffer(&buf_temp, rt->flv_header + rt->flv_header_bytes, copy); rt->flv_header_bytes += copy; |