]> granicus.if.org Git - curl/commitdiff
metalink: fix memory-leak and NULL pointer dereference
authorDaniel Stenberg <daniel@haxx.se>
Fri, 24 Nov 2017 08:02:54 +0000 (09:02 +0100)
committerDaniel Stenberg <daniel@haxx.se>
Fri, 24 Nov 2017 12:30:38 +0000 (13:30 +0100)
Reported by scan-build

Closes #2109

src/tool_metalink.c

index 270345547964e4fcbdcb2eb64d9a64855a4e0b72..bbbfc2a659d0ae5389a6f740ff137a6a7d982d32 100644 (file)
@@ -539,6 +539,7 @@ digest_context *Curl_digest_init(const digest_params *dparams)
   ctxt->digest_hash = dparams;
 
   if(dparams->digest_init(ctxt->digest_hashctx) != 1) {
+    free(ctxt->digest_hashctx);
     free(ctxt);
     return NULL;
   }
@@ -557,7 +558,8 @@ int Curl_digest_update(digest_context *context,
 
 int Curl_digest_final(digest_context *context, unsigned char *result)
 {
-  (*context->digest_hash->digest_final)(result, context->digest_hashctx);
+  if(result)
+    (*context->digest_hash->digest_final)(result, context->digest_hashctx);
 
   free(context->digest_hashctx);
   free(context);
@@ -622,6 +624,7 @@ static int check_hash(const char *filename,
   result = malloc(digest_def->dparams->digest_resultlen);
   if(!result) {
     close(fd);
+    Curl_digest_final(dctx, NULL);
     return -1;
   }
   while(1) {
@@ -690,6 +693,8 @@ static metalink_checksum *new_metalink_checksum_from_hex_digest
     chksum->digest_def = digest_def;
     chksum->digest = digest;
   }
+  else
+    free(digest);
   return chksum;
 }
 
@@ -781,8 +786,24 @@ static metalinkfile *new_metalinkfile(metalink_file_t *fileinfo)
          curl_strequal((*p)->type, "ftp") ||
          curl_strequal((*p)->type, "ftps")) {
         res = new_metalink_resource((*p)->url);
-        tail->next = res;
-        tail = res;
+        if(res) {
+          tail->next = res;
+          tail = res;
+        }
+        else {
+          tail = root.next;
+
+          /* clean up the linked list */
+          while(tail) {
+            res = tail->next;
+            free(tail->url);
+            free(tail);
+            tail = res;
+          }
+          free(f->filename);
+          free(f);
+          return NULL;
+        }
       }
     }
     f->resource = root.next;