]> git.ipfire.org Git - thirdparty/curl.git/commitdiff
rtsp: convert mallocs to dynbuf for RTP buffering
authorDaniel Stenberg <daniel@haxx.se>
Tue, 4 Apr 2023 12:44:25 +0000 (14:44 +0200)
committerDaniel Stenberg <daniel@haxx.se>
Tue, 4 Apr 2023 12:44:25 +0000 (14:44 +0200)
Closes #10786

lib/rtsp.c
lib/rtsp.h

index b8965ff15b41254a1cda5638da176f0e688c8544..3eebd5ace272639faf5e5f6df5f64650253828a4 100644 (file)
@@ -119,6 +119,7 @@ const struct Curl_handler Curl_handler_rtsp = {
   PROTOPT_NONE                          /* flags */
 };
 
+#define MAX_RTP_BUFFERSIZE 1000000 /* arbitrary */
 
 static CURLcode rtsp_setup_connection(struct Curl_easy *data,
                                       struct connectdata *conn)
@@ -130,6 +131,7 @@ static CURLcode rtsp_setup_connection(struct Curl_easy *data,
   if(!rtsp)
     return CURLE_OUT_OF_MEMORY;
 
+  Curl_dyn_init(&conn->proto.rtspc.buf, MAX_RTP_BUFFERSIZE);
   return CURLE_OK;
 }
 
@@ -176,7 +178,7 @@ static CURLcode rtsp_disconnect(struct Curl_easy *data,
 {
   (void) dead;
   (void) data;
-  Curl_safefree(conn->proto.rtspc.rtp_buf);
+  Curl_dyn_free(&conn->proto.rtspc.buf);
   return CURLE_OK;
 }
 
@@ -204,7 +206,7 @@ static CURLcode rtsp_done(struct Curl_easy *data,
       return CURLE_RTSP_CSEQ_ERROR;
     }
     if(data->set.rtspreq == RTSPREQ_RECEIVE &&
-            (data->conn->proto.rtspc.rtp_channel == -1)) {
+       (data->conn->proto.rtspc.rtp_channel == -1)) {
       infof(data, "Got an RTP Receive with a CSeq of %ld", CSeq_recv);
     }
   }
@@ -598,25 +600,16 @@ static CURLcode rtsp_rtp_readwrite(struct Curl_easy *data,
 
   char *rtp; /* moving pointer to rtp data */
   ssize_t rtp_dataleft; /* how much data left to parse in this round */
-  char *scratch;
   CURLcode result;
   bool interleaved = false;
   size_t skip_size = 0;
 
-  if(rtspc->rtp_buf) {
-    /* There was some leftover data the last time. Merge buffers */
-    char *newptr = Curl_saferealloc(rtspc->rtp_buf,
-                                    rtspc->rtp_bufsize + *nread);
-    if(!newptr) {
-      rtspc->rtp_buf = NULL;
-      rtspc->rtp_bufsize = 0;
+  if(Curl_dyn_len(&rtspc->buf)) {
+    /* There was some leftover data the last time. Append new buffers */
+    if(Curl_dyn_addn(&rtspc->buf, k->str, *nread))
       return CURLE_OUT_OF_MEMORY;
-    }
-    rtspc->rtp_buf = newptr;
-    memcpy(rtspc->rtp_buf + rtspc->rtp_bufsize, k->str, *nread);
-    rtspc->rtp_bufsize += *nread;
-    rtp = rtspc->rtp_buf;
-    rtp_dataleft = rtspc->rtp_bufsize;
+    rtp = Curl_dyn_ptr(&rtspc->buf);
+    rtp_dataleft = Curl_dyn_len(&rtspc->buf);
   }
   else {
     /* Just parse the request buffer directly */
@@ -667,9 +660,6 @@ static CURLcode rtsp_rtp_readwrite(struct Curl_easy *data,
         result = rtp_client_write(data, &rtp[0], rtp_length + 4);
         if(result) {
           *readmore = FALSE;
-          Curl_safefree(rtspc->rtp_buf);
-          rtspc->rtp_buf = NULL;
-          rtspc->rtp_bufsize = 0;
           return result;
         }
 
@@ -716,20 +706,18 @@ static CURLcode rtsp_rtp_readwrite(struct Curl_easy *data,
 
   if(rtp_dataleft && rtp[0] == '$') {
     DEBUGF(infof(data, "RTP Rewinding %zd %s", rtp_dataleft,
-          *readmore ? "(READMORE)" : ""));
+                 *readmore ? "(READMORE)" : ""));
 
     /* Store the incomplete RTP packet for a "rewind" */
-    scratch = malloc(rtp_dataleft);
-    if(!scratch) {
-      Curl_safefree(rtspc->rtp_buf);
-      rtspc->rtp_buf = NULL;
-      rtspc->rtp_bufsize = 0;
-      return CURLE_OUT_OF_MEMORY;
+    if(!Curl_dyn_len(&rtspc->buf)) {
+      /* nothing was stored, add this data */
+      if(Curl_dyn_addn(&rtspc->buf, rtp, rtp_dataleft))
+        return CURLE_OUT_OF_MEMORY;
+    }
+    else {
+      /* keep the remainder */
+      Curl_dyn_tail(&rtspc->buf, rtp_dataleft);
     }
-    memcpy(scratch, rtp, rtp_dataleft);
-    Curl_safefree(rtspc->rtp_buf);
-    rtspc->rtp_buf = scratch;
-    rtspc->rtp_bufsize = rtp_dataleft;
 
     /* As far as the transfer is concerned, this data is consumed */
     *nread = 0;
@@ -738,20 +726,10 @@ static CURLcode rtsp_rtp_readwrite(struct Curl_easy *data,
   /* Fix up k->str to point just after the last RTP packet */
   k->str += *nread - rtp_dataleft;
 
-  /* either all of the data has been read or...
-   * rtp now points at the next byte to parse
-   */
-  if(rtp_dataleft > 0)
-    DEBUGASSERT(k->str[0] == rtp[0]);
-
-  DEBUGASSERT(rtp_dataleft <= *nread); /* sanity check */
-
   *nread = rtp_dataleft;
 
   /* If we get here, we have finished with the leftover/merge buffer */
-  Curl_safefree(rtspc->rtp_buf);
-  rtspc->rtp_buf = NULL;
-  rtspc->rtp_bufsize = 0;
+  Curl_dyn_free(&rtspc->buf);
 
   return CURLE_OK;
 }
index 6e55616b3887fdcdc6938443ed97eb1d8dbb2331..111bac2a61242d8329d95c241f6a38b16aa4502a 100644 (file)
@@ -45,8 +45,7 @@ CURLcode Curl_rtsp_parseheader(struct Curl_easy *data, char *header);
  * Currently, only used for tracking incomplete RTP data reads
  */
 struct rtsp_conn {
-  char *rtp_buf;
-  ssize_t rtp_bufsize;
+  struct dynbuf buf;
   int rtp_channel;
 };