Skip to content

Commit 1fe435a

Browse files
committed
bsv, cdfs: free intfstream_t after intfstream_close at five remaining leak sites
Audit pass over every intfstream_close call site in production code: out of 53 sites, 48 were already followed by free() (the established libretro-common convention -- intfstream_close closes the inner backend, the caller owns the struct). Five were not, leaking 48 bytes per call. Five fixed: - input/bsv/bsvmovie.c:1315 check_stream (open_memory) - input/bsv/bsvmovie.c:1643 out_stream (open_writable_memory) - input/bsv/bsvmovie.c:1845 read_mem (open_memory) - libretro-common/formats/cdfs/cdfs.c:433 cue_stream (alloc-fail path) - libretro-common/formats/cdfs/cdfs.c:438 cue_stream (success path) The bsv leaks are the more interesting set: those code paths run on every replay verification (check_stream), every checkpoint encode (out_stream), and every checkpoint decode (read_mem) -- so during a long netplay session with an active replay or in checkpointed playback the leak compounds linearly with elapsed time. Each instance is small (48 bytes per intfstream_t struct) but they accumulate. The cdfs leak is per-cue-file: every time RetroArch parses a .cue (loading a multi-track CD image, bulk database scan over a CD library) it leaks 48 bytes. Both close paths in cdfs_open_cue_path were affected. Note on contract: changing intfstream_close to free the struct itself was considered and rejected. intfstream_close ships in libretro-common which is vendored into many cores; cores that correctly compensate for the existing convention by calling free() after close (the same pattern this commit standardises on inside RetroArch itself) would silently double-free under a contract change. Fix-the-call-sites is the only safe path. The 48 already-correct call sites are left as-is. This commit is a pure addition of missing free() calls; no behavioural or cleanup-order changes.
1 parent bac6894 commit 1fe435a

2 files changed

Lines changed: 5 additions & 0 deletions

File tree

input/bsv/bsvmovie.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1313,6 +1313,7 @@ bool replay_check_same_timeline(bsv_movie_t *movie,
13131313
free(buf1);
13141314
free(buf2);
13151315
intfstream_close(check_stream);
1316+
free(check_stream);
13161317
intfstream_seek(movie->file, movie_pos, SEEK_SET);
13171318
return ret;
13181319
}
@@ -1641,6 +1642,7 @@ int64_t bsv_movie_write_deduped_state(bsv_movie_t *movie, uint8_t *state,
16411642
RARCH_DBG("[STATESTREAM] Encode stats at checkpoint %d: %d blocks (%d reused, %d skipped [%d checks], %d distinct [%d hashes])\n", total_checkpoints, total_blocks, reused_blocks, skipped_blocks, memcmps, uint32s_index_count(movie->blocks), hashes);
16421643
RARCH_DBG("[STATESTREAM] %d superblocks (%d reused, %d distinct); unencoded size (KB) %d, encoded size (KB) %d; net time (secs) %f\n", total_superblocks, reused_superblocks, uint32s_index_count(movie->superblocks), total_kbs_input, total_kbs_written, ((float)total_encode_micros) / (float)1000000.0);
16431644
intfstream_close(out_stream);
1645+
free(out_stream);
16441646
return encoded_size;
16451647
}
16461648

@@ -1843,6 +1845,7 @@ bool bsv_movie_read_deduped_state(bsv_movie_t *movie, uint8_t *encoded, size_t e
18431845
/* uint32s_index_commit(movie->superblocks); */
18441846
rmsgpack_dom_reader_state_free(reader_state);
18451847
intfstream_close(read_mem);
1848+
free(read_mem);
18461849
if (!ret)
18471850
{
18481851
RARCH_ERR("[STATESTREAM] made it to end without superblock seq\n");

libretro-common/formats/cdfs/cdfs.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -431,11 +431,13 @@ static cdfs_track_t* cdfs_open_cue_track(
431431
if (!cue_contents)
432432
{
433433
intfstream_close(cue_stream);
434+
free(cue_stream);
434435
return NULL;
435436
}
436437

437438
intfstream_read(cue_stream, cue_contents, stream_size);
438439
intfstream_close(cue_stream);
440+
free(cue_stream);
439441

440442
cue_contents[stream_size] = '\0';
441443

0 commit comments

Comments
 (0)