From f6cb547426d1ee5df2038809b5a6f23380edc932 Mon Sep 17 00:00:00 2001 From: John Thacker Date: Sat, 20 Apr 2024 13:15:16 +0000 Subject: [PATCH] editcap, libwiretap: Don't use array of initial DSBs after freeing wtap_dump_close frees the passed in GArray of initial DSBs, used by editcap for injecting DSBs from a file or list of files. Add functions to increment and decrement the reference count of an array of wtap blocks. Dereference the block of initial DSBs in wtap_dump_close() instead of freeing it. In editcap, before closing the dump file in cases where we intend to open a new file (e.g., with a maximum time value or a maximum packet count), reference the block. Fix #19782, #19783, #19784. (cherry picked from commit be3550b3b138f39bebb87ac0b8490e75fc8cc847) Co-authored-by: John Thacker --- editcap.c | 9 +++++++++ wiretap/file_access.c | 2 +- wiretap/wtap.h | 3 ++- wiretap/wtap_opttypes.c | 26 ++++++++++++++++++++++++++ wiretap/wtap_opttypes.h | 23 +++++++++++++++++++++++ 5 files changed, 61 insertions(+), 2 deletions(-) diff --git a/editcap.c b/editcap.c index 45091e5..50597c5 100644 --- a/editcap.c +++ b/editcap.c @@ -1858,6 +1858,10 @@ main(int argc, char *argv[]) } while (nstime_cmp(&rec->ts, &block_next) > 0) { /* time for the next file */ + /* We presumably want to write the DSBs from files given + * on the command line to every file. + */ + wtap_block_array_ref(params.dsbs_initial); if (!wtap_dump_close(pdh, &write_err, &write_err_info)) { cfile_close_failure_message(filename, write_err, write_err_info); @@ -1890,6 +1894,11 @@ main(int argc, char *argv[]) if (split_packet_count != 0) { /* time for the next file? */ if (written_count > 0 && (written_count % split_packet_count) == 0) { + + /* We presumably want to write the DSBs from files given + * on the command line to every file. + */ + wtap_block_array_ref(params.dsbs_initial); if (!wtap_dump_close(pdh, &write_err, &write_err_info)) { cfile_close_failure_message(filename, write_err, write_err_info); diff --git a/wiretap/file_access.c b/wiretap/file_access.c index ff7a640..50d1fb1 100644 --- a/wiretap/file_access.c +++ b/wiretap/file_access.c @@ -2655,7 +2655,7 @@ wtap_dump_close_new_temp(wtap_dumper *wdh, gboolean *needs_reload, *needs_reload = wdh->needs_reload; g_free(wdh->priv); wtap_block_array_free(wdh->interface_data); - wtap_block_array_free(wdh->dsbs_initial); + wtap_block_array_unref(wdh->dsbs_initial); g_free(wdh); return ret; } diff --git a/wiretap/wtap.h b/wiretap/wtap.h index d592884..75e4fc6 100644 --- a/wiretap/wtap.h +++ b/wiretap/wtap.h @@ -1419,7 +1419,8 @@ typedef struct addrinfo_lists { * @note The shb_hdr, idb_inf, and nrb_hdr arguments will be used until * wtap_dump_close() is called, but will not be free'd by the dumper. If * you created them, you must free them yourself after wtap_dump_close(). - * dsbs_initial will be freed by wtap_dump_close(), + * dsbs_initial will be unreferenced by wtap_dump_close(), so to reuse + * them for another dump file, call wtap_block_array_ref() before closing. * dsbs_growing typically refers to another wth->dsbs. * * @see wtap_dump_params_init, wtap_dump_params_cleanup. diff --git a/wiretap/wtap_opttypes.c b/wiretap/wtap_opttypes.c index 2068743..d4a9602 100644 --- a/wiretap/wtap_opttypes.c +++ b/wiretap/wtap_opttypes.c @@ -436,6 +436,32 @@ void wtap_block_array_free(GArray* block_array) g_array_free(block_array, TRUE); } +void wtap_block_array_ref(GArray* block_array) +{ + unsigned block; + + if (block_array == NULL) + return; + + for (block = 0; block < block_array->len; block++) { + wtap_block_ref(g_array_index(block_array, wtap_block_t, block)); + } + g_array_ref(block_array); +} + +void wtap_block_array_unref(GArray* block_array) +{ + unsigned block; + + if (block_array == NULL) + return; + + for (block = 0; block < block_array->len; block++) { + wtap_block_unref(g_array_index(block_array, wtap_block_t, block)); + } + g_array_unref(block_array); +} + /* * Make a copy of a block. */ diff --git a/wiretap/wtap_opttypes.h b/wiretap/wtap_opttypes.h index 58d3103..5d130c5 100644 --- a/wiretap/wtap_opttypes.h +++ b/wiretap/wtap_opttypes.h @@ -572,6 +572,29 @@ wtap_block_unref(wtap_block_t block); WS_DLL_PUBLIC void wtap_block_array_free(GArray* block_array); +/** Decrement the reference count of an array of blocks + * + * Decrement the reference count of each block in the array + * and the GArray itself. Any element whose reference count + * drops to 0 will be freed. If the GArray and every block + * has a reference count of 1, this is the same as + * wtap_block_array_free(). + * + * @param[in] block_array Array of blocks to be dereferenced + */ +WS_DLL_PUBLIC void +wtap_block_array_unref(GArray* block_array); + +/** Increment the reference count of an array of blocks + * + * Increment the reference count of each block in the array + * and the GArray itself. + * + * @param[in] block_array Array of blocks to be referenced + */ +WS_DLL_PUBLIC void +wtap_block_array_ref(GArray* block_array); + /** Provide type of a block * * @param[in] block Block from which to retrieve mandatory data -- 2.33.0