From ddc253583f7a4cef15fac22427f419340b59748b Mon Sep 17 00:00:00 2001
From: John Thacker <johnthacker@gmail.com>
Date: Sat, 18 Apr 2026 21:19:03 -0400
Subject: [PATCH] sharkd: Implement a skeleton of cf_close, and call it

Implement a cf_close for sharkd.c, and call it when opening a new
file in order to free all the old information. I'm not certain if
this is everything that sharkd can possibly put in the capture_file
struct, but all of this is necessary.

Fix #21214

AI-Assisted: no


(cherry picked from commit 9144a54679a3375f9537f3a61ce68bcd5ba5689b)

Co-authored-by: John Thacker <johnthacker@gmail.com>
---
 sharkd.c | 33 ++++++++++++++++++++++++++++++++-
 1 file changed, 32 insertions(+), 1 deletion(-)

Index: wireshark-3.6.24/sharkd.c
===================================================================
--- wireshark-3.6.24.orig/sharkd.c
+++ wireshark-3.6.24/sharkd.c
@@ -410,6 +410,35 @@ load_cap_file(capture_file *cf, int max_
   return err;
 }
 
+void
+cf_close(capture_file *cf)
+{
+    if (cf->state == FILE_CLOSED || cf->state == FILE_READ_PENDING)
+        return; /* Nothing to do */
+
+    if (cf->provider.wth) {
+        wtap_close(cf->provider.wth);
+        cf->provider.wth = NULL;
+    }
+
+    /* We have no file open... */
+    if (cf->filename != NULL) {
+        /* If it's a temporary file, remove it. */
+        if (cf->is_tempfile)
+            ws_unlink(cf->filename);
+        g_free(cf->filename);
+        cf->filename = NULL;
+    }
+
+    if (cf->provider.frames != NULL) {
+        free_frame_data_sequence(cf->provider.frames);
+        cf->provider.frames = NULL;
+    }
+
+    /* We have no file open. */
+    cf->state = FILE_CLOSED;
+}
+
 cf_status_t
 cf_open(capture_file *cf, const char *fname, unsigned int type, gboolean is_tempfile, int *err)
 {
@@ -420,7 +449,9 @@ cf_open(capture_file *cf, const char *fn
   if (wth == NULL)
     goto fail;
 
-  /* The open succeeded.  Fill in the information for this file. */
+    /* The open succeeded.  Close whatever capture file we had open,
+       and fill in the information for this file. */
+    cf_close(cf);
 
   cf->provider.wth = wth;
   cf->f_datalen = 0; /* not used, but set it anyway */
