Skip to content

Comments

fix string building for onNewSegments and getTextSegments#297

Open
jiangts wants to merge 1 commit intomybigday:mainfrom
jiangts:main
Open

fix string building for onNewSegments and getTextSegments#297
jiangts wants to merge 1 commit intomybigday:mainfrom
jiangts:main

Conversation

@jiangts
Copy link

@jiangts jiangts commented Aug 16, 2025

This PR fixes crashes in the iOS implementation onNewSegments. Tested on 0.4.3 tag.

Key Changes

  • Improved string handling:

    • Replaced repeated NSString concatenation with a NSMutableString builder.
    • Added UTF-8 decoding with a Latin-1 fallback to handle invalid/“dirty” input without returning nil.
    • Guaranteed all dictionary values are non-nil (empty string fallback).
  • onNewSegments callback

    • Added @autoreleasepool to reduce memory pressure inside callback loops.
    • Moved rnwhisper_segments_callback_data allocation to the heap.
    • Introduced isHeapAllocated flag and cleanup_callback_data helper to prevent leaks and use-after-free.
  • getTextSegments

    • Applied the same safe string handling improvements as above.
    • Ensured returned result and segments are always consistent and non-nil.

Why

  • Prevents crashes from invalid UTF-8 sequences.
  • Avoids inserting nil values into dictionaries.
  • Eliminates risk of dangling pointers when callbacks outlive stack variables.
  • Improves memory safety and stability for real-time transcription.

@derryc09
Copy link

Thanks for this, I've been debugging this for the past week.
Whisper.rn causes the app to crash when transcribing, in my case, Japanese.

@jhen0409
Copy link
Member

Thanks for the PR! It would be helpful if you could provide a valid test file.

Also, note that we will replace all native iOS/Android implementations with RNWhisperJSI in the future, that still decode text segments as utf8.

@abretonc7s
Copy link

Can confirm this bug is still present in 0.6.0-rc.0. Calling transcribeData with onNewSegments on iOS crashes with EXC_BAD_ACCESS at RNWhisperContext.mm:463.

Root cause: the onNewSegments ObjC block is stored in the C struct without an explicit [copy], so ARC does not retain it. Heap-allocating the struct and using [onNewSegments copy] fixes it:

struct rnwhisper_segments_callback_data *user_data = new rnwhisper_segments_callback_data();
user_data->onNewSegments = [onNewSegments copy];
user_data->tdrzEnable = options[@"tdrzEnable"] && [options[@"tdrzEnable"] boolValue];
user_data->total_n_new = 0;
params.new_segment_callback_user_data = user_data;

// after fullTranscribe returns:
if (params.new_segment_callback_user_data) {
    delete (struct rnwhisper_segments_callback_data *)params.new_segment_callback_user_data;
    params.new_segment_callback_user_data = nullptr;
}

The JFK sample audio from the whisper.rn example app reliably reproduces the crash and could serve as the test file requested above.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants