Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 24 additions & 0 deletions sherpa-onnx/c-api/cxx-api.cc
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,18 @@ void OnlineStream::InputFinished() const {
SherpaOnnxOnlineStreamInputFinished(p_);
}

void OnlineStream::SetOption(const char *key, const char *value) const {
SherpaOnnxOnlineStreamSetOption(p_, key, value);
}

const char *OnlineStream::GetOption(const char *key) const {
return SherpaOnnxOnlineStreamGetOption(p_, key);
}

int32_t OnlineStream::HasOption(const char *key) const {
return SherpaOnnxOnlineStreamHasOption(p_, key);
}

OnlineRecognizer OnlineRecognizer::Create(
const OnlineRecognizerConfig &config) {
struct SherpaOnnxOnlineRecognizerConfig c;
Expand Down Expand Up @@ -211,6 +223,18 @@ void OfflineStream::AcceptWaveform(int32_t sample_rate, const float *samples,
SherpaOnnxAcceptWaveformOffline(p_, sample_rate, samples, n);
}

void OfflineStream::SetOption(const char *key, const char *value) const {
SherpaOnnxOfflineStreamSetOption(p_, key, value);
}

const char *OfflineStream::GetOption(const char *key) const {
return SherpaOnnxOfflineStreamGetOption(p_, key);
}

int32_t OfflineStream::HasOption(const char *key) const {
return SherpaOnnxOfflineStreamHasOption(p_, key);
}

static SherpaOnnxOfflineRecognizerConfig Convert(
const OfflineRecognizerConfig &config) {
struct SherpaOnnxOfflineRecognizerConfig c;
Expand Down
8 changes: 8 additions & 0 deletions sherpa-onnx/c-api/cxx-api.h
Original file line number Diff line number Diff line change
Expand Up @@ -179,6 +179,10 @@ class SHERPA_ONNX_API OnlineStream

void InputFinished() const;

void SetOption(const char *key, const char *value) const;
const char *GetOption(const char *key) const;
Comment on lines +182 to +183

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | πŸ”΄ Critical

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Compare text-returning APIs in the C++ wrapper.
rg -n 'const char \*GetOption|std::string ' sherpa-onnx/c-api/cxx-api.h

Repository: k2-fsa/sherpa-onnx

Length of output: 5348


🏁 Script executed:

#!/bin/bash
# Find the implementation file for cxx-api.h
fd -t f 'cxx-api\.(cc|cpp)' sherpa-onnx/

# Also check what GetOption and SetOption do
grep -n "GetOption\|SetOption" sherpa-onnx/c-api/cxx-api.h | head -20

Repository: k2-fsa/sherpa-onnx

Length of output: 322


🏁 Script executed:

#!/bin/bash
# Let's check the implementation to understand the lifetime concern
# First find the implementation file
find sherpa-onnx -name "*.cc" -o -name "*.cpp" | xargs grep -l "GetOption" 2>/dev/null | head -5

Repository: k2-fsa/sherpa-onnx

Length of output: 186


🏁 Script executed:

#!/bin/bash
# Check what the C API returns (the underlying C API that is being wrapped)
grep -n "GetOption\|SetOption" sherpa-onnx/c-api/c-api.h 2>/dev/null | head -20

Repository: k2-fsa/sherpa-onnx

Length of output: 309


🏁 Script executed:

#!/bin/bash
# Check the implementation of GetOption and SetOption in cxx-api.cc
grep -n -A 5 "GetOption\|SetOption" sherpa-onnx/c-api/cxx-api.cc | head -60

Repository: k2-fsa/sherpa-onnx

Length of output: 902


🏁 Script executed:

#!/bin/bash
# Check the C API implementation to see what it returns
grep -n -A 5 "SherpaOnnxOnlineStreamGetOption\|SherpaOnnxOfflineStreamGetOption" sherpa-onnx/c-api/c-api.cc | head -40

Repository: k2-fsa/sherpa-onnx

Length of output: 504


🏁 Script executed:

#!/bin/bash
# Check what stream->impl->GetOption returns in online-stream.cc and offline-stream.cc
grep -n "GetOption" sherpa-onnx/csrc/online-stream.cc | head -5
grep -n "GetOption" sherpa-onnx/csrc/offline-stream.cc | head -5

Repository: k2-fsa/sherpa-onnx

Length of output: 750


🏁 Script executed:

#!/bin/bash
# Get the actual implementation
grep -n -A 3 'GetOption.*{' sherpa-onnx/csrc/online-stream.cc

Repository: k2-fsa/sherpa-onnx

Length of output: 756


Return owning std::string from GetOption() β€” this is a lifetime safety issue.

GetOption() currently returns a borrowed const char * pointing to internal map storage that can be invalidated when SetOption() is called (reallocating the options map), when the stream is destroyed, or under concurrent access. This exposes a use-after-free risk to C++ callers. Return std::string to own the data safely.

Also, SetOption() should take const std::string & parameters for consistency with the rest of the API (e.g., CreateStream(const std::string &hotwords)).

Proposed fix
-  void SetOption(const char *key, const char *value) const;
-  const char *GetOption(const char *key) const;
+  void SetOption(const std::string &key, const std::string &value) const;
+  std::string GetOption(const std::string &key) const;

Also applies to: 382–383 (OfflineStream)

πŸ€– Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@sherpa-onnx/c-api/cxx-api.h` around lines 182 - 183, Change the API to avoid
returning borrowed C strings and to use std::string parameters: update
SetOption(const char *key, const char *value) to SetOption(const std::string
&key, const std::string &value) and change GetOption(const char *key) const to
return std::string (not const char*) so the caller owns the returned data; apply
the same changes for the OfflineStream variants (the other SetOption/GetOption
declarations) and ensure implementations copy/construct std::string from
internal storage rather than returning pointers into internal containers.

int32_t HasOption(const char *key) const;

Comment on lines +182 to +185
void Destroy(const SherpaOnnxOnlineStream *p) const;
};

Expand Down Expand Up @@ -378,6 +382,10 @@ class SHERPA_ONNX_API OfflineStream
void AcceptWaveform(int32_t sample_rate, const float *samples,
int32_t n) const;

void SetOption(const char *key, const char *value) const;
const char *GetOption(const char *key) const;
int32_t HasOption(const char *key) const;

void Destroy(const SherpaOnnxOfflineStream *p) const;
};

Expand Down
Loading